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