1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17
18 #include "db_common.h"
19 #include "distributeddb_data_generate_unit_test.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "log_print.h"
22 #include "relational_store_delegate_impl.h"
23 #include "relational_store_manager.h"
24 #include "relational_virtual_device.h"
25 #include "runtime_config.h"
26 #include "virtual_communicator_aggregator.h"
27
28 using namespace testing::ext;
29 using namespace DistributedDB;
30 using namespace DistributedDBUnitTest;
31 using namespace std;
32
33 namespace {
34 constexpr const char* DB_SUFFIX = ".db";
35 constexpr const char* STORE_ID = "Relational_Store_ID";
36 const std::string DEVICE_A = "DEVICE_A";
37 const std::string DEVICE_B = "DEVICE_B";
38 std::string g_testDir;
39 std::string g_dbDir;
40 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
41 VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
42 RelationalVirtualDevice *g_deviceB = nullptr;
43
44 const std::string NORMAL_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS sync_data(" \
45 "key BLOB NOT NULL UNIQUE," \
46 "value BLOB," \
47 "timestamp INT NOT NULL," \
48 "flag INT NOT NULL," \
49 "device BLOB," \
50 "ori_device BLOB," \
51 "hash_key BLOB PRIMARY KEY NOT NULL," \
52 "w_timestamp INT," \
53 "UNIQUE(device, ori_device));" \
54 "CREATE INDEX key_index ON sync_data (key, flag);";
55
56 const std::string EMPTY_COLUMN_TYPE_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS student(" \
57 "id INTEGER NOT NULL UNIQUE," \
58 "name TEXT," \
59 "field_1);";
60
61 const std::string NORMAL_CREATE_TABLE_SQL_STUDENT = R""(create table student_1 (
62 id INTEGER PRIMARY KEY,
63 name STRING,
64 level INTEGER,
65 score INTEGER
66 ))"";
67
68 const std::string NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER = R""(create table student_1 (
69 id INTEGER PRIMARY KEY,
70 name STRING,
71 score INTEGER,
72 level INTEGER
73 ))"";
74
75 const std::string ALL_FIELD_TYPE_TABLE_SQL = R""(CREATE TABLE IF NOT EXISTS tbl_all_type(
76 id INTEGER PRIMARY KEY,
77 f_int INT,
78 f_real REAL,
79 f_text TEXT,
80 f_blob BLOB,
81 f_none
82 ))"";
83
FakeOldVersionDB(sqlite3 * db)84 void FakeOldVersionDB(sqlite3 *db)
85 {
86 std::string dropLogTable = "drop table naturalbase_rdb_aux_student_1_log;";
87 EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropLogTable), SQLITE_OK);
88 dropLogTable = "drop table naturalbase_rdb_aux_sync_data_log;";
89 EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropLogTable), SQLITE_OK);
90
91 std::string createLogTable = "CREATE TABLE naturalbase_rdb_aux_student_1_log(" \
92 "data_key INT NOT NULL," \
93 "device BLOB," \
94 "ori_device BLOB," \
95 "timestamp INT NOT NULL," \
96 "wtimestamp INT NOT NULL," \
97 "flag INT NOT NULL," \
98 "hash_key BLOB NOT NULL," \
99 "PRIMARY KEY(hash_key));";
100 EXPECT_EQ(RelationalTestUtils::ExecSql(db, createLogTable), SQLITE_OK);
101
102 createLogTable = "CREATE TABLE naturalbase_rdb_aux_sync_data_log(" \
103 "data_key INT NOT NULL," \
104 "device BLOB," \
105 "ori_device BLOB," \
106 "timestamp INT NOT NULL," \
107 "wtimestamp INT NOT NULL," \
108 "flag INT NOT NULL," \
109 "hash_key BLOB NOT NULL," \
110 "PRIMARY KEY(hash_key));";
111 EXPECT_EQ(RelationalTestUtils::ExecSql(db, createLogTable), SQLITE_OK);
112
113 std::string dropTrigger = "DROP TRIGGER IF EXISTS naturalbase_rdb_student_1_ON_UPDATE;";
114 EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropTrigger), SQLITE_OK);
115
116 std::string oldTrigger = "CREATE TRIGGER naturalbase_rdb_student_1_ON_UPDATE AFTER UPDATE \n"
117 "ON student_1\n"
118 "BEGIN\n"
119 "\t UPDATE naturalbase_rdb_aux_student_1_log SET timestamp=get_sys_time(0), device='', "
120 "flag=0x22 WHERE hash_key=calc_hash(OLD.id) AND flag&0x02=0x02;\n"
121 "END;";
122 EXPECT_EQ(RelationalTestUtils::ExecSql(db, oldTrigger), SQLITE_OK);
123 Key key;
124 DBCommon::StringToVector("log_table_version", key);
125 Value val;
126 DBCommon::StringToVector("1.0", val);
127 EXPECT_EQ(RelationalTestUtils::SetMetaData(db, key, val), SQLITE_OK);
128 }
129
AddDeviceSchema(RelationalVirtualDevice * device,sqlite3 * db,const std::string & name)130 void AddDeviceSchema(RelationalVirtualDevice *device, sqlite3 *db, const std::string &name)
131 {
132 TableInfo table;
133 SQLiteUtils::AnalysisSchema(db, name, table);
134
135 std::vector<FieldInfo> fieldList;
136 for (const auto &it : table.GetFields()) {
137 fieldList.push_back(it.second);
138 }
139 device->SetLocalFieldInfo(table.GetFieldInfos());
140 device->SetTableInfo(table);
141 }
142 }
143
144 class DistributedDBInterfacesRelationalSyncTest : public testing::Test {
145 public:
146 static void SetUpTestCase(void);
147 static void TearDownTestCase(void);
148 void SetUp() override;
149 void TearDown() override;
150 protected:
151 sqlite3 *db = nullptr;
152 RelationalStoreDelegate *delegate = nullptr;
153 };
154
SetUpTestCase(void)155 void DistributedDBInterfacesRelationalSyncTest::SetUpTestCase(void)
156 {
157 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
158 LOGD("Test dir is %s", g_testDir.c_str());
159 g_dbDir = g_testDir + "/";
160
161 g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
162 ASSERT_TRUE(g_communicatorAggregator != nullptr);
163 RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
164 }
165
TearDownTestCase(void)166 void DistributedDBInterfacesRelationalSyncTest::TearDownTestCase(void)
167 {
168 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
169 }
170
SetUp()171 void DistributedDBInterfacesRelationalSyncTest::SetUp()
172 {
173 DistributedDBToolsUnitTest::PrintTestCaseInfo();
174
175 g_deviceB = new (std::nothrow) RelationalVirtualDevice(DEVICE_B);
176 ASSERT_TRUE(g_deviceB != nullptr);
177 auto *syncInterfaceB = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
178 ASSERT_TRUE(syncInterfaceB != nullptr);
179 ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
180
181 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
182 const std::string &deviceId, uint8_t flag) -> bool {
183 return true;
184 };
185 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
186
187 db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
188 ASSERT_NE(db, nullptr);
189 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
190 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
191 RelationalTestUtils::CreateDeviceTable(db, "sync_data", DEVICE_A);
192 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
193 EXPECT_EQ(status, OK);
194 ASSERT_NE(delegate, nullptr);
195
196 status = delegate->CreateDistributedTable("sync_data");
197 EXPECT_EQ(status, OK);
198
199 AddDeviceSchema(g_deviceB, db, "sync_data");
200 }
201
TearDown()202 void DistributedDBInterfacesRelationalSyncTest::TearDown()
203 {
204 if (g_deviceB != nullptr) {
205 delete g_deviceB;
206 g_deviceB = nullptr;
207 }
208 PermissionCheckCallbackV2 nullCallback;
209 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(nullCallback), OK);
210
211 g_mgr.CloseStore(delegate);
212 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
213 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
214 }
215
216 /**
217 * @tc.name: RelationalSyncTest001
218 * @tc.desc: Test with sync interface, table is not a distributed table
219 * @tc.type: FUNC
220 * @tc.require:
221 * @tc.author: lianhuix
222 */
223 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest001, TestSize.Level1)
224 {
225 std::vector<std::string> devices = {DEVICE_A};
226 Query query = Query::Select("sync_datb");
227 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0302(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 228 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
229 EXPECT_EQ(devicesMap.size(), devices.size());
230 }, true);
231
232 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_NOT_FOUND);
233 }
234
235 /**
236 * @tc.name: RelationalSyncTest002
237 * @tc.desc: Test with sync interface, query is not support
238 * @tc.type: FUNC
239 * @tc.require:
240 * @tc.author: lianhuix
241 */
242 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest002, TestSize.Level1)
243 {
244 std::vector<std::string> devices = {DEVICE_A};
245 Query query = Query::Select("sync_data").Like("value", "abc");
246 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0402(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 247 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
248 EXPECT_EQ(devicesMap.size(), devices.size());
249 }, true);
250
251 EXPECT_EQ(errCode, NOT_SUPPORT);
252 }
253
254 /**
255 * @tc.name: RelationalSyncTest003
256 * @tc.desc: Test with sync interface, query is invalid format
257 * @tc.type: FUNC
258 * @tc.require:
259 * @tc.author: lianhuix
260 */
261 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest003, TestSize.Level1)
262 {
263 std::vector<std::string> devices = {DEVICE_A};
264 Query query = Query::Select("sync_data").And().Or().EqualTo("flag", 2);
265 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0502(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 266 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
267 EXPECT_EQ(devicesMap.size(), devices.size());
268 }, true);
269
270 EXPECT_EQ(errCode, INVALID_QUERY_FORMAT);
271 }
272
273 /**
274 * @tc.name: RelationalSyncTest004
275 * @tc.desc: Test with sync interface, query use invalid field
276 * @tc.type: FUNC
277 * @tc.require:
278 * @tc.author: lianhuix
279 */
280 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest004, TestSize.Level1)
281 {
282 std::vector<std::string> devices = {DEVICE_A};
283 Query query = Query::Select("sync_data").EqualTo("fleg", 2);
284 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0602(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 285 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
286 EXPECT_EQ(devicesMap.size(), devices.size());
287 }, true);
288
289 EXPECT_EQ(errCode, INVALID_QUERY_FIELD);
290 }
291
292 /**
293 * @tc.name: RelationalSyncTest005
294 * @tc.desc: Test with sync interface, query table has been modified
295 * @tc.type: FUNC
296 * @tc.require:
297 * @tc.author: lianhuix
298 */
299 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest005, TestSize.Level1)
300 {
301 std::string modifySql = "ALTER TABLE sync_data ADD COLUMN add_field INTEGER;";
302 EXPECT_EQ(RelationalTestUtils::ExecSql(db, modifySql), SQLITE_OK);
303
304 std::vector<std::string> devices = {DEVICE_A};
305 Query query = Query::Select("sync_data");
306 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0702(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 307 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
308 EXPECT_EQ(devicesMap.size(), devices.size());
309 }, true);
310
311 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_CHANGED);
312 }
313
314 /**
315 * @tc.name: RelationalSyncTest006
316 * @tc.desc: Test with sync interface, query is not set table name
317 * @tc.type: FUNC
318 * @tc.require:
319 * @tc.author: lianhuix
320 */
321 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest006, TestSize.Level1)
322 {
323 std::vector<std::string> devices = {DEVICE_A};
324 Query query = Query::Select();
325 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 326 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
327 EXPECT_EQ(devicesMap.size(), devices.size());
328 }, true);
329
330 EXPECT_EQ(errCode, NOT_SUPPORT);
331 }
332
333 /**
334 * @tc.name: RelationalSyncTest007
335 * @tc.desc: Test with sync interface, distributed table has empty column type
336 * @tc.type: FUNC
337 * @tc.require:
338 * @tc.author: lianhuix
339 */
340 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest007, TestSize.Level1)
341 {
342 EXPECT_EQ(RelationalTestUtils::ExecSql(db, EMPTY_COLUMN_TYPE_CREATE_TABLE_SQL), SQLITE_OK);
343 RelationalTestUtils::CreateDeviceTable(db, "student", DEVICE_A);
344
345 DBStatus status = delegate->CreateDistributedTable("student");
346 EXPECT_EQ(status, OK);
347
348 std::vector<std::string> devices = {DEVICE_A};
349 Query query = Query::Select("student");
350 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0902(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 351 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
352 EXPECT_EQ(devicesMap.size(), devices.size());
353 }, true);
354
355 EXPECT_EQ(errCode, OK);
356 }
357
358 /**
359 * @tc.name: RelationalSyncTest008
360 * @tc.desc: Test sync with rebuilt table
361 * @tc.type: FUNC
362 * @tc.require:
363 * @tc.author: lianhuix
364 */
365 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest008, TestSize.Level1)
366 {
367 /**
368 * @tc.steps:step1. Drop sync_data
369 * @tc.expected: step1. ok
370 */
371 std::string dropSql = "DROP TABLE IF EXISTS sync_data;";
372 EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropSql), SQLITE_OK);
373
374 /**
375 * @tc.steps:step2. sync with sync_data
376 * @tc.expected: step2. return INVALID_QUERY_FORMAT
377 */
378 std::vector<std::string> devices = {DEVICE_A};
379 Query query = Query::Select("sync_data");
380 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0a02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 381 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
382 EXPECT_EQ(devicesMap.size(), devices.size());
383 }, true);
384 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_CHANGED);
385
386 /**
387 * @tc.steps:step3. recreate sync_data
388 * @tc.expected: step3. ok
389 */
390 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
391 DBStatus status = delegate->CreateDistributedTable("sync_data");
392 EXPECT_EQ(status, OK);
393
394 /**
395 * @tc.steps:step4. Check trigger
396 * @tc.expected: step4. trigger exists
397 */
398 bool result = false;
399 std::string checkSql = "select * from sqlite_master where type = 'trigger' and tbl_name = 'sync_data';";
400 EXPECT_EQ(RelationalTestUtils::CheckSqlResult(db, checkSql, result), E_OK);
401 EXPECT_EQ(result, true);
402
403 /**
404 * @tc.steps:step5. sync with sync_data
405 * @tc.expected: step5. ok
406 */
407 errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0b02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 408 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
409 EXPECT_EQ(devicesMap.size(), devices.size());
410 }, true);
411
412 EXPECT_EQ(errCode, OK);
413 }
414
415 /**
416 * @tc.name: RelationalSyncTest009
417 * @tc.desc: Test sync with invalid query
418 * @tc.type: FUNC
419 * @tc.require:
420 * @tc.author: lianhuix
421 */
422 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest009, TestSize.Level1)
423 {
424 EXPECT_EQ(RelationalTestUtils::ExecSql(db, EMPTY_COLUMN_TYPE_CREATE_TABLE_SQL), SQLITE_OK);
425 RelationalTestUtils::CreateDeviceTable(db, "student", DEVICE_A);
426
427 DBStatus status = delegate->CreateDistributedTable("student");
428 EXPECT_EQ(status, OK);
429
430 std::vector<std::string> devices = {DEVICE_A};
431 Query query = Query::Select("student").EqualTo("$id", 123);
432 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0c02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 433 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
434 EXPECT_EQ(devicesMap.size(), devices.size());
435 }, true);
436 EXPECT_EQ(status, INVALID_QUERY_FORMAT);
437
438 query = Query::Select("student").EqualTo("A$id", 123);
439 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0d02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 440 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
441 EXPECT_EQ(devicesMap.size(), devices.size());
442 }, true);
443 EXPECT_EQ(status, INVALID_QUERY_FORMAT);
444
445 query = Query::Select("student").EqualTo("$.id", 123);
446 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0e02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 447 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
448 EXPECT_EQ(devicesMap.size(), devices.size());
449 }, true);
450
451 EXPECT_EQ(status, OK);
452 }
453
454 /**
455 * @tc.name: RelationalSyncTest010
456 * @tc.desc: Test sync with shcema changed
457 * @tc.type: FUNC
458 * @tc.require:
459 * @tc.author: lianhuix
460 */
461 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest010, TestSize.Level1)
462 {
463 std::vector<std::string> devices = {DEVICE_A};
464 Query query = Query::Select("sync_data");
465 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b0f02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 466 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
467 EXPECT_EQ(devicesMap.size(), devices.size());
468 }, true);
469 EXPECT_EQ(errCode, OK);
470
471 std::string modifySql = "DROP TABLE IF EXISTS sync_data;";
472 EXPECT_EQ(RelationalTestUtils::ExecSql(db, modifySql), SQLITE_OK);
473
474 errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b1002(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 475 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
476 EXPECT_EQ(devicesMap.size(), devices.size());
477 }, true);
478 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_CHANGED);
479
480 errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b1102(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 481 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
482 EXPECT_EQ(devicesMap.size(), devices.size());
483 }, true);
484 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_CHANGED);
485 }
486
487 /**
488 * @tc.name: UpdatePrimaryKeyTest001
489 * @tc.desc: Test update data's primary key
490 * @tc.type: FUNC
491 * @tc.require:
492 * @tc.author: lianhuix
493 */
494 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, UpdatePrimaryKeyTest001, TestSize.Level1)
495 {
496 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
497 RelationalTestUtils::CreateDeviceTable(db, "student_1", DEVICE_A);
498
499 DBStatus status = delegate->CreateDistributedTable("student_1");
500 EXPECT_EQ(status, OK);
501
502 std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 2, 95);";
503 EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
504
505 std::string updateSql = "update student_1 set id = 1002 where name = 'xue';";
506 EXPECT_EQ(RelationalTestUtils::ExecSql(db, updateSql), SQLITE_OK);
507
508 int cnt = RelationalTestUtils::CheckTableRecords(db, std::string(DBConstant::RELATIONAL_PREFIX) + "student_1" +
509 "_log");
510 EXPECT_EQ(cnt, 2);
511 }
512
513 /**
514 * @tc.name: UpgradeTriggerTest001
515 * @tc.desc: Test upgrade from old version
516 * @tc.type: FUNC
517 * @tc.require:
518 * @tc.author: lianhuix
519 */
520 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, UpgradeTriggerTest001, TestSize.Level1)
521 {
522 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
523 RelationalTestUtils::CreateDeviceTable(db, "student_1", DEVICE_A);
524
525 DBStatus status = delegate->CreateDistributedTable("student_1");
526 EXPECT_EQ(status, OK);
527
528 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
529 delegate = nullptr;
530
531 FakeOldVersionDB(db);
532
533 status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
534 EXPECT_EQ(status, OK);
535 ASSERT_NE(delegate, nullptr);
536
537 // checkTrigger
538 std::string resultTrigger;
539 int errCode = RelationalTestUtils::ExecSql(db, "SELECT sql FROM sqlite_master WHERE type = ? AND name = ?",
__anonce34f60b1202(sqlite3_stmt *stmt) 540 [](sqlite3_stmt *stmt) {
541 (void)SQLiteUtils::BindTextToStatement(stmt, 1, "trigger"); // 1: bind index
542 (void)SQLiteUtils::BindTextToStatement(stmt, 2, "naturalbase_rdb_student_1_ON_UPDATE"); // 2: bind index
543 return E_OK;
544 }, [&resultTrigger](sqlite3_stmt *stmt) {
545 (void)SQLiteUtils::GetColumnTextValue(stmt, 0, resultTrigger);
546 return E_OK;
547 });
548 EXPECT_EQ(errCode, E_OK);
549 LOGD("result trigger: %s", resultTrigger.c_str());
550 std::string expectTrigger = "CREATE TRIGGER naturalbase_rdb_student_1_ON_UPDATE AFTER UPDATE \n"
551 "ON 'student_1'\n"
552 "BEGIN\n"
553 "\t UPDATE naturalbase_rdb_aux_student_1_log SET data_key=-1,timestamp=get_sys_time(0), device='',"
554 " flag=0x03 WHERE hash_key=calc_hash(OLD.'id', 0) AND flag&0x02=0x02;\n"
555 "\t INSERT OR REPLACE INTO naturalbase_rdb_aux_student_1_log VALUES (NEW._rowid_, '', '', get_sys_time(0), "
556 "get_last_time(), CASE WHEN (calc_hash(NEW.'id', 0) != calc_hash(NEW.'id', 0)) " \
557 "THEN 0x02 ELSE 0x22 END, calc_hash(NEW.'id', 0), '', '', '', '', '', 0);\n"
558 "END";
559 EXPECT_TRUE(resultTrigger == expectTrigger);
560 }
561
562
563 namespace {
PrepareSyncData(sqlite3 * db,int dataSize)564 void PrepareSyncData(sqlite3 *db, int dataSize)
565 {
566 int i = 1;
567 std::string insertSql = "INSERT INTO sync_data VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
568 int ret = RelationalTestUtils::ExecSql(db, insertSql, [&i, dataSize] (sqlite3_stmt *stmt) {
569 SQLiteUtils::BindTextToStatement(stmt, 1, "KEY_" + std::to_string(i));
570 SQLiteUtils::BindTextToStatement(stmt, 2, "VAL_" + std::to_string(i));
571 sqlite3_bind_int64(stmt, 3, 1000000 - (1000 + i));
572 sqlite3_bind_int64(stmt, 4, i % 4);
573 SQLiteUtils::BindTextToStatement(stmt, 5, "DEV_" + std::to_string(i));
574 SQLiteUtils::BindTextToStatement(stmt, 6, "KEY_" + std::to_string(i));
575 SQLiteUtils::BindTextToStatement(stmt, 7, "HASHKEY_" + std::to_string(i));
576 sqlite3_bind_int64(stmt, 8, 1000 + i);
577 return (i++ == dataSize) ? E_OK : -E_UNFINISHED;
578 }, nullptr);
579 EXPECT_EQ(ret, E_OK);
580 }
581
GetKey(VirtualRowData rowData)582 std::string GetKey(VirtualRowData rowData)
583 {
584 DataValue dataVal;
585 rowData.objectData.GetDataValue("key", dataVal);
586 EXPECT_EQ(dataVal.GetType(), StorageType::STORAGE_TYPE_TEXT);
587 std::string dataStr;
588 EXPECT_EQ(dataVal.GetText(dataStr), E_OK);
589 return dataStr;
590 }
591
CheckSyncData(sqlite3 * db,const std::string & checkSql,const std::vector<VirtualRowData> & resultData)592 void CheckSyncData(sqlite3 *db, const std::string &checkSql, const std::vector<VirtualRowData> &resultData)
593 {
594 std::set<std::string> keySet;
595 keySet.clear();
596 for (size_t i = 0; i < resultData.size(); i++) {
597 std::string ss = GetKey(resultData[i]);
598 keySet.insert(ss);
599 }
600 EXPECT_EQ(keySet.size(), resultData.size());
601
602 RelationalTestUtils::ExecSql(db, checkSql, nullptr, [keySet](sqlite3_stmt *stmt) {
603 std::string val;
604 SQLiteUtils::GetColumnTextValue(stmt, 0, val);
605 EXPECT_NE(keySet.find(val), keySet.end());
606 return E_OK;
607 });
608 }
609 }
610
611 /**
612 * @tc.name: SyncLimitTest001
613 * @tc.desc: Sync device with limit query
614 * @tc.type: FUNC
615 * @tc.require:
616 * @tc.author: lianhuix
617 */
618 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest001, TestSize.Level3)
619 {
620 PrepareSyncData(db, 5000);
621 std::vector<std::string> devices = {DEVICE_B};
622 Query query = Query::Select("sync_data").Limit(4500, 100);
623 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b1702(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 624 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
625 EXPECT_EQ(devicesMap.size(), devices.size());
626 }, true);
627 EXPECT_EQ(errCode, OK);
628
629 std::vector<VirtualRowData> data;
630 g_deviceB->GetAllSyncData("sync_data", data);
631 EXPECT_EQ(data.size(), static_cast<size_t>(4500));
632 std::string checkSql = "select * from sync_data limit 4500 offset 100;";
633 CheckSyncData(db, checkSql, data);
634 }
635
636 /**
637 * @tc.name: SyncLimitTest002
638 * @tc.desc: Sync device with limit query
639 * @tc.type: FUNC
640 * @tc.require:
641 * @tc.author: lianhuix
642 */
643 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest002, TestSize.Level3)
644 {
645 PrepareSyncData(db, 5000);
646
647 std::vector<std::string> devices = {DEVICE_B};
648 Query query = Query::Select("sync_data").Limit(5000, 2000);
649 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b1802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 650 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
651 EXPECT_EQ(devicesMap.size(), devices.size());
652 }, true);
653 EXPECT_EQ(errCode, OK);
654
655 std::vector<VirtualRowData> data;
656 g_deviceB->GetAllSyncData("sync_data", data);
657 EXPECT_EQ(data.size(), static_cast<size_t>(3000));
658 std::string checkSql = "select * from sync_data limit 5000 offset 2000;";
659 CheckSyncData(db, checkSql, data);
660 }
661
662 /**
663 * @tc.name: SyncLimitTest003
664 * @tc.desc: Sync device with limit query
665 * @tc.type: FUNC
666 * @tc.require:
667 * @tc.author: lianhuix
668 */
669 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest003, TestSize.Level3)
670 {
671 PrepareSyncData(db, 5000);
672
673 std::vector<std::string> devices = {DEVICE_B};
674 Query query = Query::Select("sync_data").OrderBy("timestamp").Limit(4500, 1500);
675 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b1902(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 676 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
677 EXPECT_EQ(devicesMap.size(), devices.size());
678 }, true);
679 EXPECT_EQ(errCode, OK);
680
681 std::vector<VirtualRowData> data;
682 g_deviceB->GetAllSyncData("sync_data", data);
683 EXPECT_EQ(data.size(), static_cast<size_t>(3500));
684 std::string checkSql = "select * from sync_data order by timestamp limit 4500 offset 1500;";
685 CheckSyncData(db, checkSql, data);
686 }
687
688 /**
689 * @tc.name: SyncOrderByTest001
690 * @tc.desc: Sync device with limit query
691 * @tc.type: FUNC
692 * @tc.require:
693 * @tc.author: lianhuix
694 */
695 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncOrderByTest001, TestSize.Level3)
696 {
697 PrepareSyncData(db, 5000);
698
699 std::vector<std::string> devices = {DEVICE_B};
700 Query query = Query::Select("sync_data").OrderBy("timestamp");
701 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b1a02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 702 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
703 EXPECT_EQ(devicesMap.size(), devices.size());
704 }, true);
705 EXPECT_EQ(errCode, OK);
706
707 std::vector<VirtualRowData> data;
708 g_deviceB->GetAllSyncData("sync_data", data);
709 EXPECT_EQ(data.size(), static_cast<size_t>(5000));
710 std::string checkSql = "select * from sync_data order by timestamp";
711 CheckSyncData(db, checkSql, data);
712 }
713
714 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest001, TestSize.Level1)
715 {
716 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
717 AddDeviceSchema(g_deviceB, db, "student_1");
718
719 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
720 EXPECT_EQ(status, OK);
721
722 std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 2, 95);";
723 EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
724
725 std::vector<std::string> devices = {DEVICE_B};
726 Query query = Query::Select("sTudENT_1");
727 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b1b02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 728 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
729 EXPECT_EQ(devicesMap.size(), devices.size());
730 }, true);
731 EXPECT_EQ(status, OK);
732
733 std::vector<VirtualRowData> data;
734 g_deviceB->GetAllSyncData("student_1", data);
735 EXPECT_EQ(data.size(), 1u);
736 }
737
738 namespace {
739 struct StudentInOrder {
740 int id_;
741 std::string name_;
742 int level_;
743 int score_;
744
operator ()__anonce34f60b1c11::StudentInOrder745 VirtualRowData operator() () const
746 {
747 VirtualRowData virtualRowData;
748 DataValue d1;
749 d1 = (int64_t)id_;
750 virtualRowData.objectData.PutDataValue("id", d1);
751 DataValue d2;
752 d2.SetText(name_);
753 virtualRowData.objectData.PutDataValue("name", d2);
754 DataValue d3;
755 d3 = (int64_t)level_;
756 virtualRowData.objectData.PutDataValue("level", d3);
757 DataValue d4;
758 d4 = (int64_t)score_;
759 virtualRowData.objectData.PutDataValue("score", d4);
760 virtualRowData.logInfo.dataKey = 3; // 3 fake datakey
761 virtualRowData.logInfo.device = DEVICE_B;
762 virtualRowData.logInfo.originDev = DEVICE_B;
763 virtualRowData.logInfo.timestamp = 3170194300890338180; // 3170194300890338180 fake timestamp
764 virtualRowData.logInfo.wTimestamp = 3170194300890338180; // 3170194300890338180 fake timestamp
765 virtualRowData.logInfo.flag = 2; // 2 fake flag
766
767 std::vector<uint8_t> hashKey;
768 DBCommon::CalcValueHash({}, hashKey);
769 virtualRowData.logInfo.hashKey = hashKey;
770 return virtualRowData;
771 }
772 };
773 }
774
775 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest002, TestSize.Level1)
776 {
777 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
778 AddDeviceSchema(g_deviceB, db, "student_1");
779
780 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
781 EXPECT_EQ(status, OK);
782
783 g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
784
785 std::vector<std::string> devices = {DEVICE_B};
786 Query query = Query::Select("sTudENT_1");
787 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonce34f60b1d02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 788 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
789 EXPECT_EQ(devicesMap.size(), devices.size());
790 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
791 }, true);
792 EXPECT_EQ(status, OK);
793
794 std::string deviceTableName = g_mgr.GetDistributedTableName(DEVICE_B, "student_1");
__anonce34f60b1e02(sqlite3_stmt *stmt) 795 RelationalTestUtils::ExecSql(db, "select count(*) from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
796 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1);
797 return OK;
798 });
799
800 status = delegate->RemoveDeviceData(DEVICE_B, "sTudENT_1");
801 EXPECT_EQ(status, OK);
802
__anonce34f60b1f02(sqlite3_stmt *stmt) 803 RelationalTestUtils::ExecSql(db, "select count(*) from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
804 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 0);
805 return OK;
806 });
807 }
808
809 /**
810 * @tc.name: TableNameCaseInsensitiveTest003
811 * @tc.desc: Test distributed tables sync with table names in different case
812 * @tc.type: FUNC
813 * @tc.require:
814 * @tc.author: liuhongyang
815 */
816 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest003, TestSize.Level1)
817 {
818 /**
819 * @tc.steps:step1. Close the delegate, and open in Collaboration mode
820 * @tc.expected: step1. ok
821 */
822 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
823 delegate = nullptr;
824 RelationalStoreDelegate::Option option;
825 option.tableMode = DistributedTableMode::COLLABORATION;
826 EXPECT_EQ(g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, option, delegate), OK);
827 ASSERT_NE(delegate, nullptr);
828 /**
829 * @tc.steps:step2. Create student_1 table in distributed mode, and insert one fake data
830 * @tc.expected: step2. ok
831 */
832 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
833 AddDeviceSchema(g_deviceB, db, "student_1");
834 EXPECT_EQ(delegate->CreateDistributedTable("StUDent_1"), OK);
835 DistributedDB::DistributedSchema distributedSchema;
836 distributedSchema.tables.push_back({"sTudeNt_1", {{"id", true, true}, {"name"}, {"level"}, {"score"}}});
837 EXPECT_EQ(delegate->SetDistributedSchema(distributedSchema), OK);
838 g_deviceB->SetDistributedSchema(distributedSchema);
839 g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
840 /**
841 * @tc.steps:step3. Sync with table name in different case
842 * @tc.expected: step3. ok
843 */
844 std::vector<std::string> devices = {DEVICE_B};
845 Query query = Query::Select("sTudENT_1");
846 DBStatus status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonce34f60b2002(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 847 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
848 EXPECT_EQ(devicesMap.size(), devices.size());
849 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
850 }, true);
851 EXPECT_EQ(status, OK);
852 }
853
854 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest001, TestSize.Level1)
855 {
856 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER), SQLITE_OK);
857 AddDeviceSchema(g_deviceB, db, "student_1");
858 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student_1;"), SQLITE_OK);
859
860 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
861 AddDeviceSchema(g_deviceB, db, "student_1");
862
863 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
864 EXPECT_EQ(status, OK);
865
866 std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 4, 95);";
867 EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
868
869 std::vector<std::string> devices = {DEVICE_B};
870 Query query = Query::Select("sTudENT_1").EqualTo("ID", 1001); // 1001 : id
871 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b2102(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 872 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
873 EXPECT_EQ(devicesMap.size(), devices.size());
874 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
875 }, true);
876 EXPECT_EQ(status, OK);
877
878 std::vector<VirtualRowData> data;
879 g_deviceB->GetAllSyncData("student_1", data);
880 EXPECT_EQ(data.size(), 1u);
881 DataValue value;
882 data[0].objectData.GetDataValue("id", value);
883 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
884 int64_t intVal;
885 value.GetInt64(intVal);
886 EXPECT_EQ(intVal, (int64_t)1001); // 1001 : id
887
888 data[0].objectData.GetDataValue("name", value);
889 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_TEXT);
890 std::string strVal;
891 value.GetText(strVal);
892 EXPECT_EQ(strVal, "xue");
893
894 data[0].objectData.GetDataValue("level", value);
895 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
896 value.GetInt64(intVal);
897 EXPECT_EQ(intVal, (int64_t)4); // 4 level
898
899 data[0].objectData.GetDataValue("score", value);
900 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
901 value.GetInt64(intVal);
902 EXPECT_EQ(intVal, (int64_t)95); // 95 score
903 }
904
905 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest002, TestSize.Level1)
906 {
907 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER), SQLITE_OK);
908 AddDeviceSchema(g_deviceB, db, "student_1");
909 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student_1;"), SQLITE_OK);
910
911 g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
912
913 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
914
915 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
916 EXPECT_EQ(status, OK);
917
918 std::vector<std::string> devices = {DEVICE_B};
919 Query query = Query::Select("sTudENT_1").EqualTo("ID", 1001); // 1001 id
920 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonce34f60b2202(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 921 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
922 EXPECT_EQ(devicesMap.size(), devices.size());
923 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
924 }, true);
925 EXPECT_EQ(status, OK);
926
927 std::string deviceTableName = g_mgr.GetDistributedTableName(DEVICE_B, "student_1");
__anonce34f60b2302(sqlite3_stmt *stmt) 928 RelationalTestUtils::ExecSql(db, "select * from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
929 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1001); // 1001 id
930 std::string value;
931 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, value), E_OK);
932 EXPECT_EQ(value, "xue");
933 EXPECT_EQ(sqlite3_column_int64(stmt, 2), 4); // 4 level
934 EXPECT_EQ(sqlite3_column_int64(stmt, 3), 91); // 91 score
935 return OK;
936 });
937 }
938
939 /**
940 * @tc.name: SyncZeroBlobTest001
941 * @tc.desc: Sync device with zero blob
942 * @tc.type: FUNC
943 * @tc.require:
944 * @tc.author: lianhuix
945 */
946 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest001, TestSize.Level1)
947 {
948 EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK);
949 EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK);
950 AddDeviceSchema(g_deviceB, db, "tbl_all_type");
951
952 // prepare with zero blob data
953 std::string insertSql = "INSERT INTO tbl_all_type VALUES(?, ?, ?, ?, ?, ?)";
__anonce34f60b2402(sqlite3_stmt *stmt) 954 int ret = RelationalTestUtils::ExecSql(db, insertSql, [] (sqlite3_stmt *stmt) {
955 sqlite3_bind_int64(stmt, 1, 1001); // 1, 1001 bind index, bind value
956 sqlite3_bind_int64(stmt, 2, 12344); // 2, 12344 bind index, bind value
957 sqlite3_bind_double(stmt, 3, 1.234); // 3, 1.234 bind index, bind value
958 SQLiteUtils::BindTextToStatement(stmt, 4, ""); // 4, bind index
959 SQLiteUtils::BindBlobToStatement(stmt, 5, {}); // 5,bind index
960 return E_OK;
961 }, nullptr);
962 EXPECT_EQ(ret, E_OK);
963
964 std::vector<std::string> devices = {DEVICE_B};
965 Query query = Query::Select("tbl_all_type");
966 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b2502(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 967 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
968 EXPECT_EQ(devicesMap.size(), devices.size());
969 for (const auto &itDev : devicesMap) {
970 for (const auto &itTbl : itDev.second) {
971 EXPECT_EQ(itTbl.status, OK);
972 }
973 }
974 }, true);
975 EXPECT_EQ(errCode, OK);
976
977 std::vector<VirtualRowData> data;
978 g_deviceB->GetAllSyncData("tbl_all_type", data);
979 EXPECT_EQ(data.size(), 1U);
980 for (const auto &it : data) {
981 DataValue val;
982 it.objectData.GetDataValue("id", val);
983 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER);
984 it.objectData.GetDataValue("f_int", val);
985 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER);
986 it.objectData.GetDataValue("f_real", val);
987 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_REAL);
988 it.objectData.GetDataValue("f_text", val);
989 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_TEXT);
990 it.objectData.GetDataValue("f_blob", val);
991 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_BLOB);
992 it.objectData.GetDataValue("f_none", val);
993 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_NULL);
994 }
995 }
996
997 namespace {
998 struct TblAllType {
999 DataValue id_;
1000 DataValue fInt_;
1001 DataValue fReal_;
1002 DataValue fText_;
1003 DataValue fBlob_;
1004 DataValue fNone_;
1005
TblAllType__anonce34f60b2611::TblAllType1006 TblAllType(int64_t id, int64_t fInt, double fReal, const std::string &fText, const Blob &fBlob)
1007 {
1008 id_ = id;
1009 fInt_ = fInt;
1010 fReal_ = fReal;
1011 fText_ = fText;
1012 fBlob_ = fBlob;
1013 }
1014
operator ()__anonce34f60b2611::TblAllType1015 VirtualRowData operator() () const
1016 {
1017 VirtualRowData virtualRowData;
1018 virtualRowData.objectData.PutDataValue("id", id_);
1019 virtualRowData.objectData.PutDataValue("f_int", fInt_);
1020 virtualRowData.objectData.PutDataValue("f_real", fReal_);
1021 virtualRowData.objectData.PutDataValue("f_text", fText_);
1022 virtualRowData.objectData.PutDataValue("f_blob", fBlob_);
1023 virtualRowData.objectData.PutDataValue("f_none", fNone_);
1024
1025 virtualRowData.logInfo.dataKey = 4; // 4 fake datakey
1026 virtualRowData.logInfo.device = DEVICE_B;
1027 virtualRowData.logInfo.originDev = DEVICE_B;
1028 virtualRowData.logInfo.timestamp = 3170194300891338180; // 3170194300891338180 fake timestamp
1029 virtualRowData.logInfo.wTimestamp = 3170194300891338180; // 3170194300891338180 fake timestamp
1030 virtualRowData.logInfo.flag = 2; // 2 fake flag
1031
1032 std::vector<uint8_t> hashKey;
1033 DBCommon::CalcValueHash({}, hashKey);
1034 virtualRowData.logInfo.hashKey = hashKey;
1035 return virtualRowData;
1036 }
1037 };
1038 }
1039
1040 /**
1041 * @tc.name: SyncZeroBlobTest002
1042 * @tc.desc: Sync device with zero blob
1043 * @tc.type: FUNC
1044 * @tc.require:
1045 * @tc.author: lianhuix
1046 */
1047 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest002, TestSize.Level1)
1048 {
1049 EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK);
1050 EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK);
1051 AddDeviceSchema(g_deviceB, db, "tbl_all_type");
1052
1053 std::vector<VirtualRowData> dataList;
1054 g_deviceB->PutDeviceData("tbl_all_type",
1055 std::vector<TblAllType> {{1001, 12344, 1.234, "", {}}}); // 1001, 12344, 1.234 : fake data
1056
1057 std::vector<std::string> devices = {DEVICE_B};
1058 Query query = Query::Select("tbl_all_type");
1059 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonce34f60b2702(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1060 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1061 EXPECT_EQ(devicesMap.size(), devices.size());
1062 for (const auto &itDev : devicesMap) {
1063 for (const auto &itTbl : itDev.second) {
1064 EXPECT_EQ(itTbl.status, OK);
1065 }
1066 }
1067 }, true);
1068 EXPECT_EQ(errCode, OK);
1069
1070 std::string devictTbl = RelationalStoreManager::GetDistributedTableName(DEVICE_B, "tbl_all_type");
1071 std::string insertSql = "SELECT * FROM " + devictTbl;
1072 int resCnt = 0;
__anonce34f60b2802(sqlite3_stmt *stmt) 1073 int ret = RelationalTestUtils::ExecSql(db, insertSql, nullptr, [&resCnt](sqlite3_stmt *stmt) {
1074 EXPECT_EQ(sqlite3_column_type(stmt, 0), SQLITE_INTEGER);
1075 EXPECT_EQ(sqlite3_column_int(stmt, 0), 1001); // 1001: fake data
1076
1077 EXPECT_EQ(sqlite3_column_type(stmt, 1), SQLITE_INTEGER); // 1: column index
1078 EXPECT_EQ(sqlite3_column_int(stmt, 1), 12344); // 1: column index; 12344: fake data
1079
1080 EXPECT_EQ(sqlite3_column_type(stmt, 2), SQLITE_FLOAT); // 2: column index
1081 EXPECT_EQ(sqlite3_column_double(stmt, 2), 1.234); // 2: column index; 1.234: fake data
1082
1083 EXPECT_EQ(sqlite3_column_type(stmt, 3), SQLITE_TEXT); // 3: column index
1084 std::string strVal;
1085 SQLiteUtils::GetColumnTextValue(stmt, 3, strVal); // 3: column index
1086 EXPECT_EQ(strVal, "");
1087
1088 EXPECT_EQ(sqlite3_column_type(stmt, 4), SQLITE_BLOB); // 4: column index
1089 std::vector<uint8_t> blobVal;
1090 SQLiteUtils::GetColumnBlobValue(stmt, 4, blobVal); // 4: column index
1091 EXPECT_EQ(blobVal, std::vector<uint8_t> {});
1092
1093 EXPECT_EQ(sqlite3_column_type(stmt, 5), SQLITE_NULL); // 5: column index
1094 resCnt++;
1095 return E_OK;
1096 });
1097 EXPECT_EQ(resCnt, 1);
1098 EXPECT_EQ(ret, E_OK);
1099 }
1100
1101 /**
1102 * @tc.name: RuntimeConfig001
1103 * @tc.desc: Runtime config api
1104 * @tc.type: FUNC
1105 * @tc.require:
1106 * @tc.author: zhangqiquan
1107 */
1108 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RuntimeConfig001, TestSize.Level1)
1109 {
1110 DBStatus status = RuntimeConfig::SetProcessLabel("", "");
1111 EXPECT_EQ(status, INVALID_ARGS);
1112 status = RuntimeConfig::SetProcessLabel("DistributedDBInterfacesRelationalSyncTest", "RuntimeConfig001");
1113 EXPECT_EQ(status, OK);
1114 status = RuntimeConfig::SetProcessCommunicator(nullptr);
1115 if (!RuntimeContext::GetInstance()->IsCommunicatorAggregatorValid()) {
1116 EXPECT_EQ(status, OK);
1117 }
1118 EXPECT_EQ(RuntimeConfig::IsProcessSystemApiAdapterValid(),
1119 RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid());
1120 }
1121
1122 /**
1123 * @tc.name: RelationalSyncRangeTest001
1124 * @tc.desc: Test with sync interface, range query is not support
1125 * @tc.type: FUNC
1126 * @tc.require:
1127 * @tc.author: mazhao
1128 */
1129 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncRangeTest001, TestSize.Level1)
1130 {
1131 std::vector<std::string> devices = {DEVICE_A};
1132 Query query = Query::Select("sync_data").Range({}, {});
1133 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonce34f60b2902(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1134 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1135 EXPECT_EQ(devicesMap.size(), devices.size());
1136 }, true);
1137
1138 EXPECT_EQ(errCode, NOT_SUPPORT);
1139 }
1140
1141 /**
1142 * @tc.name: RelationalSyncTest011
1143 * @tc.desc: Test sync with invalid parm
1144 * @tc.type: FUNC
1145 * @tc.require:
1146 * @tc.author: caihaoting
1147 */
1148 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest011, TestSize.Level1)
1149 {
1150 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1151 ASSERT_NE(db, nullptr);
1152 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1153 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "CREATE TABLE IF NOT EXISTS t2(a INT, b TEXT)"), SQLITE_OK);
1154 AddDeviceSchema(g_deviceB, db, "t2");
1155 RelationalStoreDelegate *delegate = nullptr;
1156 auto observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1157 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID,
1158 { .observer = observer }, delegate);
1159 EXPECT_EQ(status, OK);
1160 ASSERT_NE(delegate, nullptr);
1161 EXPECT_EQ(delegate->CreateDistributedTable("t2"), OK);
1162
1163 std::vector<std::string> devices = {DEVICE_B};
1164 Query query = Query::Select("t2");
1165 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_CLOUD_MERGE, query, nullptr, true), NOT_SUPPORT);
1166
1167 auto relationalStoreImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1168 EXPECT_EQ(relationalStoreImpl->Close(), OK);
1169 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, true), DB_ERROR);
1170
1171 std::mutex dataMutex;
1172 std::condition_variable cv;
1173 bool finish = false;
__anonce34f60b2a02(const std::map<std::string, SyncProcess> &process) 1174 auto callback = [&cv, &dataMutex, &finish, &status](const std::map<std::string, SyncProcess> &process) {
1175 for (const auto &item: process) {
1176 if (item.second.process == DistributedDB::FINISHED) {
1177 {
1178 EXPECT_EQ(item.second.errCode, status);
1179 std::lock_guard<std::mutex> autoLock(dataMutex);
1180 finish = true;
1181 }
1182 cv.notify_one();
1183 }
1184 }
1185 };
1186 int64_t syncWaitTime = 60;
1187 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, callback, syncWaitTime), DB_ERROR);
1188
1189 CloudSyncOption option;
1190 option.devices = devices;
1191 option.mode = SyncMode::SYNC_MODE_PULL_ONLY;
1192 option.query = query;
1193 option.waitTime = syncWaitTime;
1194 EXPECT_EQ(delegate->Sync(option, callback), DB_ERROR);
1195
1196 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1197 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1198 delete observer;
1199 }
1200