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