File indexing completed on 2024-05-19 05:42:09
0001 // ct_lvtmdb.t.cpp -*-C++-*- 0002 0003 /* 0004 // Copyright 2023 Codethink Ltd <codethink@codethink.co.uk> 0005 // SPDX-License-Identifier: Apache-2.0 0006 // 0007 // Licensed under the Apache License, Version 2.0 (the "License"); 0008 // you may not use this file except in compliance with the License. 0009 // You may obtain a copy of the License at 0010 // 0011 // http://www.apache.org/licenses/LICENSE-2.0 0012 // 0013 // Unless required by applicable law or agreed to in writing, software 0014 // distributed under the License is distributed on an "AS IS" BASIS, 0015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0016 // See the License for the specific language governing permissions and 0017 // limitations under the License. 0018 */ 0019 0020 #include <ct_lvtmdb_namespaceobject.h> 0021 #include <ct_lvtmdb_objectstore.h> 0022 #include <ct_lvtmdb_soci_reader.h> 0023 #include <ct_lvtmdb_soci_writer.h> 0024 0025 #include <filesystem> 0026 #include <iostream> 0027 0028 #include <catch2-local-includes.h> 0029 0030 namespace fs = std::filesystem; 0031 0032 using namespace Codethink::lvtmdb; 0033 0034 TEST_CASE("Merge Two Different Databases") 0035 { 0036 ObjectStore store1; 0037 ObjectStore store2; 0038 0039 NamespaceObject *store1_parent = nullptr; 0040 NamespaceObject *store1_b = nullptr; 0041 NamespaceObject *store1_c = nullptr; 0042 0043 NamespaceObject *store2_a = nullptr; 0044 NamespaceObject *store2_parent = nullptr; 0045 NamespaceObject *store2_b = nullptr; 0046 NamespaceObject *store2_c = nullptr; 0047 0048 // Parent is the first one to be added, so it will probably have id 1 0049 // on the first database. 0050 store1.withRWLock([&] { 0051 store1_parent = store1.getOrAddNamespace("parent", "parent", nullptr); 0052 store1_b = store1.getOrAddNamespace("b", "b", store1_parent); 0053 store1_c = store1.getOrAddNamespace("c", "c", store1_parent); 0054 0055 CHECK(store1.namespaces().size() == 3); 0056 }); 0057 0058 // parent is the second one to be added, so it will probably have id 2 0059 // on the second database. 0060 store2.withRWLock([&] { 0061 store2_a = store2.getOrAddNamespace("a", "a", store1_parent); 0062 0063 // and that makes b and c from the store 2 point to a different id for parent, 0064 // when the db is saved on disk. 0065 store2_parent = store2.getOrAddNamespace("parent", "parent", nullptr); 0066 store2_b = store2.getOrAddNamespace("b", "b", store1_parent); 0067 store2_c = store2.getOrAddNamespace("c", "c", store1_parent); 0068 CHECK(store2.namespaces().size() == 4); 0069 }); 0070 0071 fs::path project_path = fs::temp_directory_path(); 0072 0073 std::error_code ec; 0074 std::filesystem::remove(project_path / "database_1.db", ec); 0075 std::filesystem::remove(project_path / "database_2.db", ec); 0076 // We don't care about the error code. 0077 0078 { 0079 SociWriter writer; 0080 auto db_file = project_path / "database_1.db"; 0081 CHECK(writer.createOrOpen(db_file.string())); 0082 store1.writeToDatabase(writer); 0083 } 0084 { 0085 SociWriter writer2; 0086 auto db_file = project_path / "database_2.db"; 0087 CHECK(writer2.createOrOpen(db_file.string())); 0088 store2.writeToDatabase(writer2); 0089 } 0090 0091 SociReader reader; 0092 ObjectStore mergedStore; 0093 auto res = mergedStore.readFromDatabase(reader, (project_path / "database_1.db").string()); 0094 CHECK(!res.has_error()); 0095 0096 res = mergedStore.readFromDatabase(reader, (project_path / "database_2.db").string()); 0097 CHECK(!res.has_error()); 0098 0099 // We have 3 namespaces on db1, 4 on db2. but they overlap. 0100 // we should only have 4 namespaces on the merged store. 0101 mergedStore.withROLock([&] { 0102 CHECK(mergedStore.namespaces().size() == 4); 0103 }); 0104 }