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: AR000GK58F
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,
__anonf1fa0da10302(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: AR000GK58F
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,
__anonf1fa0da10402(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: AR000GK58F
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,
__anonf1fa0da10502(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: AR000GK58F
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,
__anonf1fa0da10602(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: AR000GK58F
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,
__anonf1fa0da10702(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: AR000GK58F
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,
__anonf1fa0da10802(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: AR000GK58F
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,
__anonf1fa0da10902(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: AR000GK58F
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,
__anonf1fa0da10a02(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,
__anonf1fa0da10b02(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: AR000GK58F
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,
__anonf1fa0da10c02(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,
__anonf1fa0da10d02(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,
__anonf1fa0da10e02(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: AR000GK58F
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,
__anonf1fa0da10f02(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,
__anonf1fa0da11002(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,
__anonf1fa0da11102(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: AR000GK58F
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, DBConstant::RELATIONAL_PREFIX + "student_1" + "_log");
509     EXPECT_EQ(cnt, 2);
510 }
511 
512 /**
513   * @tc.name: UpgradeTriggerTest001
514   * @tc.desc: Test upgrade from old version
515   * @tc.type: FUNC
516   * @tc.require: AR000GK58F
517   * @tc.author: lianhuix
518   */
519 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, UpgradeTriggerTest001, TestSize.Level1)
520 {
521     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
522     RelationalTestUtils::CreateDeviceTable(db, "student_1", DEVICE_A);
523 
524     DBStatus status = delegate->CreateDistributedTable("student_1");
525     EXPECT_EQ(status, OK);
526 
527     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
528     delegate = nullptr;
529 
530     FakeOldVersionDB(db);
531 
532     status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
533     EXPECT_EQ(status, OK);
534     ASSERT_NE(delegate, nullptr);
535 
536     // checkTrigger
537     std::string resultTrigger;
538     int errCode = RelationalTestUtils::ExecSql(db, "SELECT sql FROM sqlite_master WHERE type = ? AND name = ?",
__anonf1fa0da11202(sqlite3_stmt *stmt) 539         [](sqlite3_stmt *stmt) {
540             (void)SQLiteUtils::BindTextToStatement(stmt, 1, "trigger"); // 1: bind index
541             (void)SQLiteUtils::BindTextToStatement(stmt, 2, "naturalbase_rdb_student_1_ON_UPDATE"); // 2: bind index
542             return E_OK;
543         }, [&resultTrigger](sqlite3_stmt *stmt) {
544             (void)SQLiteUtils::GetColumnTextValue(stmt, 0, resultTrigger);
545             return E_OK;
546         });
547     EXPECT_EQ(errCode, E_OK);
548     LOGD("result trigger: %s", resultTrigger.c_str());
549     std::string expectTrigger = "CREATE TRIGGER naturalbase_rdb_student_1_ON_UPDATE AFTER UPDATE \n"
550         "ON 'student_1'\n"
551         "BEGIN\n"
552         "\t UPDATE naturalbase_rdb_aux_student_1_log SET data_key=-1,timestamp=get_sys_time(0), device='',"
553         " flag=0x03 WHERE hash_key=calc_hash(OLD.'id', 0) AND flag&0x02=0x02;\n"
554         "\t INSERT OR REPLACE INTO naturalbase_rdb_aux_student_1_log VALUES (NEW._rowid_, '', '', get_sys_time(0), "
555         "get_last_time(), CASE WHEN (calc_hash(NEW.'id', 0) != calc_hash(NEW.'id', 0)) " \
556         "THEN 0x02 ELSE 0x22 END, calc_hash(NEW.'id', 0), '', '', '', '', '', 0);\n"
557         "END";
558     EXPECT_TRUE(resultTrigger == expectTrigger);
559 }
560 
561 
562 namespace {
PrepareSyncData(sqlite3 * db,int dataSize)563 void PrepareSyncData(sqlite3 *db, int dataSize)
564 {
565     int i = 1;
566     std::string insertSql = "INSERT INTO sync_data VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
567     int ret = RelationalTestUtils::ExecSql(db, insertSql, [&i, dataSize] (sqlite3_stmt *stmt) {
568         SQLiteUtils::BindTextToStatement(stmt, 1, "KEY_" + std::to_string(i));
569         SQLiteUtils::BindTextToStatement(stmt, 2, "VAL_" + std::to_string(i));
570         sqlite3_bind_int64(stmt, 3, 1000000 - (1000 + i));
571         sqlite3_bind_int64(stmt, 4, i % 4);
572         SQLiteUtils::BindTextToStatement(stmt, 5, "DEV_" + std::to_string(i));
573         SQLiteUtils::BindTextToStatement(stmt, 6, "KEY_" + std::to_string(i));
574         SQLiteUtils::BindTextToStatement(stmt, 7, "HASHKEY_" + std::to_string(i));
575         sqlite3_bind_int64(stmt, 8, 1000 + i);
576         return (i++ == dataSize) ? E_OK : -E_UNFINISHED;
577     }, nullptr);
578     EXPECT_EQ(ret, E_OK);
579 }
580 
GetKey(VirtualRowData rowData)581 std::string GetKey(VirtualRowData rowData)
582 {
583     DataValue dataVal;
584     rowData.objectData.GetDataValue("key", dataVal);
585     EXPECT_EQ(dataVal.GetType(), StorageType::STORAGE_TYPE_TEXT);
586     std::string dataStr;
587     EXPECT_EQ(dataVal.GetText(dataStr), E_OK);
588     return dataStr;
589 }
590 
CheckSyncData(sqlite3 * db,const std::string & checkSql,const std::vector<VirtualRowData> & resultData)591 void CheckSyncData(sqlite3 *db, const std::string &checkSql, const std::vector<VirtualRowData> &resultData)
592 {
593     std::set<std::string> keySet;
594     keySet.clear();
595     for (size_t i = 0; i < resultData.size(); i++) {
596         std::string ss = GetKey(resultData[i]);
597         keySet.insert(ss);
598     }
599     EXPECT_EQ(keySet.size(), resultData.size());
600 
601     RelationalTestUtils::ExecSql(db, checkSql, nullptr, [keySet](sqlite3_stmt *stmt) {
602         std::string val;
603         SQLiteUtils::GetColumnTextValue(stmt, 0, val);
604         EXPECT_NE(keySet.find(val), keySet.end());
605         return E_OK;
606     });
607 }
608 }
609 
610 /**
611   * @tc.name: SyncLimitTest001
612   * @tc.desc: Sync device with limit query
613   * @tc.type: FUNC
614   * @tc.require:
615   * @tc.author: lianhuix
616   */
617 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest001, TestSize.Level3)
618 {
619     PrepareSyncData(db, 5000);
620     std::vector<std::string> devices = {DEVICE_B};
621     Query query = Query::Select("sync_data").Limit(4500, 100);
622     int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11702(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 623         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
624             EXPECT_EQ(devicesMap.size(), devices.size());
625         }, true);
626     EXPECT_EQ(errCode, OK);
627 
628     std::vector<VirtualRowData> data;
629     g_deviceB->GetAllSyncData("sync_data", data);
630     EXPECT_EQ(data.size(), static_cast<size_t>(4500));
631     std::string checkSql = "select * from sync_data limit 4500 offset 100;";
632     CheckSyncData(db, checkSql, data);
633 }
634 
635 /**
636   * @tc.name: SyncLimitTest002
637   * @tc.desc: Sync device with limit query
638   * @tc.type: FUNC
639   * @tc.require:
640   * @tc.author: lianhuix
641   */
642 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest002, TestSize.Level3)
643 {
644     PrepareSyncData(db, 5000);
645 
646     std::vector<std::string> devices = {DEVICE_B};
647     Query query = Query::Select("sync_data").Limit(5000, 2000);
648     int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 649         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
650             EXPECT_EQ(devicesMap.size(), devices.size());
651         }, true);
652     EXPECT_EQ(errCode, OK);
653 
654     std::vector<VirtualRowData> data;
655     g_deviceB->GetAllSyncData("sync_data", data);
656     EXPECT_EQ(data.size(), static_cast<size_t>(3000));
657     std::string checkSql = "select * from sync_data limit 5000 offset 2000;";
658     CheckSyncData(db, checkSql, data);
659 }
660 
661 /**
662   * @tc.name: SyncLimitTest003
663   * @tc.desc: Sync device with limit query
664   * @tc.type: FUNC
665   * @tc.require:
666   * @tc.author: lianhuix
667   */
668 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest003, TestSize.Level3)
669 {
670     PrepareSyncData(db, 5000);
671 
672     std::vector<std::string> devices = {DEVICE_B};
673     Query query = Query::Select("sync_data").OrderBy("timestamp").Limit(4500, 1500);
674     int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11902(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 675         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
676             EXPECT_EQ(devicesMap.size(), devices.size());
677         }, true);
678     EXPECT_EQ(errCode, OK);
679 
680     std::vector<VirtualRowData> data;
681     g_deviceB->GetAllSyncData("sync_data", data);
682     EXPECT_EQ(data.size(), static_cast<size_t>(3500));
683     std::string checkSql = "select * from sync_data order by timestamp limit 4500 offset 1500;";
684     CheckSyncData(db, checkSql, data);
685 }
686 
687 /**
688   * @tc.name: SyncOrderByTest001
689   * @tc.desc: Sync device with limit query
690   * @tc.type: FUNC
691   * @tc.require:
692   * @tc.author: lianhuix
693   */
694 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncOrderByTest001, TestSize.Level3)
695 {
696     PrepareSyncData(db, 5000);
697 
698     std::vector<std::string> devices = {DEVICE_B};
699     Query query = Query::Select("sync_data").OrderBy("timestamp");
700     int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11a02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 701         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
702             EXPECT_EQ(devicesMap.size(), devices.size());
703         }, true);
704     EXPECT_EQ(errCode, OK);
705 
706     std::vector<VirtualRowData> data;
707     g_deviceB->GetAllSyncData("sync_data", data);
708     EXPECT_EQ(data.size(), static_cast<size_t>(5000));
709     std::string checkSql = "select * from sync_data order by timestamp";
710     CheckSyncData(db, checkSql, data);
711 }
712 
713 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest001, TestSize.Level1)
714 {
715     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
716     AddDeviceSchema(g_deviceB, db, "student_1");
717 
718     DBStatus status = delegate->CreateDistributedTable("StUDent_1");
719     EXPECT_EQ(status, OK);
720 
721     std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 2, 95);";
722     EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
723 
724     std::vector<std::string> devices = {DEVICE_B};
725     Query query = Query::Select("sTudENT_1");
726     status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11b02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 727         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
728             EXPECT_EQ(devicesMap.size(), devices.size());
729         }, true);
730     EXPECT_EQ(status, OK);
731 
732     std::vector<VirtualRowData> data;
733     g_deviceB->GetAllSyncData("student_1", data);
734     EXPECT_EQ(data.size(), 1u);
735 }
736 
737 namespace {
738 struct StudentInOrder {
739     int id_;
740     std::string name_;
741     int level_;
742     int score_;
743 
operator ()__anonf1fa0da11c10::StudentInOrder744     VirtualRowData operator() () const
745     {
746         VirtualRowData virtualRowData;
747         DataValue d1;
748         d1 = (int64_t)id_;
749         virtualRowData.objectData.PutDataValue("id", d1);
750         DataValue d2;
751         d2.SetText(name_);
752         virtualRowData.objectData.PutDataValue("name", d2);
753         DataValue d3;
754         d3 = (int64_t)level_;
755         virtualRowData.objectData.PutDataValue("level", d3);
756         DataValue d4;
757         d4 = (int64_t)score_;
758         virtualRowData.objectData.PutDataValue("score", d4);
759         virtualRowData.logInfo.dataKey = 3; // 3 fake datakey
760         virtualRowData.logInfo.device = DEVICE_B;
761         virtualRowData.logInfo.originDev = DEVICE_B;
762         virtualRowData.logInfo.timestamp = 3170194300890338180; // 3170194300890338180 fake timestamp
763         virtualRowData.logInfo.wTimestamp = 3170194300890338180; // 3170194300890338180 fake timestamp
764         virtualRowData.logInfo.flag = 2; // 2 fake flag
765 
766         std::vector<uint8_t> hashKey;
767         DBCommon::CalcValueHash({}, hashKey);
768         virtualRowData.logInfo.hashKey = hashKey;
769         return virtualRowData;
770     }
771 };
772 }
773 
774 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest002, TestSize.Level1)
775 {
776     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
777     AddDeviceSchema(g_deviceB, db, "student_1");
778 
779     DBStatus status = delegate->CreateDistributedTable("StUDent_1");
780     EXPECT_EQ(status, OK);
781 
782     g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
783 
784     std::vector<std::string> devices = {DEVICE_B};
785     Query query = Query::Select("sTudENT_1");
786     status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonf1fa0da11d02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 787         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
788             EXPECT_EQ(devicesMap.size(), devices.size());
789             EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
790         }, true);
791     EXPECT_EQ(status, OK);
792 
793     std::string deviceTableName = g_mgr.GetDistributedTableName(DEVICE_B, "student_1");
__anonf1fa0da11e02(sqlite3_stmt *stmt) 794     RelationalTestUtils::ExecSql(db, "select count(*) from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
795         EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1);
796         return OK;
797     });
798 
799     status = delegate->RemoveDeviceData(DEVICE_B, "sTudENT_1");
800     EXPECT_EQ(status, OK);
801 
__anonf1fa0da11f02(sqlite3_stmt *stmt) 802     RelationalTestUtils::ExecSql(db, "select count(*) from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
803         EXPECT_EQ(sqlite3_column_int64(stmt, 0), 0);
804         return OK;
805     });
806 }
807 
808 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest001, TestSize.Level1)
809 {
810     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER), SQLITE_OK);
811     AddDeviceSchema(g_deviceB, db, "student_1");
812     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student_1;"), SQLITE_OK);
813 
814     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
815     AddDeviceSchema(g_deviceB, db, "student_1");
816 
817     DBStatus status = delegate->CreateDistributedTable("StUDent_1");
818     EXPECT_EQ(status, OK);
819 
820     std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 4, 95);";
821     EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
822 
823     std::vector<std::string> devices = {DEVICE_B};
824     Query query = Query::Select("sTudENT_1").EqualTo("ID", 1001); // 1001 : id
825     status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da12002(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 826         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
827             EXPECT_EQ(devicesMap.size(), devices.size());
828             EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
829         }, true);
830     EXPECT_EQ(status, OK);
831 
832     std::vector<VirtualRowData> data;
833     g_deviceB->GetAllSyncData("student_1", data);
834     EXPECT_EQ(data.size(), 1u);
835     DataValue value;
836     data[0].objectData.GetDataValue("id", value);
837     EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
838     int64_t intVal;
839     value.GetInt64(intVal);
840     EXPECT_EQ(intVal, (int64_t)1001); // 1001 : id
841 
842     data[0].objectData.GetDataValue("name", value);
843     EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_TEXT);
844     std::string strVal;
845     value.GetText(strVal);
846     EXPECT_EQ(strVal, "xue");
847 
848     data[0].objectData.GetDataValue("level", value);
849     EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
850     value.GetInt64(intVal);
851     EXPECT_EQ(intVal, (int64_t)4); // 4 level
852 
853     data[0].objectData.GetDataValue("score", value);
854     EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
855     value.GetInt64(intVal);
856     EXPECT_EQ(intVal, (int64_t)95); // 95 score
857 }
858 
859 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest002, TestSize.Level1)
860 {
861     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER), SQLITE_OK);
862     AddDeviceSchema(g_deviceB, db, "student_1");
863     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student_1;"), SQLITE_OK);
864 
865     g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
866 
867     EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
868 
869     DBStatus status = delegate->CreateDistributedTable("StUDent_1");
870     EXPECT_EQ(status, OK);
871 
872     std::vector<std::string> devices = {DEVICE_B};
873     Query query = Query::Select("sTudENT_1").EqualTo("ID", 1001); // 1001 id
874     status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonf1fa0da12102(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 875         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
876             EXPECT_EQ(devicesMap.size(), devices.size());
877             EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
878         }, true);
879     EXPECT_EQ(status, OK);
880 
881     std::string deviceTableName = g_mgr.GetDistributedTableName(DEVICE_B, "student_1");
__anonf1fa0da12202(sqlite3_stmt *stmt) 882     RelationalTestUtils::ExecSql(db, "select * from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
883         EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1001); // 1001 id
884         std::string value;
885         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, value), E_OK);
886         EXPECT_EQ(value, "xue");
887         EXPECT_EQ(sqlite3_column_int64(stmt, 2), 4); // 4 level
888         EXPECT_EQ(sqlite3_column_int64(stmt, 3), 91); // 91 score
889         return OK;
890     });
891 }
892 
893 /**
894   * @tc.name: SyncZeroBlobTest001
895   * @tc.desc: Sync device with zero blob
896   * @tc.type: FUNC
897   * @tc.require:
898   * @tc.author: lianhuix
899   */
900 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest001, TestSize.Level1)
901 {
902     EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK);
903     EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK);
904     AddDeviceSchema(g_deviceB, db, "tbl_all_type");
905 
906     // prepare with zero blob data
907     std::string insertSql = "INSERT INTO tbl_all_type VALUES(?, ?, ?, ?, ?, ?)";
__anonf1fa0da12302(sqlite3_stmt *stmt) 908     int ret = RelationalTestUtils::ExecSql(db, insertSql, [] (sqlite3_stmt *stmt) {
909         sqlite3_bind_int64(stmt, 1, 1001); // 1, 1001 bind index, bind value
910         sqlite3_bind_int64(stmt, 2, 12344); // 2, 12344 bind index, bind value
911         sqlite3_bind_double(stmt, 3, 1.234); // 3, 1.234 bind index, bind value
912         SQLiteUtils::BindTextToStatement(stmt, 4, ""); // 4, bind index
913         SQLiteUtils::BindBlobToStatement(stmt, 5, {}); // 5,bind index
914         return E_OK;
915     }, nullptr);
916     EXPECT_EQ(ret, E_OK);
917 
918     std::vector<std::string> devices = {DEVICE_B};
919     Query query = Query::Select("tbl_all_type");
920     int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da12402(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             for (const auto &itDev : devicesMap) {
924                 for (const auto &itTbl : itDev.second) {
925                     EXPECT_EQ(itTbl.status, OK);
926                 }
927             }
928         }, true);
929     EXPECT_EQ(errCode, OK);
930 
931     std::vector<VirtualRowData> data;
932     g_deviceB->GetAllSyncData("tbl_all_type", data);
933     EXPECT_EQ(data.size(), 1U);
934     for (const auto &it : data) {
935         DataValue val;
936         it.objectData.GetDataValue("id", val);
937         EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER);
938         it.objectData.GetDataValue("f_int", val);
939         EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER);
940         it.objectData.GetDataValue("f_real", val);
941         EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_REAL);
942         it.objectData.GetDataValue("f_text", val);
943         EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_TEXT);
944         it.objectData.GetDataValue("f_blob", val);
945         EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_BLOB);
946         it.objectData.GetDataValue("f_none", val);
947         EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_NULL);
948     }
949 }
950 
951 namespace {
952 struct TblAllType {
953     DataValue id_;
954     DataValue fInt_;
955     DataValue fReal_;
956     DataValue fText_;
957     DataValue fBlob_;
958     DataValue fNone_;
959 
TblAllType__anonf1fa0da12510::TblAllType960     TblAllType(int64_t id, int64_t fInt, double fReal, const std::string &fText, const Blob &fBlob)
961     {
962         id_ = id;
963         fInt_ = fInt;
964         fReal_ = fReal;
965         fText_ = fText;
966         fBlob_ = fBlob;
967     }
968 
operator ()__anonf1fa0da12510::TblAllType969     VirtualRowData operator() () const
970     {
971         VirtualRowData virtualRowData;
972         virtualRowData.objectData.PutDataValue("id", id_);
973         virtualRowData.objectData.PutDataValue("f_int", fInt_);
974         virtualRowData.objectData.PutDataValue("f_real", fReal_);
975         virtualRowData.objectData.PutDataValue("f_text", fText_);
976         virtualRowData.objectData.PutDataValue("f_blob", fBlob_);
977         virtualRowData.objectData.PutDataValue("f_none", fNone_);
978 
979         virtualRowData.logInfo.dataKey = 4; // 4 fake datakey
980         virtualRowData.logInfo.device = DEVICE_B;
981         virtualRowData.logInfo.originDev = DEVICE_B;
982         virtualRowData.logInfo.timestamp = 3170194300891338180; // 3170194300891338180 fake timestamp
983         virtualRowData.logInfo.wTimestamp = 3170194300891338180; // 3170194300891338180 fake timestamp
984         virtualRowData.logInfo.flag = 2; // 2 fake flag
985 
986         std::vector<uint8_t> hashKey;
987         DBCommon::CalcValueHash({}, hashKey);
988         virtualRowData.logInfo.hashKey = hashKey;
989         return virtualRowData;
990     }
991 };
992 }
993 
994 /**
995   * @tc.name: SyncZeroBlobTest002
996   * @tc.desc: Sync device with zero blob
997   * @tc.type: FUNC
998   * @tc.require:
999   * @tc.author: lianhuix
1000   */
1001 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest002, TestSize.Level1)
1002 {
1003     EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK);
1004     EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK);
1005     AddDeviceSchema(g_deviceB, db, "tbl_all_type");
1006 
1007     std::vector<VirtualRowData> dataList;
1008     g_deviceB->PutDeviceData("tbl_all_type",
1009         std::vector<TblAllType> {{1001, 12344, 1.234, "", {}}}); // 1001, 12344, 1.234 : fake data
1010 
1011     std::vector<std::string> devices = {DEVICE_B};
1012     Query query = Query::Select("tbl_all_type");
1013     int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonf1fa0da12602(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1014         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1015             EXPECT_EQ(devicesMap.size(), devices.size());
1016             for (const auto &itDev : devicesMap) {
1017                 for (const auto &itTbl : itDev.second) {
1018                     EXPECT_EQ(itTbl.status, OK);
1019                 }
1020             }
1021         }, true);
1022     EXPECT_EQ(errCode, OK);
1023 
1024     std::string devictTbl = RelationalStoreManager::GetDistributedTableName(DEVICE_B, "tbl_all_type");
1025     std::string insertSql = "SELECT * FROM " + devictTbl;
1026     int resCnt = 0;
__anonf1fa0da12702(sqlite3_stmt *stmt) 1027     int ret = RelationalTestUtils::ExecSql(db, insertSql, nullptr, [&resCnt](sqlite3_stmt *stmt) {
1028         EXPECT_EQ(sqlite3_column_type(stmt, 0), SQLITE_INTEGER);
1029         EXPECT_EQ(sqlite3_column_int(stmt, 0), 1001); // 1001: fake data
1030 
1031         EXPECT_EQ(sqlite3_column_type(stmt, 1), SQLITE_INTEGER); // 1: column index
1032         EXPECT_EQ(sqlite3_column_int(stmt, 1), 12344); // 1: column index; 12344: fake data
1033 
1034         EXPECT_EQ(sqlite3_column_type(stmt, 2), SQLITE_FLOAT); // 2: column index
1035         EXPECT_EQ(sqlite3_column_double(stmt, 2), 1.234); // 2: column index; 1.234: fake data
1036 
1037         EXPECT_EQ(sqlite3_column_type(stmt, 3), SQLITE_TEXT); // 3: column index
1038         std::string strVal;
1039         SQLiteUtils::GetColumnTextValue(stmt, 3, strVal); // 3: column index
1040         EXPECT_EQ(strVal, "");
1041 
1042         EXPECT_EQ(sqlite3_column_type(stmt, 4), SQLITE_BLOB); // 4: column index
1043         std::vector<uint8_t> blobVal;
1044         SQLiteUtils::GetColumnBlobValue(stmt, 4, blobVal); // 4: column index
1045         EXPECT_EQ(blobVal, std::vector<uint8_t> {});
1046 
1047         EXPECT_EQ(sqlite3_column_type(stmt, 5), SQLITE_NULL); // 5: column index
1048         resCnt++;
1049         return E_OK;
1050     });
1051     EXPECT_EQ(resCnt, 1);
1052     EXPECT_EQ(ret, E_OK);
1053 }
1054 
1055 /**
1056   * @tc.name: RuntimeConfig001
1057   * @tc.desc: Runtime config api
1058   * @tc.type: FUNC
1059   * @tc.require:
1060   * @tc.author: zhangqiquan
1061   */
1062 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RuntimeConfig001, TestSize.Level1)
1063 {
1064     DBStatus status = RuntimeConfig::SetProcessLabel("", "");
1065     EXPECT_EQ(status, INVALID_ARGS);
1066     status = RuntimeConfig::SetProcessLabel("DistributedDBInterfacesRelationalSyncTest", "RuntimeConfig001");
1067     EXPECT_EQ(status, OK);
1068     status = RuntimeConfig::SetProcessCommunicator(nullptr);
1069     if (!RuntimeContext::GetInstance()->IsCommunicatorAggregatorValid()) {
1070         EXPECT_EQ(status, OK);
1071     }
1072     EXPECT_EQ(RuntimeConfig::IsProcessSystemApiAdapterValid(),
1073         RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid());
1074 }
1075 
1076 /**
1077   * @tc.name: RelationalSyncRangeTest001
1078   * @tc.desc: Test with sync interface, range query is not support
1079   * @tc.type: FUNC
1080   * @tc.require: DTS2023112110763
1081   * @tc.author: mazhao
1082   */
1083 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncRangeTest001, TestSize.Level1)
1084 {
1085     std::vector<std::string> devices = {DEVICE_A};
1086     Query query = Query::Select("sync_data").Range({}, {});
1087     int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da12802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1088         [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1089             EXPECT_EQ(devicesMap.size(), devices.size());
1090         }, true);
1091 
1092     EXPECT_EQ(errCode, NOT_SUPPORT);
1093 }
1094 
1095 /**
1096   * @tc.name: RelationalSyncTest011
1097   * @tc.desc: Test sync with invalid parm
1098   * @tc.type: FUNC
1099   * @tc.require:
1100   * @tc.author: caihaoting
1101  */
1102 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest011, TestSize.Level1)
1103 {
1104     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1105     ASSERT_NE(db, nullptr);
1106     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1107     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "CREATE TABLE IF NOT EXISTS t2(a INT, b TEXT)"), SQLITE_OK);
1108     AddDeviceSchema(g_deviceB, db, "t2");
1109     RelationalStoreDelegate *delegate = nullptr;
1110     auto observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1111     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID,
1112         { .observer = observer }, delegate);
1113     EXPECT_EQ(status, OK);
1114     ASSERT_NE(delegate, nullptr);
1115     EXPECT_EQ(delegate->CreateDistributedTable("t2"), OK);
1116 
1117     std::vector<std::string> devices = {DEVICE_B};
1118     Query query = Query::Select("t2");
1119     EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_CLOUD_MERGE, query, nullptr, true), NOT_SUPPORT);
1120 
1121     auto relationalStoreImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1122     EXPECT_EQ(relationalStoreImpl->Close(), OK);
1123     EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, true), DB_ERROR);
1124 
1125     std::mutex dataMutex;
1126     std::condition_variable cv;
1127     bool finish = false;
__anonf1fa0da12902(const std::map<std::string, SyncProcess> &process) 1128     auto callback = [&cv, &dataMutex, &finish, &status](const std::map<std::string, SyncProcess> &process) {
1129         for (const auto &item: process) {
1130             if (item.second.process == DistributedDB::FINISHED) {
1131                 {
1132                     EXPECT_EQ(item.second.errCode, status);
1133                     std::lock_guard<std::mutex> autoLock(dataMutex);
1134                     finish = true;
1135                 }
1136                 cv.notify_one();
1137             }
1138         }
1139     };
1140     int64_t syncWaitTime = 60;
1141     EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, callback, syncWaitTime), DB_ERROR);
1142 
1143     CloudSyncOption option;
1144     option.devices = devices;
1145     option.mode = SyncMode::SYNC_MODE_PULL_ONLY;
1146     option.query = query;
1147     option.waitTime = syncWaitTime;
1148     EXPECT_EQ(delegate->Sync(option, callback), DB_ERROR);
1149 
1150     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1151     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1152     delete observer;
1153 }
1154