diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2021-03-18 14:49:13 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-18 14:49:13 +0100 |
| commit | d4e5e1a833fa37afb5829d9eb9bfbe1472425df4 (patch) | |
| tree | 1042dd9a9a6934b39a766c3b219ade22b9dd15c7 /test/unit/test_c_api.cpp | |
| parent | 979e3a3ba0b270f7401a57105411375bb99ddbb5 (diff) | |
| parent | eae06c94dba10640ca2d669c4e7b356a1613f9f3 (diff) | |
| download | PROJ-d4e5e1a833fa37afb5829d9eb9bfbe1472425df4.tar.gz PROJ-d4e5e1a833fa37afb5829d9eb9bfbe1472425df4.zip | |
Merge pull request #2577 from rouault/insert_sql
Add capability to get SQL statements to add custom CRS in the database
Diffstat (limited to 'test/unit/test_c_api.cpp')
| -rw-r--r-- | test/unit/test_c_api.cpp | 211 |
1 files changed, 190 insertions, 21 deletions
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 20fb0583..b624e063 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -1776,29 +1776,58 @@ TEST_F(CApi, proj_context_set_database_path_null) { // --------------------------------------------------------------------------- -TEST_F(CApi, proj_context_set_database_path_main_memory_one_aux) { +TEST_F(CApi, proj_context_set_database_path_aux) { + + const std::string auxDbName( + "file:proj_test_aux.db?mode=memory&cache=shared"); + + sqlite3 *dbAux = nullptr; + sqlite3_open_v2( + auxDbName.c_str(), &dbAux, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI, nullptr); + ASSERT_TRUE(dbAux != nullptr); + ASSERT_TRUE(sqlite3_exec(dbAux, "BEGIN", nullptr, nullptr, nullptr) == + SQLITE_OK); + { + auto ctxt = DatabaseContext::create(); + const auto dbStructure = ctxt->getDatabaseStructure(); + for (const auto &sql : dbStructure) { + ASSERT_TRUE(sqlite3_exec(dbAux, sql.c_str(), nullptr, nullptr, + nullptr) == SQLITE_OK); + } + } - auto c_path = proj_context_get_database_path(m_ctxt); - ASSERT_TRUE(c_path != nullptr); - std::string path(c_path); - const char *aux_db_list[] = {path.c_str(), nullptr}; - - // This is super exotic and a miracle that it works. :memory: as the - // main DB is empty. The real stuff is in the aux_db_list. No view - // is created in the ':memory:' internal DB, but as there's only one - // aux DB its tables and views can be directly queried... - // If that breaks at some point, that wouldn't be a big issue. - // Keeping that one as I had a hard time figuring out why it worked ! - // The real thing is tested by the C++ - // factory::attachExtraDatabases_auxiliary - EXPECT_TRUE(proj_context_set_database_path(m_ctxt, ":memory:", aux_db_list, - nullptr)); + ASSERT_TRUE(sqlite3_exec( + dbAux, + "INSERT INTO geodetic_crs VALUES('OTHER','OTHER_4326','WGS " + "84',NULL,'geographic 2D','EPSG','6422','EPSG','6326'," + "NULL,0);", + nullptr, nullptr, nullptr) == SQLITE_OK); + ASSERT_TRUE(sqlite3_exec(dbAux, "COMMIT", nullptr, nullptr, nullptr) == + SQLITE_OK); - auto source_crs = proj_create_from_database(m_ctxt, "EPSG", "4326", - PJ_CATEGORY_CRS, false, - nullptr); // WGS84 - ASSERT_NE(source_crs, nullptr); - ObjectKeeper keeper_source_crs(source_crs); + const char *const aux_db_list[] = {auxDbName.c_str(), nullptr}; + + EXPECT_TRUE( + proj_context_set_database_path(m_ctxt, nullptr, aux_db_list, nullptr)); + + sqlite3_close(dbAux); + + { + auto crs = proj_create_from_database(m_ctxt, "EPSG", "4326", + PJ_CATEGORY_CRS, false, + nullptr); // WGS84 + ASSERT_NE(crs, nullptr); + ObjectKeeper keeper_source_crs(crs); + } + + { + auto crs = proj_create_from_database(m_ctxt, "OTHER", "OTHER_4326", + PJ_CATEGORY_CRS, false, + nullptr); // WGS84 + ASSERT_NE(crs, nullptr); + ObjectKeeper keeper_source_crs(crs); + } } // --------------------------------------------------------------------------- @@ -2728,6 +2757,15 @@ TEST_F(CApi, proj_context_get_database_metadata) { // --------------------------------------------------------------------------- +TEST_F(CApi, proj_context_get_database_structure) { + auto list = proj_context_get_database_structure(m_ctxt, nullptr); + ASSERT_NE(list, nullptr); + ASSERT_NE(list[0], nullptr); + proj_string_list_destroy(list); +} + +// --------------------------------------------------------------------------- + TEST_F(CApi, proj_clone) { auto obj = proj_create(m_ctxt, "+proj=longlat"); ObjectKeeper keeper(obj); @@ -5265,4 +5303,135 @@ TEST_F(CApi, proj_crs_is_derived) { } } +// --------------------------------------------------------------------------- + +TEST_F(CApi, proj_get_insert_statements) { + { + auto session = proj_insert_object_session_create(nullptr); + EXPECT_NE(session, nullptr); + + EXPECT_EQ(proj_insert_object_session_create(nullptr), nullptr); + + proj_insert_object_session_destroy(nullptr, session); + } + + { proj_insert_object_session_destroy(nullptr, nullptr); } + { + auto wkt = "GEOGCRS[\"myGDA2020\",\n" + " DATUM[\"GDA2020\",\n" + " ELLIPSOID[\"GRS_1980\",6378137,298.257222101,\n" + " LENGTHUNIT[\"metre\",1]]],\n" + " PRIMEM[\"Greenwich\",0,\n" + " ANGLEUNIT[\"Degree\",0.0174532925199433]],\n" + " CS[ellipsoidal,2],\n" + " AXIS[\"geodetic latitude (Lat)\",north,\n" + " ORDER[1],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " AXIS[\"geodetic longitude (Lon)\",east,\n" + " ORDER[2],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]]]"; + auto crs = proj_create_from_wkt(m_ctxt, wkt, nullptr, nullptr, nullptr); + ObjectKeeper keeper_from_wkt(crs); + EXPECT_NE(crs, nullptr); + + { + char *code = + proj_suggests_code_for(m_ctxt, crs, "HOBU", false, nullptr); + ASSERT_NE(code, nullptr); + EXPECT_EQ(std::string(code), "MYGDA2020"); + proj_string_destroy(code); + } + + { + char *code = + proj_suggests_code_for(m_ctxt, crs, "HOBU", true, nullptr); + ASSERT_NE(code, nullptr); + EXPECT_EQ(std::string(code), "1"); + proj_string_destroy(code); + } + + const auto sizeOfStringList = [](const char *const *list) { + if (list == nullptr) + return -1; + int size = 0; + for (auto iter = list; *iter; ++iter) { + size += 1; + } + return size; + }; + + // No session specified: we use a temporary session + for (int i = 0; i < 2; i++) { + auto list = proj_get_insert_statements( + m_ctxt, nullptr, crs, "HOBU", "XXXX", false, nullptr, nullptr); + ASSERT_NE(list, nullptr); + ASSERT_NE(list[0], nullptr); + EXPECT_EQ(std::string(list[0]), + "INSERT INTO geodetic_datum VALUES('HOBU'," + "'GEODETIC_DATUM_XXXX','GDA2020','','EPSG','7019'," + "'EPSG','8901',NULL,NULL,NULL,0);"); + EXPECT_EQ(sizeOfStringList(list), 4); + proj_string_list_destroy(list); + } + + // Pass an empty list of allowed authorities + // We cannot reuse the EPSG ellipsoid and prime meridian + { + const char *const allowed_authorities[] = {nullptr}; + auto list = + proj_get_insert_statements(m_ctxt, nullptr, crs, "HOBU", "XXXX", + false, allowed_authorities, nullptr); + EXPECT_EQ(sizeOfStringList(list), 6); + proj_string_list_destroy(list); + } + + // Allow only PROJ + // We cannot reuse the EPSG ellipsoid and prime meridian + { + const char *const allowed_authorities[] = {"PROJ", nullptr}; + auto list = + proj_get_insert_statements(m_ctxt, nullptr, crs, "HOBU", "XXXX", + false, allowed_authorities, nullptr); + EXPECT_EQ(sizeOfStringList(list), 6); + proj_string_list_destroy(list); + } + + // Allow EPSG + { + const char *const allowed_authorities[] = {"EPSG", nullptr}; + auto list = + proj_get_insert_statements(m_ctxt, nullptr, crs, "HOBU", "XXXX", + false, allowed_authorities, nullptr); + EXPECT_EQ(sizeOfStringList(list), 4); + proj_string_list_destroy(list); + } + + auto session = proj_insert_object_session_create(m_ctxt); + EXPECT_NE(session, nullptr); + + { + auto list = proj_get_insert_statements( + m_ctxt, session, crs, "HOBU", "XXXX", false, nullptr, nullptr); + ASSERT_NE(list, nullptr); + ASSERT_NE(list[0], nullptr); + EXPECT_EQ(std::string(list[0]), + "INSERT INTO geodetic_datum VALUES('HOBU'," + "'GEODETIC_DATUM_XXXX','GDA2020','','EPSG','7019'," + "'EPSG','8901',NULL,NULL,NULL,0);"); + proj_string_list_destroy(list); + } + + // Object already inserted: return empty list + { + auto list = proj_get_insert_statements( + m_ctxt, session, crs, "HOBU", "XXXX", false, nullptr, nullptr); + ASSERT_NE(list, nullptr); + ASSERT_EQ(list[0], nullptr); + proj_string_list_destroy(list); + } + + proj_insert_object_session_destroy(m_ctxt, session); + } +} + } // namespace |
