• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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