aboutsummaryrefslogtreecommitdiff
path: root/test/unit/test_c_api.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/test_c_api.cpp')
-rw-r--r--test/unit/test_c_api.cpp211
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