1 /*
2  * Copyright (c) 2021 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 #ifdef RELATIONAL_STORE
16 #include <gtest/gtest.h>
17 
18 #include "data_transformer.h"
19 #include "db_common.h"
20 #include "db_constant.h"
21 #include "db_errno.h"
22 #include "db_types.h"
23 #include "distributeddb_data_generate_unit_test.h"
24 #include "distributeddb_tools_unit_test.h"
25 #include "generic_single_ver_kv_entry.h"
26 #include "kvdb_properties.h"
27 #include "log_print.h"
28 #include "relational_schema_object.h"
29 #include "relational_store_delegate.h"
30 #include "relational_store_instance.h"
31 #include "relational_store_manager.h"
32 #include "relational_store_sqlite_ext.h"
33 #include "relational_sync_able_storage.h"
34 #include "runtime_config.h"
35 #include "sqlite_relational_store.h"
36 #include "sqlite_utils.h"
37 #include "virtual_communicator_aggregator.h"
38 
39 using namespace testing::ext;
40 using namespace DistributedDB;
41 using namespace DistributedDBUnitTest;
42 using namespace std;
43 
44 namespace {
45 string g_testDir;
46 string g_storePath;
47 string g_storeID = "dftStoreID";
48 string g_tableName { "data" };
49 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
50 RelationalStoreDelegate *g_delegate = nullptr;
51 IRelationalStore *g_store = nullptr;
52 
CreateDBAndTable()53 void CreateDBAndTable()
54 {
55     sqlite3 *db = nullptr;
56     int errCode = sqlite3_open(g_storePath.c_str(), &db);
57     if (errCode != SQLITE_OK) {
58         LOGE("open db failed:%d", errCode);
59         sqlite3_close(db);
60         return;
61     }
62 
63     const string sql =
64         "PRAGMA journal_mode=WAL;"
65         "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
66     char *zErrMsg = nullptr;
67     errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &zErrMsg);
68     if (errCode != SQLITE_OK) {
69         LOGE("sql error:%s", zErrMsg);
70         sqlite3_free(zErrMsg);
71     }
72     sqlite3_close(db);
73 }
74 
AddOrUpdateRecord(int64_t key,int64_t value)75 int AddOrUpdateRecord(int64_t key, int64_t value)
76 {
77     sqlite3 *db = nullptr;
78     int errCode = sqlite3_open(g_storePath.c_str(), &db);
79     if (errCode == SQLITE_OK) {
80         const string sql =
81             "INSERT OR REPLACE INTO " + g_tableName + " VALUES(" + to_string(key) + "," + to_string(value) + ");";
82         errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
83     }
84     errCode = SQLiteUtils::MapSQLiteErrno(errCode);
85     sqlite3_close(db);
86     return errCode;
87 }
88 
GetLogData(int key,uint64_t & flag,Timestamp & timestamp,const DeviceID & device="")89 int GetLogData(int key, uint64_t &flag, Timestamp &timestamp, const DeviceID &device = "")
90 {
91     if (!device.empty()) {
92     }
93     const string sql = "SELECT timestamp, flag \
94         FROM " + g_tableName + " as a, " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log as b \
95         WHERE a.key=? AND a.rowid=b.data_key;";
96 
97     sqlite3 *db = nullptr;
98     sqlite3_stmt *statement = nullptr;
99     int errCode = sqlite3_open(g_storePath.c_str(), &db);
100     if (errCode != SQLITE_OK) {
101         LOGE("open db failed:%d", errCode);
102         errCode = SQLiteUtils::MapSQLiteErrno(errCode);
103         goto END;
104     }
105     errCode = SQLiteUtils::GetStatement(db, sql, statement);
106     if (errCode != E_OK) {
107         goto END;
108     }
109     errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, key); // 1 means key's index
110     if (errCode != E_OK) {
111         goto END;
112     }
113     errCode = SQLiteUtils::StepWithRetry(statement, false);
114     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
115         timestamp = static_cast<Timestamp>(sqlite3_column_int64(statement, 0));
116         flag = static_cast<Timestamp>(sqlite3_column_int64(statement, 1));
117         errCode = E_OK;
118     } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
119         errCode = -E_NOT_FOUND;
120     }
121 
122 END:
123     SQLiteUtils::ResetStatement(statement, true, errCode);
124     sqlite3_close(db);
125     return errCode;
126 }
127 
InitStoreProp(const std::string & storePath,const std::string & appId,const std::string & userId,RelationalDBProperties & properties)128 void InitStoreProp(const std::string &storePath, const std::string &appId, const std::string &userId,
129     RelationalDBProperties &properties)
130 {
131     properties.SetStringProp(RelationalDBProperties::DATA_DIR, storePath);
132     properties.SetStringProp(RelationalDBProperties::APP_ID, appId);
133     properties.SetStringProp(RelationalDBProperties::USER_ID, userId);
134     properties.SetStringProp(RelationalDBProperties::STORE_ID, g_storeID);
135     std::string identifier = userId + "-" + appId + "-" + g_storeID;
136     std::string hashIdentifier = DBCommon::TransferHashString(identifier);
137     properties.SetStringProp(RelationalDBProperties::IDENTIFIER_DATA, hashIdentifier);
138 }
139 
GetRelationalStore()140 const RelationalSyncAbleStorage *GetRelationalStore()
141 {
142     RelationalDBProperties properties;
143     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
144     int errCode = E_OK;
145     g_store = RelationalStoreInstance::GetDataBase(properties, errCode);
146     if (g_store == nullptr) {
147         LOGE("Get db failed:%d", errCode);
148         return nullptr;
149     }
150     return static_cast<SQLiteRelationalStore *>(g_store)->GetStorageEngine();
151 }
152 
GetCount(sqlite3 * db,const string & sql,size_t & count)153 int GetCount(sqlite3 *db, const string &sql, size_t &count)
154 {
155     sqlite3_stmt *stmt = nullptr;
156     int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
157     if (errCode != E_OK) {
158         return errCode;
159     }
160     errCode = SQLiteUtils::StepWithRetry(stmt, false);
161     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
162         count = static_cast<size_t>(sqlite3_column_int64(stmt, 0));
163         errCode = E_OK;
164     }
165     SQLiteUtils::ResetStatement(stmt, true, errCode);
166     return errCode;
167 }
168 
ExpectCount(sqlite3 * db,const string & sql,size_t expectCount)169 void ExpectCount(sqlite3 *db, const string &sql, size_t expectCount)
170 {
171     size_t count = 0;
172     ASSERT_EQ(GetCount(db, sql, count), E_OK);
173     EXPECT_EQ(count, expectCount);
174 }
175 
GetOneText(sqlite3 * db,const string & sql)176 std::string GetOneText(sqlite3 *db, const string &sql)
177 {
178     std::string result;
179     sqlite3_stmt *stmt = nullptr;
180     int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
181     if (errCode != E_OK) {
182         return result;
183     }
184     errCode = SQLiteUtils::StepWithRetry(stmt, false);
185     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
186         SQLiteUtils::GetColumnTextValue(stmt, 0, result);
187     }
188     SQLiteUtils::ResetStatement(stmt, true, errCode);
189     return result;
190 }
191 
PutBatchData(uint32_t totalCount,uint32_t valueSize)192 int PutBatchData(uint32_t totalCount, uint32_t valueSize)
193 {
194     sqlite3 *db = nullptr;
195     sqlite3_stmt *stmt = nullptr;
196     const string sql = "INSERT INTO " + g_tableName + " VALUES(?,?);";
197     int errCode = sqlite3_open(g_storePath.c_str(), &db);
198     if (errCode != SQLITE_OK) {
199         goto ERROR;
200     }
201     EXPECT_EQ(sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", nullptr, nullptr, nullptr), SQLITE_OK);
202     errCode = SQLiteUtils::GetStatement(db, sql, stmt);
203     if (errCode != E_OK) {
204         goto ERROR;
205     }
206     for (uint32_t i = 0; i < totalCount; i++) {
207         errCode = SQLiteUtils::BindBlobToStatement(stmt, 2, Value(valueSize, 'a'), false);  // 2 means value index
208         if (errCode != E_OK) {
209             break;
210         }
211         errCode = SQLiteUtils::StepWithRetry(stmt);
212         if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
213             break;
214         }
215         errCode = E_OK;
216         SQLiteUtils::ResetStatement(stmt, false, errCode);
217     }
218 
219 ERROR:
220     if (errCode == E_OK) {
221         EXPECT_EQ(sqlite3_exec(db, "COMMIT TRANSACTION", nullptr, nullptr, nullptr), SQLITE_OK);
222     } else {
223         EXPECT_EQ(sqlite3_exec(db, "ROLLBACK TRANSACTION", nullptr, nullptr, nullptr), SQLITE_OK);
224     }
225     SQLiteUtils::ResetStatement(stmt, true, errCode);
226     errCode = SQLiteUtils::MapSQLiteErrno(errCode);
227     sqlite3_close(db);
228     return errCode;
229 }
230 
ExecSqlAndAssertOK(sqlite3 * db,const std::string & sql)231 void ExecSqlAndAssertOK(sqlite3 *db, const std::string &sql)
232 {
233     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
234 }
235 
ExecSqlAndAssertOK(sqlite3 * db,const initializer_list<std::string> & sqlList)236 void ExecSqlAndAssertOK(sqlite3 *db, const initializer_list<std::string> &sqlList)
237 {
238     for (const auto &sql : sqlList) {
239         ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
240     }
241 }
242 
ExpectMissQueryCnt(const std::vector<SingleVerKvEntry * > & entries,size_t expectCount)243 void ExpectMissQueryCnt(const std::vector<SingleVerKvEntry *> &entries, size_t expectCount)
244 {
245     size_t count = 0;
246     for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
247         if (((*iter)->GetFlag() & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) == 0) {
248             count++;
249         }
250         auto nextOne = std::next(iter, 1);
251         if (nextOne != entries.end()) {
252             EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
253         }
254     }
255     EXPECT_EQ(count, expectCount);
256 }
257 
SetRemoteSchema(const RelationalSyncAbleStorage * store,const std::string & deviceID)258 void SetRemoteSchema(const RelationalSyncAbleStorage *store, const std::string &deviceID)
259 {
260     std::string remoteSchema = store->GetSchemaInfo().ToSchemaString();
261     uint8_t remoteSchemaType = static_cast<uint8_t>(store->GetSchemaInfo().GetSchemaType());
262     const_cast<RelationalSyncAbleStorage *>(store)->SaveRemoteDeviceSchema(deviceID, remoteSchema, remoteSchemaType);
263 }
264 
SetNextBeginTime001()265 void SetNextBeginTime001()
266 {
267     QueryObject query(Query::Select(g_tableName));
268     std::unique_ptr<SQLiteSingleVerRelationalContinueToken> token =
269         std::make_unique<SQLiteSingleVerRelationalContinueToken>(SyncTimeRange {}, query);
270     ASSERT_TRUE(token != nullptr);
271 
272     DataItem dataItem;
273     dataItem.timestamp = INT64_MAX;
274     token->SetNextBeginTime(dataItem);
275 
276     dataItem.flag = DataItem::DELETE_FLAG;
277     token->FinishGetData();
278     EXPECT_EQ(token->IsGetAllDataFinished(), false);
279     token->SetNextBeginTime(dataItem);
280 }
281 
282 class DistributedDBRelationalGetDataTest : public testing::Test {
283 public:
284     static void SetUpTestCase(void);
285     static void TearDownTestCase(void);
286     void SetUp();
287     void TearDown();
288 };
289 
SetUpTestCase(void)290 void DistributedDBRelationalGetDataTest::SetUpTestCase(void)
291 {
292     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
293     g_storePath = g_testDir + "/getDataTest.db";
294     LOGI("The test db is:%s", g_testDir.c_str());
295 
296     auto communicator = new (std::nothrow) VirtualCommunicatorAggregator();
297     ASSERT_TRUE(communicator != nullptr);
298     RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicator);
299 }
300 
TearDownTestCase(void)301 void DistributedDBRelationalGetDataTest::TearDownTestCase(void)
302 {}
303 
SetUp(void)304 void DistributedDBRelationalGetDataTest::SetUp(void)
305 {
306     g_tableName = "data";
307     DistributedDBToolsUnitTest::PrintTestCaseInfo();
308     CreateDBAndTable();
309 }
310 
TearDown(void)311 void DistributedDBRelationalGetDataTest::TearDown(void)
312 {
313     if (g_delegate != nullptr) {
314         EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
315         g_delegate = nullptr;
316     }
317     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
318         LOGE("rm test db files error.");
319     }
320     return;
321 }
322 
323 /**
324  * @tc.name: LogTbl1
325  * @tc.desc: When put sync data to relational store, trigger generate log.
326  * @tc.type: FUNC
327  * @tc.require: AR000GK58G
328  * @tc.author: lidongwei
329  */
330 HWTEST_F(DistributedDBRelationalGetDataTest, LogTbl1, TestSize.Level1)
331 {
332     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
333     ASSERT_NE(g_delegate, nullptr);
334     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
335 
336     /**
337      * @tc.steps: step1. Put data.
338      * @tc.expected: Succeed, return OK.
339      */
340     int insertKey = 1;
341     int insertValue = 1;
342     EXPECT_EQ(AddOrUpdateRecord(insertKey, insertValue), E_OK);
343 
344     /**
345      * @tc.steps: step2. Check log record.
346      * @tc.expected: Record exists.
347      */
348     uint64_t flag = 0;
349     Timestamp timestamp1 = 0;
350     EXPECT_EQ(GetLogData(insertKey, flag, timestamp1), E_OK);
351     EXPECT_EQ(flag, DataItem::LOCAL_FLAG);
352     EXPECT_NE(timestamp1, 0ULL);
353 }
354 
355 /**
356  * @tc.name: GetSyncData1
357  * @tc.desc: GetSyncData interface
358  * @tc.type: FUNC
359  * @tc.require: AR000GK58H
360  * @tc.author: lidongwei
361   */
362 HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData1, TestSize.Level1)
363 {
364     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
365     ASSERT_NE(g_delegate, nullptr);
366     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
367 
368     /**
369      * @tc.steps: step1. Put 500 records.
370      * @tc.expected: Succeed, return OK.
371      */
372     const size_t RECORD_COUNT = 500;
373     for (size_t i = 0; i < RECORD_COUNT; ++i) {
374         EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
375     }
376 
377     /**
378      * @tc.steps: step2. Get all data.
379      * @tc.expected: Succeed and the count is right.
380      */
381     auto store = GetRelationalStore();
382     ASSERT_NE(store, nullptr);
383     ContinueToken token = nullptr;
384     QueryObject query(Query::Select(g_tableName));
385     std::vector<SingleVerKvEntry *> entries;
386     DataSizeSpecInfo sizeInfo {MTU_SIZE, 50};
387 
388     int errCode = store->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries);
389     auto count = entries.size();
390     SingleVerKvEntry::Release(entries);
391     EXPECT_EQ(errCode, -E_UNFINISHED);
392     while (token != nullptr) {
393         errCode = store->GetSyncDataNext(entries, token, sizeInfo);
394         count += entries.size();
395         SingleVerKvEntry::Release(entries);
396         EXPECT_TRUE(errCode == E_OK || errCode == -E_UNFINISHED);
397     }
398     EXPECT_EQ(count, RECORD_COUNT);
399 
400     RelationalDBProperties properties;
401     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
402     auto db = RelationalStoreInstance::GetDataBase(properties, errCode, false);
403     EXPECT_EQ(db, nullptr);
404     RefObject::DecObjRef(g_store);
405 }
406 
407 /**
408  * @tc.name: GetSyncData2
409  * @tc.desc: GetSyncData interface. For overlarge data(over 4M), ignore it.
410  * @tc.type: FUNC
411  * @tc.require: AR000GK58H
412  * @tc.author: lidongwei
413   */
414 HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData2, TestSize.Level1)
415 {
416     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
417     ASSERT_NE(g_delegate, nullptr);
418     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
419 
420     /**
421      * @tc.steps: step1. Put 10 records.(1M + 2M + 3M + 4M + 5M) * 2.
422      * @tc.expected: Succeed, return OK.
423      */
424     for (int i = 1; i <= 5; ++i) {
425         EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK);  // 1024*1024 equals 1M.
426     }
427     for (int i = 1; i <= 5; ++i) {
428         EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK);  // 1024*1024 equals 1M.
429     }
430 
431     /**
432      * @tc.steps: step2. Get all data.
433      * @tc.expected: Succeed and the count is 6.
434      */
435     auto store = GetRelationalStore();
436     ASSERT_NE(store, nullptr);
437     ContinueToken token = nullptr;
438     QueryObject query(Query::Select(g_tableName));
439     std::vector<SingleVerKvEntry *> entries;
440 
441     const size_t EXPECT_COUNT = 6;  // expect 6 records.
442     DataSizeSpecInfo sizeInfo;
443     sizeInfo.blockSize = 100 * 1024 * 1024;  // permit 100M.
444     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries), E_OK);
445     EXPECT_EQ(entries.size(), EXPECT_COUNT);
446     SingleVerKvEntry::Release(entries);
447     RefObject::DecObjRef(g_store);
448 }
449 
450 /**
451  * @tc.name: GetSyncData3
452  * @tc.desc: GetSyncData interface. For deleted data.
453  * @tc.type: FUNC
454  * @tc.require: AR000GK58H
455  * @tc.author: lidongwei
456   */
457 HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData3, TestSize.Level1)
458 {
459     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
460     ASSERT_NE(g_delegate, nullptr);
461     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
462 
463     /**
464      * @tc.steps: step1. Create distributed table "dataPlus".
465      * @tc.expected: Succeed, return OK.
466      */
467     const string tableName = g_tableName + "Plus";
468     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
469     sqlite3 *db = nullptr;
470     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
471     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
472     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
473 
474     /**
475      * @tc.steps: step2. Put 5 records with different type into "dataPlus" table. Put 5 records into "data" table.
476      * @tc.expected: Succeed, return OK.
477      */
478     const size_t RECORD_COUNT = 5;  // 5 records
479     ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
480                             "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
481                             "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
482                             "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
483                             "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');"});
484 
485     /**
486      * @tc.steps: step3. Get all data from "dataPlus" table.
487      * @tc.expected: Succeed and the count is right.
488      */
489     auto store = GetRelationalStore();
490     ASSERT_NE(store, nullptr);
491     ContinueToken token = nullptr;
492     QueryObject query(Query::Select(tableName));
493     std::vector<SingleVerKvEntry *> entries;
494     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
495     EXPECT_EQ(entries.size(), RECORD_COUNT);
496 
497     /**
498      * @tc.steps: step4. Put data into "data" table from deviceA and deviceB
499      * @tc.expected: Succeed, return OK.
500      */
501     QueryObject gQuery(Query::Select(g_tableName));
502     DeviceID deviceA = "deviceA";
503     DeviceID deviceB = "deviceB";
504     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
505         DBCommon::GetDistributedTableName(deviceA, g_tableName)));
506     SetRemoteSchema(store, deviceA);
507     SetRemoteSchema(store, deviceB);
508     auto rEntries = std::vector<SingleVerKvEntry *>(entries.rbegin(), entries.rend());
509     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
510         DBCommon::GetDistributedTableName(deviceB, g_tableName)));
511     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(gQuery, rEntries, deviceB), E_OK);
512     rEntries.clear();
513     SingleVerKvEntry::Release(entries);
514 
515     /**
516      * @tc.steps: step5. Delete 2 "dataPlus" data from deviceA.
517      * @tc.expected: Succeed.
518      */
519     ExecSqlAndAssertOK(db, "DELETE FROM " + tableName + " WHERE rowid<=2;");
520     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
521     EXPECT_EQ(entries.size(), RECORD_COUNT);
522     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(gQuery, entries, deviceA), E_OK);
523     SingleVerKvEntry::Release(entries);
524 
525     /**
526      * @tc.steps: step6. Check data.
527      * @tc.expected: 2 data in the from deviceA are deleted and all data from deviceB are not deleted.
528      */
529     ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName +
530         "_log WHERE flag&0x01=0x01;", 2U);  // 2 deleted log
531     ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
532         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceA)) + ";", 3U);  // 3 records in A
533     ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
534         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceB)) + ";", RECORD_COUNT);  // 5 records in B
535 
536     sqlite3_close(db);
537     RefObject::DecObjRef(g_store);
538 }
539 
540 /**
541  * @tc.name: GetQuerySyncData1
542  * @tc.desc: GetSyncData interface.
543  * @tc.type: FUNC
544  * @tc.require: AR000GK58H
545  * @tc.author: lidongwei
546  */
547 HWTEST_F(DistributedDBRelationalGetDataTest, GetQuerySyncData1, TestSize.Level1)
548 {
549     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
550     ASSERT_NE(g_delegate, nullptr);
551     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
552 
553     /**
554      * @tc.steps: step1. Put 100 records.
555      * @tc.expected: Succeed, return OK.
556      */
557     const size_t RECORD_COUNT = 100; // 100 records.
558     for (size_t i = 0; i < RECORD_COUNT; ++i) {
559         EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
560     }
561 
562     /**
563      * @tc.steps: step2. Get data limit 80, offset 30.
564      * @tc.expected: Get 70 records.
565      */
566     auto store = GetRelationalStore();
567     ASSERT_NE(store, nullptr);
568     ContinueToken token = nullptr;
569     const unsigned int LIMIT = 80; // limit as 80.
570     const unsigned int OFFSET = 30; // offset as 30.
571     const unsigned int EXPECT_COUNT = RECORD_COUNT - OFFSET; // expect 70 records.
572     QueryObject query(Query::Select(g_tableName).Limit(LIMIT, OFFSET));
573     std::vector<SingleVerKvEntry *> entries;
574 
575     int errCode = store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries);
576     EXPECT_EQ(entries.size(), EXPECT_COUNT);
577     EXPECT_EQ(errCode, E_OK);
578     EXPECT_EQ(token, nullptr);
579     SingleVerKvEntry::Release(entries);
580     RefObject::DecObjRef(g_store);
581 }
582 
583 /**
584  * @tc.name: GetQuerySyncData2
585  * @tc.desc: GetSyncData interface.
586  * @tc.type: FUNC
587  * @tc.require: AR000GK58H
588  * @tc.author: lidongwei
589  */
590 HWTEST_F(DistributedDBRelationalGetDataTest, GetQuerySyncData2, TestSize.Level1)
591 {
592     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
593     ASSERT_NE(g_delegate, nullptr);
594     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
595 
596     /**
597      * @tc.steps: step1. Put 100 records.
598      * @tc.expected: Succeed, return OK.
599      */
600     const size_t RECORD_COUNT = 100; // 100 records.
601     for (size_t i = 0; i < RECORD_COUNT; ++i) {
602         EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
603     }
604 
605     /**
606      * @tc.steps: step2. Get record whose key is not equal to 10 and value is not equal to 20, order by key desc.
607      * @tc.expected: Succeed, Get 98 records.
608      */
609     auto store = GetRelationalStore();
610     ASSERT_NE(store, nullptr);
611     ContinueToken token = nullptr;
612 
613     Query query = Query::Select(g_tableName).NotEqualTo("key", 10).And().NotEqualTo("value", 20).OrderBy("key", false);
614     QueryObject queryObj(query);
615     queryObj.SetSchema(store->GetSchemaInfo());
616 
617     std::vector<SingleVerKvEntry *> entries;
618     EXPECT_EQ(store->GetSyncData(queryObj, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
619     EXPECT_EQ(token, nullptr);
620     size_t expectCount = 98;  // expect 98 records.
621     EXPECT_EQ(entries.size(), expectCount);
622     for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
623         auto nextOne = std::next(iter, 1);
624         if (nextOne != entries.end()) {
625             EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
626         }
627     }
628     SingleVerKvEntry::Release(entries);
629 
630     /**
631      * @tc.steps: step3. Get record whose key is equal to 10 or value is equal to 20, order by key asc.
632      * @tc.expected: Succeed, Get 98 records.
633      */
634     query = Query::Select(g_tableName).EqualTo("key", 10).Or().EqualTo("value", 20).OrderBy("key", true);
635     queryObj = QueryObject(query);
636     queryObj.SetSchema(store->GetSchemaInfo());
637 
638     EXPECT_EQ(store->GetSyncData(queryObj, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
639     EXPECT_EQ(token, nullptr);
640     expectCount = 2;  // expect 2 records.
641     EXPECT_EQ(entries.size(), expectCount);
642     for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
643         auto nextOne = std::next(iter, 1);
644         if (nextOne != entries.end()) {
645             EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
646         }
647     }
648     SingleVerKvEntry::Release(entries);
649     RefObject::DecObjRef(g_store);
650 }
651 
652 /**
653  * @tc.name: GetIncorrectTypeData1
654  * @tc.desc: GetSyncData and PutSyncDataWithQuery interface.
655  * @tc.type: FUNC
656  * @tc.require: AR000GK58H
657  * @tc.author: lidongwei
658  */
659 HWTEST_F(DistributedDBRelationalGetDataTest, GetIncorrectTypeData1, TestSize.Level1)
660 {
661     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
662     ASSERT_NE(g_delegate, nullptr);
663     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
664 
665     /**
666      * @tc.steps: step1. Create 2 index for table "data".
667      * @tc.expected: Succeed, return OK.
668      */
669     sqlite3 *db = nullptr;
670     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
671 
672     ExecSqlAndAssertOK(db, {"CREATE INDEX index1 ON " + g_tableName + "(value);",
673                             "CREATE UNIQUE INDEX index2 ON " + g_tableName + "(value,key);"});
674 
675     /**
676      * @tc.steps: step2. Create distributed table "dataPlus".
677      * @tc.expected: Succeed, return OK.
678      */
679     const string tableName = g_tableName + "Plus";
680     string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
681     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
682     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
683 
684     /**
685      * @tc.steps: step3. Put 5 records with different type into "dataPlus" table.
686      * @tc.expected: Succeed, return OK.
687      */
688     const size_t RECORD_COUNT = 5;  // 5 sqls
689     ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
690                             "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
691                             "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
692                             "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
693                             "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');"});
694 
695     /**
696      * @tc.steps: step4. Get all data from "dataPlus" table.
697      * @tc.expected: Succeed and the count is right.
698      */
699     auto store = GetRelationalStore();
700     ASSERT_NE(store, nullptr);
701     ContinueToken token = nullptr;
702     QueryObject query(Query::Select(tableName));
703     std::vector<SingleVerKvEntry *> entries;
704     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
705     EXPECT_EQ(entries.size(), RECORD_COUNT);
706 
707     /**
708      * @tc.steps: step5. Put data into "data" table from deviceA.
709      * @tc.expected: Succeed, return OK.
710      */
711     QueryObject queryPlus(Query::Select(g_tableName));
712     const DeviceID deviceID = "deviceA";
713     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
714         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
715     ASSERT_EQ(E_OK, SQLiteUtils::CloneIndexes(db, g_tableName,
716         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
717 
718     SetRemoteSchema(store, deviceID);
719     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
720     SingleVerKvEntry::Release(entries);
721 
722     /**
723      * @tc.steps: step6. Check data.
724      * @tc.expected: All data in the two tables are same.
725      */
726     ExpectCount(db, "SELECT count(*) FROM " + tableName + " as a, " + DBConstant::RELATIONAL_PREFIX + g_tableName +
727         "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b "
728         "WHERE a.key=b.key AND (a.value=b.value OR (a.value is NULL AND b.value is NULL));", RECORD_COUNT);
729 
730     /**
731      * @tc.steps: step7. Check index.
732      * @tc.expected: 2 index for deviceA's data table exists.
733      */
734     ExpectCount(db,
735         "SELECT count(*) FROM sqlite_master WHERE type='index' AND tbl_name='" + DBConstant::RELATIONAL_PREFIX +
736         g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "'", 2U); // 2 index
737     sqlite3_close(db);
738     RefObject::DecObjRef(g_store);
739 }
740 
741 /**
742  * @tc.name: UpdateData1
743  * @tc.desc: UpdateData succeed when the table has primary key.
744  * @tc.type: FUNC
745  * @tc.require: AR000GK58H
746  * @tc.author: lidongwei
747  */
748 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateData1, TestSize.Level1)
749 {
750     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
751     ASSERT_NE(g_delegate, nullptr);
752     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
753 
754     /**
755      * @tc.steps: step1. Create distributed table "dataPlus".
756      * @tc.expected: Succeed, return OK.
757      */
758     const string tableName = g_tableName + "Plus";
759     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
760     sqlite3 *db = nullptr;
761     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
762     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
763     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
764 
765     /**
766      * @tc.steps: step2. Put 5 records with different type into "dataPlus" table.
767      * @tc.expected: Succeed, return OK.
768      */
769     vector<string> sqls = {
770         "INSERT INTO " + tableName + " VALUES(NULL, 1);",
771         "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
772         "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
773         "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
774         "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');",
775     };
776     const size_t RECORD_COUNT = sqls.size();
777     for (const auto &item : sqls) {
778         ASSERT_EQ(sqlite3_exec(db, item.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
779     }
780 
781     /**
782      * @tc.steps: step3. Get all data from "dataPlus" table.
783      * @tc.expected: Succeed and the count is right.
784      */
785     auto store = GetRelationalStore();
786     ASSERT_NE(store, nullptr);
787     ContinueToken token = nullptr;
788     QueryObject query(Query::Select(tableName));
789     std::vector<SingleVerKvEntry *> entries;
790     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
791     EXPECT_EQ(entries.size(), RECORD_COUNT);
792 
793     /**
794      * @tc.steps: step4. Put data into "data" table from deviceA for 10 times.
795      * @tc.expected: Succeed, return OK.
796      */
797     query = QueryObject(Query::Select(g_tableName));
798     const DeviceID deviceID = "deviceA";
799     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
800         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
801 
802     SetRemoteSchema(store, deviceID);
803     for (uint32_t i = 0; i < 10; ++i) {  // 10 for test.
804         EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
805     }
806     SingleVerKvEntry::Release(entries);
807 
808     /**
809      * @tc.steps: step5. Check data.
810      * @tc.expected: There is 5 data in table.
811      */
812     sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
813         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
814     size_t count = 0;
815     EXPECT_EQ(GetCount(db, sql, count), E_OK);
816     EXPECT_EQ(count, RECORD_COUNT);
817 
818     sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;";
819     count = 0;
820     EXPECT_EQ(GetCount(db, sql, count), E_OK);
821     EXPECT_EQ(count, RECORD_COUNT);
822 
823     sqlite3_close(db);
824     RefObject::DecObjRef(g_store);
825 }
826 
827 /**
828  * @tc.name: UpdateDataWithMulDevData1
829  * @tc.desc: UpdateData succeed when there is multiple devices data exists.
830  * @tc.type: FUNC
831  * @tc.require: AR000GK58H
832  * @tc.author: lidongwei
833  */
834 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateDataWithMulDevData1, TestSize.Level1)
835 {
836     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
837     ASSERT_NE(g_delegate, nullptr);
838     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
839     /**
840      * @tc.steps: step1. Create distributed table "dataPlus".
841      * @tc.expected: Succeed, return OK.
842      */
843     const string tableName = g_tableName + "Plus";
844     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
845     sqlite3 *db = nullptr;
846     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
847     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
848     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
849     /**
850      * @tc.steps: step2. Put k1v1 into "dataPlus" table.
851      * @tc.expected: Succeed, return OK.
852      */
853     sql = "INSERT INTO " + tableName + " VALUES(1, 1);"; // k1v1
854     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
855     /**
856      * @tc.steps: step3. Get k1v1 from "dataPlus" table.
857      * @tc.expected: Succeed and the count is right.
858      */
859     auto store = GetRelationalStore();
860     ASSERT_NE(store, nullptr);
861     ContinueToken token = nullptr;
862     QueryObject query(Query::Select(tableName));
863     std::vector<SingleVerKvEntry *> entries;
864     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
865     /**
866      * @tc.steps: step4. Put k1v1 into "data" table from deviceA.
867      * @tc.expected: Succeed, return OK.
868      */
869     query = QueryObject(Query::Select(g_tableName));
870     const DeviceID deviceID = "deviceA";
871     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
872         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
873 
874     SetRemoteSchema(store, deviceID);
875     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
876     SingleVerKvEntry::Release(entries);
877     /**
878      * @tc.steps: step4. Put k1v1 into "data" table.
879      * @tc.expected: Succeed, return OK.
880      */
881     EXPECT_EQ(AddOrUpdateRecord(1, 1), E_OK); // k1v1
882     /**
883      * @tc.steps: step5. Change k1v1 to k1v2
884      * @tc.expected: Succeed, return OK.
885      */
886     sql = "UPDATE " + g_tableName + " SET value=2 WHERE key=1;"; // k1v1
887     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); // change k1v1 to k1v2
888 
889     sqlite3_close(db);
890     RefObject::DecObjRef(g_store);
891 }
892 
893 /**
894  * @tc.name: MissQuery1
895  * @tc.desc: Check REMOTE_DEVICE_DATA_MISS_QUERY flag succeed.
896  * @tc.type: FUNC
897  * @tc.require: AR000GK58H
898  * @tc.author: lidongwei
899  */
900 HWTEST_F(DistributedDBRelationalGetDataTest, MissQuery1, TestSize.Level1)
901 {
902     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
903     ASSERT_NE(g_delegate, nullptr);
904     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
905     /**
906      * @tc.steps: step1. Create distributed table "dataPlus".
907      * @tc.expected: Succeed, return OK.
908      */
909     const string tableName = g_tableName + "Plus";
910     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
911     sqlite3 *db = nullptr;
912     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
913     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
914     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
915 
916     /**
917      * @tc.steps: step2. Put 5 records with different type into "dataPlus" table.
918      * @tc.expected: Succeed, return OK.
919      */
920     ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
921         "INSERT INTO " + tableName + " VALUES(NULL, 2);", "INSERT INTO " + tableName + " VALUES(NULL, 3);",
922         "INSERT INTO " + tableName + " VALUES(NULL, 4);", "INSERT INTO " + tableName + " VALUES(NULL, 5);"});
923 
924     /**
925      * @tc.steps: step3. Get all data from "dataPlus" table.
926      * @tc.expected: Succeed and the count is right.
927      */
928     auto store = GetRelationalStore();
929     ASSERT_NE(store, nullptr);
930     ContinueToken token = nullptr;
931     SyncTimeRange timeRange;
932     QueryObject query(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4));
933     std::vector<SingleVerKvEntry *> entries;
934     EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK);
935     timeRange.lastQueryTime = (*(entries.rbegin()))->GetTimestamp();
936     EXPECT_EQ(entries.size(), 3U);  // 3 for test
937 
938     /**
939      * @tc.steps: step4. Put data into "data" table from deviceA for 10 times.
940      * @tc.expected: Succeed, return OK.
941      */
942     query = QueryObject(Query::Select(g_tableName));
943     const DeviceID deviceID = "deviceA";
944     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
945         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
946 
947     SetRemoteSchema(store, deviceID);
948     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
949     SingleVerKvEntry::Release(entries);
950 
951     /**
952      * @tc.steps: step5. Check data.
953      * @tc.expected: There is 3 data in table.
954      */
955     std::string getDataSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
956         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
957     ExpectCount(db, getDataSql, 3);  // 2,3,4
958 
959     std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;";
960     ExpectCount(db, getLogSql, 3);  // 2,3,4
961 
962     /**
963      * @tc.steps: step6. Update data. k2v2 to k2v102, k3v3 to k3v103, k4v4 to k4v104.
964      * @tc.expected: Update succeed.
965      */
966     ExecSqlAndAssertOK(db, {"INSERT OR REPLACE INTO " + tableName + " VALUES(2, 102);",
967                             "UPDATE " + tableName + " SET value=103 WHERE value=3;",
968                             "DELETE FROM " + tableName + " WHERE key=4;",
969                             "INSERT INTO " + tableName + " VALUES(4, 104);"});
970 
971     /**
972      * @tc.steps: step7. Get all data from "dataPlus" table.
973      * @tc.expected: Succeed and the count is right.
974      */
975     query = QueryObject(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4));
976     EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK);
977     EXPECT_EQ(entries.size(), 3U);  // 3 miss query data.
978 
979     /**
980      * @tc.steps: step8. Put data into "data" table from deviceA for 10 times.
981      * @tc.expected: Succeed, return OK.
982      */
983     SetRemoteSchema(store, deviceID);
984     query = QueryObject(Query::Select(g_tableName));
985     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
986     SingleVerKvEntry::Release(entries);
987 
988     /**
989      * @tc.steps: step9. Check data.
990      * @tc.expected: There is 0 data in table.
991      */
992     ExpectCount(db, getDataSql, 0U);  // 0 data exists
993     ExpectCount(db, getLogSql, 0U);  // 0 data exists
994 
995     sqlite3_close(db);
996     RefObject::DecObjRef(g_store);
997 }
998 
999 /**
1000  * @tc.name: CompatibleData1
1001  * @tc.desc: Check compatibility.
1002  * @tc.type: FUNC
1003  * @tc.require: AR000GK58H
1004  * @tc.author: lidongwei
1005  */
1006 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData1, TestSize.Level1)
1007 {
1008     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1009     ASSERT_NE(g_delegate, nullptr);
1010     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1011     /**
1012      * @tc.steps: step1. Create distributed table "dataPlus".
1013      * @tc.expected: Succeed, return OK.
1014      */
1015     const string tableName = g_tableName + "Plus";
1016     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1017         extra_field TEXT NOT NULL DEFAULT 'default_value');";
1018     sqlite3 *db = nullptr;
1019     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1020     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1021     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1022     /**
1023      * @tc.steps: step2. Put 1 record into data and dataPlus table.
1024      * @tc.expected: Succeed, return OK.
1025      */
1026     ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1027     sql = "INSERT INTO " + tableName + " VALUES(2, 102, 'f3');"; // k2v102
1028     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1029     /**
1030      * @tc.steps: step3. Get all data from "data" table.
1031      * @tc.expected: Succeed and the count is right.
1032      */
1033     auto store = GetRelationalStore();
1034     ASSERT_NE(store, nullptr);
1035     ContinueToken token = nullptr;
1036     QueryObject query(Query::Select(g_tableName));
1037     std::vector<SingleVerKvEntry *> entries;
1038     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1039     EXPECT_EQ(entries.size(), 1UL);
1040     /**
1041      * @tc.steps: step4. Put data into "data_plus" table from deviceA.
1042      * @tc.expected: Succeed, return OK.
1043      */
1044     QueryObject queryPlus(Query::Select(tableName));
1045     const DeviceID deviceID = "deviceA";
1046     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName),
1047         DBCommon::GetDistributedTableName(deviceID, tableName)));
1048 
1049     SetRemoteSchema(store, deviceID);
1050     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1051     SingleVerKvEntry::Release(entries);
1052     /**
1053      * @tc.steps: step4. Get all data from "dataPlus" table.
1054      * @tc.expected: Succeed and the count is right.
1055      */
1056     EXPECT_EQ(store->GetSyncData(queryPlus, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1057     EXPECT_EQ(entries.size(), 1UL);
1058     /**
1059      * @tc.steps: step5. Put data into "data" table from deviceA.
1060      * @tc.expected: Succeed, return OK.
1061      */
1062     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
1063         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
1064     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
1065     SingleVerKvEntry::Release(entries);
1066     /**
1067      * @tc.steps: step6. Check data.
1068      * @tc.expected: All data in the two tables are same.
1069      */
1070     sql = "SELECT count(*) FROM " + g_tableName + " as a," + DBConstant::RELATIONAL_PREFIX + tableName + "_" +
1071         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " +
1072         "WHERE a.key=b.key AND a.value=b.value;";
1073     size_t count = 0;
1074     EXPECT_EQ(GetCount(db, sql, count), E_OK);
1075     EXPECT_EQ(count, 1UL);
1076     sql = "SELECT count(*) FROM " + tableName + " as a," + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
1077         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " +
1078         "WHERE a.key=b.key AND a.value=b.value;";
1079     count = 0;
1080     EXPECT_EQ(GetCount(db, sql, count), E_OK);
1081     EXPECT_EQ(count, 1UL);
1082     sqlite3_close(db);
1083     RefObject::DecObjRef(g_store);
1084 }
1085 
1086 /**
1087  * @tc.name: GetDataSortByTime1
1088  * @tc.desc: All query get data sort by time asc.
1089  * @tc.type: FUNC
1090  * @tc.require: AR000GK58H
1091  * @tc.author: lidongwei
1092  */
1093 HWTEST_F(DistributedDBRelationalGetDataTest, GetDataSortByTime1, TestSize.Level1)
1094 {
1095     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1096     ASSERT_NE(g_delegate, nullptr);
1097     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1098     /**
1099      * @tc.steps: step2. Add 3 record into data. k1v105, k2v104, k3v103, timestamp desc.
1100      * @tc.expected: Succeed, return OK.
1101      */
1102     sqlite3 *db = nullptr;
1103     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1104     std::string sql = "INSERT INTO " + g_tableName + " VALUES(1, 101);"; // k1v101
1105     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1106     sql = "INSERT INTO " + g_tableName + " VALUES(2, 102);"; // k2v102
1107     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1108     sql = "INSERT INTO " + g_tableName + " VALUES(3, 103);"; // k3v103
1109     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1110     sql = "UPDATE " + g_tableName + " SET value=104 WHERE key=2;"; // k2v104
1111     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1112     sql = "UPDATE " + g_tableName + " SET value=105 WHERE key=1;"; // k1v105
1113     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1114     /**
1115      * @tc.steps: step3. Get all data from "data" table by all query.
1116      * @tc.expected: Succeed and the count is right.
1117      */
1118     auto store = GetRelationalStore();
1119     ASSERT_NE(store, nullptr);
1120     ContinueToken token = nullptr;
1121     QueryObject query(Query::Select(g_tableName));
1122     std::vector<SingleVerKvEntry *> entries;
1123     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1124     ExpectMissQueryCnt(entries, 3UL);  // 3 data
1125     SingleVerKvEntry::Release(entries);
1126 
1127     query = QueryObject(Query::Select(g_tableName).EqualTo("key", 1).Or().EqualTo("key", 3));
1128     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1129     ExpectMissQueryCnt(entries, 2UL);  // 2 data
1130     SingleVerKvEntry::Release(entries);
1131 
1132     query = QueryObject(Query::Select(g_tableName).OrderBy("key", false));
1133     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1134     ExpectMissQueryCnt(entries, 3UL);  // 3 data
1135     SingleVerKvEntry::Release(entries);
1136 
1137     query = QueryObject(Query::Select(g_tableName).OrderBy("value", false));
1138     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1139     ExpectMissQueryCnt(entries, 3UL);  // 3 data
1140     SingleVerKvEntry::Release(entries);
1141 
1142     query = QueryObject(Query::Select(g_tableName).Limit(2));
1143     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1144     ExpectMissQueryCnt(entries, 2UL);  // 2 data
1145     SingleVerKvEntry::Release(entries);
1146 
1147     sqlite3_close(db);
1148     RefObject::DecObjRef(g_store);
1149 }
1150 
1151 /**
1152  * @tc.name: SameFieldWithLogTable1
1153  * @tc.desc: Get query data OK when the table has same field with log table.
1154  * @tc.type: FUNC
1155  * @tc.require: AR000GK58H
1156  * @tc.author: lidongwei
1157  */
1158 HWTEST_F(DistributedDBRelationalGetDataTest, SameFieldWithLogTable1, TestSize.Level1)
1159 {
1160     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1161     ASSERT_NE(g_delegate, nullptr);
1162     /**
1163      * @tc.steps: step1. Create distributed table "dataPlus".
1164      * @tc.expected: Succeed, return OK.
1165      */
1166     const string tableName = g_tableName + "Plus";
1167     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, flag INTEGER NOT NULL, \
1168         device TEXT NOT NULL DEFAULT 'default_value');";
1169     sqlite3 *db = nullptr;
1170     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1171     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1172     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1173     /**
1174      * @tc.steps: step2. Put 1 record into dataPlus table.
1175      * @tc.expected: Succeed, return OK.
1176      */
1177     sql = "INSERT INTO " + tableName + " VALUES(1, 101, 'f3');"; // k1v101
1178     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1179     /**
1180      * @tc.steps: step3. Get all data from dataPlus table.
1181      * @tc.expected: Succeed and the count is right.
1182      */
1183     auto store = GetRelationalStore();
1184     ASSERT_NE(store, nullptr);
1185     ContinueToken token = nullptr;
1186     QueryObject query(Query::Select(tableName).EqualTo("flag", 101).OrderBy("device", false));
1187     std::vector<SingleVerKvEntry *> entries;
1188     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1189     EXPECT_EQ(entries.size(), 1UL);
1190     SingleVerKvEntry::Release(entries);
1191     sqlite3_close(db);
1192     RefObject::DecObjRef(g_store);
1193 }
1194 
1195 /**
1196  * @tc.name: CompatibleData2
1197  * @tc.desc: Check compatibility.
1198  * @tc.type: FUNC
1199  * @tc.require: AR000GK58H
1200  * @tc.author: lidongwei
1201  */
1202 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData2, TestSize.Level1)
1203 {
1204     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1205     ASSERT_NE(g_delegate, nullptr);
1206     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1207 
1208     sqlite3 *db = nullptr;
1209     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1210 
1211     auto store = GetRelationalStore();
1212     ASSERT_NE(store, nullptr);
1213 
1214     /**
1215      * @tc.steps: step1. Create distributed table from deviceA.
1216      * @tc.expected: Succeed, return OK.
1217      */
1218     const DeviceID deviceID = "deviceA";
1219     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
1220         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
1221 
1222     /**
1223      * @tc.steps: step2. Alter "data" table and create distributed table again.
1224      * @tc.expected: Succeed.
1225      */
1226     std::string sql = "ALTER TABLE " + g_tableName + " ADD COLUMN integer_type INTEGER DEFAULT 123 not null;"
1227         "ALTER TABLE " + g_tableName + " ADD COLUMN text_type TEXT DEFAULT 'high_version' not null;"
1228         "ALTER TABLE " + g_tableName + " ADD COLUMN real_type REAL DEFAULT 123.123456 not null;"
1229         "ALTER TABLE " + g_tableName + " ADD COLUMN blob_type BLOB DEFAULT 123 not null;";
1230     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1231     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1232 
1233     /**
1234      * @tc.steps: step3. Check deviceA's distributed table.
1235      * @tc.expected: The create sql is correct.
1236      */
1237     std::string expectSql = "CREATE TABLE 'naturalbase_rdb_aux_data_"
1238         "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f' ('key' 'integer' NOT NULL,'value' 'integer',"
1239         " 'integer_type' 'integer' NOT NULL DEFAULT 123, 'text_type' 'text' NOT NULL DEFAULT 'high_version', "
1240         "'real_type' 'real' NOT NULL DEFAULT 123.123456, 'blob_type' 'blob' NOT NULL DEFAULT 123, PRIMARY KEY ('key'))";
1241     sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
1242         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';";
1243     EXPECT_EQ(GetOneText(db, sql), expectSql);
1244 
1245     sqlite3_close(db);
1246     RefObject::DecObjRef(g_store);
1247 }
1248 
1249 /**
1250  * @tc.name: PutSyncDataConflictDataTest001
1251  * @tc.desc: Check put with conflict sync data.
1252  * @tc.type: FUNC
1253  * @tc.require: AR000GK58H
1254  * @tc.author: lianhuix
1255  */
1256 HWTEST_F(DistributedDBRelationalGetDataTest, PutSyncDataConflictDataTest001, TestSize.Level1)
1257 {
1258     const DeviceID deviceID_A = "deviceA";
1259     const DeviceID deviceID_B = "deviceB";
1260     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath);
1261     RelationalTestUtils::CreateDeviceTable(db, g_tableName, deviceID_B);
1262 
1263     DBStatus status = g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate);
1264     EXPECT_EQ(status, DBStatus::OK);
1265     ASSERT_NE(g_delegate, nullptr);
1266     EXPECT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1267 
1268     auto store = const_cast<RelationalSyncAbleStorage *>(GetRelationalStore());
1269     ASSERT_NE(store, nullptr);
1270 
1271     RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1001,'VAL_1');");
1272     RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1002,'VAL_2');");
1273     RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1003,'VAL_3');");
1274 
1275     DataSizeSpecInfo sizeInfo {MTU_SIZE, 50};
1276     ContinueToken token = nullptr;
1277     QueryObject query(Query::Select(g_tableName));
1278     std::vector<SingleVerKvEntry *> entries;
1279     int errCode = store->GetSyncData(query, {}, sizeInfo, token, entries);
1280     EXPECT_EQ(errCode, E_OK);
1281 
1282     SetRemoteSchema(store, deviceID_B);
1283     errCode = store->PutSyncDataWithQuery(query, entries, deviceID_B);
1284     EXPECT_EQ(errCode, E_OK);
1285     GenericSingleVerKvEntry::Release(entries);
1286 
1287     QueryObject query2(Query::Select(g_tableName).EqualTo("key", 1001));
1288     std::vector<SingleVerKvEntry *> entries2;
1289     store->GetSyncData(query2, {}, sizeInfo, token, entries2);
1290 
1291     errCode = store->PutSyncDataWithQuery(query, entries2, deviceID_B);
1292     EXPECT_EQ(errCode, E_OK);
1293     GenericSingleVerKvEntry::Release(entries2);
1294 
1295     RefObject::DecObjRef(g_store);
1296 
1297     std::string deviceTable = DBCommon::GetDistributedTableName(deviceID_B, g_tableName);
1298     EXPECT_EQ(RelationalTestUtils::CheckTableRecords(db, deviceTable), 3);
1299     sqlite3_close_v2(db);
1300 }
1301 
1302 /**
1303  * @tc.name: SaveNonexistDevdata1
1304  * @tc.desc: Save non-exist device data and check errCode.
1305  * @tc.type: FUNC
1306  * @tc.require: AR000GK58H
1307  * @tc.author: lidongwei
1308  */
1309 HWTEST_F(DistributedDBRelationalGetDataTest, SaveNonexistDevdata1, TestSize.Level1)
1310 {
1311     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1312     ASSERT_NE(g_delegate, nullptr);
1313     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1314     /**
1315      * @tc.steps: step1. Create distributed table "dataPlus".
1316      * @tc.expected: Succeed, return OK.
1317      */
1318     const string tableName = g_tableName + "Plus";
1319     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1320         extra_field TEXT NOT NULL DEFAULT 'default_value');";
1321     sqlite3 *db = nullptr;
1322     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1323     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1324     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1325     /**
1326      * @tc.steps: step2. Put 1 record into data table.
1327      * @tc.expected: Succeed, return OK.
1328      */
1329     ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1330 
1331     /**
1332      * @tc.steps: step3. Get all data from "data" table.
1333      * @tc.expected: Succeed and the count is right.
1334      */
1335     auto store = GetRelationalStore();
1336     ASSERT_NE(store, nullptr);
1337     ContinueToken token = nullptr;
1338     QueryObject query(Query::Select(g_tableName));
1339     std::vector<SingleVerKvEntry *> entries;
1340     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1341     EXPECT_EQ(entries.size(), 1UL);
1342 
1343     /**
1344      * @tc.steps: step4. Put data into "data_plus" table from deviceA and deviceA does not exist.
1345      * @tc.expected: Succeed, return OK.
1346      */
1347     query = QueryObject(Query::Select(tableName));
1348     const DeviceID deviceID = "deviceA";
1349     SetRemoteSchema(store, deviceID);
1350     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID),
1351         -1);  // -1 means error
1352     SingleVerKvEntry::Release(entries);
1353 
1354     sqlite3_close(db);
1355     RefObject::DecObjRef(g_store);
1356 }
1357 
1358 /**
1359  * @tc.name: GetMaxTimestamp1
1360  * @tc.desc: Get max timestamp.
1361  * @tc.type: FUNC
1362  * @tc.require: AR000GK58H
1363  * @tc.author: lidongwei
1364  */
1365 HWTEST_F(DistributedDBRelationalGetDataTest, GetMaxTimestamp1, TestSize.Level1)
1366 {
1367     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1368     ASSERT_NE(g_delegate, nullptr);
1369     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1370     /**
1371      * @tc.steps: step1. Create distributed table "dataPlus".
1372      * @tc.expected: Succeed, return OK.
1373      */
1374     sqlite3 *db = nullptr;
1375     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1376     const string tableName = g_tableName + "Plus";
1377     ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1378         extra_field TEXT NOT NULL DEFAULT 'default_value');");
1379     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1380 
1381     /**
1382      * @tc.steps: step2. Get max timestamp when no data exists.
1383      * @tc.expected: Succeed and the time is 0;
1384      */
1385     auto store = GetRelationalStore();
1386     ASSERT_NE(store, nullptr);
1387 
1388     Timestamp time1 = 0;
1389     store->GetMaxTimestamp(time1);
1390     EXPECT_EQ(time1, 0uLL);
1391 
1392     /**
1393      * @tc.steps: step3. Put 1 record into data table and get max timestamp.
1394      * @tc.expected: Succeed and the time is updated.
1395      */
1396     ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1397     Timestamp time2 = 0;
1398     store->GetMaxTimestamp(time2);
1399     EXPECT_GT(time2, time1);
1400 
1401     /**
1402      * @tc.steps: step4. Put 1 record into data table and get max timestamp.
1403      * @tc.expected: Succeed and the time is updated.
1404      */
1405     ASSERT_EQ(AddOrUpdateRecord(2, 102), E_OK);
1406     Timestamp time3 = 0;
1407     store->GetMaxTimestamp(time3);
1408     EXPECT_GT(time3, time2);
1409 
1410     /**
1411      * @tc.steps: step5. Put 1 record into data table and get the max timestamp of data table.
1412      * @tc.expected: Succeed and the time is equals to max timestamp in DB.
1413      */
1414     Timestamp time4 = 0;
1415     store->GetMaxTimestamp(g_tableName, time4);
1416     EXPECT_EQ(time4, time3);
1417 
1418     /**
1419      * @tc.steps: step6. Put 1 record into data table and get the max timestamp of dataPlus table.
1420      * @tc.expected: Succeed and the time is 0.
1421      */
1422     Timestamp time5 = 0;
1423     store->GetMaxTimestamp(tableName, time5);
1424     EXPECT_EQ(time5, 0uLL);
1425 
1426     sqlite3_close(db);
1427     RefObject::DecObjRef(g_store);
1428 }
1429 
1430 /**
1431  * @tc.name: NoPkData1
1432  * @tc.desc: For no pk data.
1433  * @tc.type: FUNC
1434  * @tc.require: AR000GK58H
1435  * @tc.author: lidongwei
1436  */
1437 HWTEST_F(DistributedDBRelationalGetDataTest, NoPkData1, TestSize.Level1)
1438 {
1439     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1440     ASSERT_NE(g_delegate, nullptr);
1441 
1442     sqlite3 *db = nullptr;
1443     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1444     ExecSqlAndAssertOK(db, "DROP TABLE IF EXISTS " + g_tableName + "; \
1445         CREATE TABLE " + g_tableName + "(key INTEGER NOT NULL, value INTEGER);");
1446     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1447 
1448     /**
1449      * @tc.steps: step1. Create distributed table "dataPlus".
1450      * @tc.expected: Succeed, return OK.
1451      */
1452     const string tableName = g_tableName + "Plus";
1453     ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER NOT NULL, value INTEGER);");
1454     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1455 
1456     /**
1457      * @tc.steps: step2. Put 2 data into "data" table.
1458      * @tc.expected: Succeed.
1459      */
1460     ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK);
1461     ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK);
1462 
1463     /**
1464      * @tc.steps: step3. Get data from "data" table.
1465      * @tc.expected: Succeed.
1466      */
1467     auto store = GetRelationalStore();
1468     ASSERT_NE(store, nullptr);
1469 
1470     ContinueToken token = nullptr;
1471     QueryObject query(Query::Select(g_tableName));
1472     std::vector<SingleVerKvEntry *> entries;
1473     EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK);
1474     EXPECT_EQ(entries.size(), 2U);  // expect 2 data.
1475 
1476     /**
1477      * @tc.steps: step4. Put data into "data" table from deviceA.
1478      * @tc.expected: Succeed, return OK.
1479      */
1480     QueryObject queryPlus(Query::Select(tableName));
1481     const DeviceID deviceID = "deviceA";
1482     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName),
1483         DBCommon::GetDistributedTableName(deviceID, tableName)));
1484     SetRemoteSchema(store, deviceID);
1485     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1486     SingleVerKvEntry::Release(entries);
1487 
1488     /**
1489      * @tc.steps: step5. Changet data in "data" table.
1490      * @tc.expected: Succeed.
1491      */
1492     ExecSqlAndAssertOK(db, {"UPDATE " + g_tableName + " SET value=101 WHERE key=1;",
1493                             "DELETE FROM " + g_tableName + " WHERE key=2;",
1494                             "INSERT INTO " + g_tableName + " VALUES(2, 102);"});
1495 
1496     /**
1497      * @tc.steps: step6. Get data from "data" table.
1498      * @tc.expected: Succeed.
1499      */
1500     EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK);
1501     EXPECT_EQ(entries.size(), 2U);  // expect 2 data.
1502 
1503     /**
1504      * @tc.steps: step7. Put data into "data" table from deviceA.
1505      * @tc.expected: Succeed, return OK.
1506      */
1507     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1508     SingleVerKvEntry::Release(entries);
1509 
1510     /**
1511      * @tc.steps: step8. Check data.
1512      * @tc.expected: There is 2 data.
1513      */
1514     std::string sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_" +
1515         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
1516     size_t count = 0;
1517     EXPECT_EQ(GetCount(db, sql, count), E_OK);
1518     EXPECT_EQ(count, 2U); // expect 2 data.
1519 
1520     sqlite3_close(db);
1521     RefObject::DecObjRef(g_store);
1522 }
1523 
1524 /**
1525  * @tc.name: GetAfterDropTable1
1526  * @tc.desc: Get data after drop table.
1527  * @tc.type: FUNC
1528  * @tc.require: AR000H2QPN
1529  * @tc.author: lidongwei
1530  */
1531 HWTEST_F(DistributedDBRelationalGetDataTest, GetAfterDropTable1, TestSize.Level1)
1532 {
1533     /**
1534      * @tc.steps: step1. Create distributed table.
1535      * @tc.expected: Succeed, return OK.
1536      */
1537     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1538     ASSERT_NE(g_delegate, nullptr);
1539     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1540 
1541     /**
1542      * @tc.steps: step2. Insert several data.
1543      * @tc.expected: Succeed, return OK.
1544      */
1545     ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK);
1546     ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK);
1547     ASSERT_EQ(AddOrUpdateRecord(3, 3), E_OK);
1548 
1549     /**
1550      * @tc.steps: step3. Check data in distributed log table.
1551      * @tc.expected: The data in log table is in expect. All the flag in log table is 1.
1552      */
1553     sqlite3 *db = nullptr;
1554     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1555 
1556     std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log "
1557                             "WHERE flag&0x01<>0;";
1558     ExpectCount(db, getLogSql, 0u);  // 0 means no deleted data.
1559 
1560     /**
1561      * @tc.steps: step4. Drop the table in another connection.
1562      * @tc.expected: Succeed.
1563      */
__anona733078b0202null1564     std::thread t1([] {
1565         sqlite3 *db = nullptr;
1566         ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1567         ExecSqlAndAssertOK(db, "DROP TABLE " + g_tableName);
1568         sqlite3_close(db);
1569     });
1570     t1.join();
1571     std::this_thread::sleep_for(std::chrono::seconds(1));
1572     /**
1573      * @tc.steps: step5. Check data in distributed log table.
1574      * @tc.expected: The data in log table is in expect. All the flag in log table is 3.
1575      */
1576     ExpectCount(db, getLogSql, 3u);  // 3 means all deleted data.
1577     sqlite3_close(db);
1578 }
1579 
1580 /**
1581   * @tc.name: SetSchema1
1582   * @tc.desc: Test invalid parameters of query_object.cpp
1583   * @tc.type: FUNC
1584   * @tc.require:
1585   * @tc.author: bty
1586   */
1587 HWTEST_F(DistributedDBRelationalGetDataTest, SetSchema1, TestSize.Level1)
1588 {
1589     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1590     ASSERT_NE(g_delegate, nullptr);
1591     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1592     auto store = GetRelationalStore();
1593     ASSERT_NE(store, nullptr);
1594     Query query = Query::Select().OrderBy("errDevice", false);
1595     QueryObject queryObj1(query);
1596     int errorNo = E_OK;
1597     errorNo = queryObj1.SetSchema(store->GetSchemaInfo());
1598     EXPECT_EQ(errorNo, -E_INVALID_ARGS);
1599     EXPECT_FALSE(queryObj1.IsQueryForRelationalDB());
1600     errorNo = queryObj1.Init();
1601     EXPECT_EQ(errorNo, -E_NOT_SUPPORT);
1602     QueryObject queryObj2(query);
1603     queryObj2.SetTableName(g_tableName);
1604     errorNo = queryObj2.SetSchema(store->GetSchemaInfo());
1605     EXPECT_EQ(errorNo, E_OK);
1606     errorNo = queryObj2.Init();
1607     EXPECT_EQ(errorNo, -E_INVALID_QUERY_FIELD);
1608     RefObject::DecObjRef(g_store);
1609 }
1610 
1611 /**
1612   * @tc.name: SetNextBeginTime001
1613   * @tc.desc: Test invalid parameters of query_object.cpp
1614   * @tc.type: FUNC
1615   * @tc.require:
1616   * @tc.author: bty
1617   */
1618 HWTEST_F(DistributedDBRelationalGetDataTest, SetNextBeginTime001, TestSize.Level1)
1619 {
1620     ASSERT_NO_FATAL_FAILURE(SetNextBeginTime001());
1621 }
1622 
1623 /**
1624  * @tc.name: CloseStore001
1625  * @tc.desc: Test Relational Store Close Action.
1626  * @tc.type: FUNC
1627  * @tc.require: AR000H2QPN
1628  * @tc.author: zhangqiquan
1629  */
1630 HWTEST_F(DistributedDBRelationalGetDataTest, CloseStore001, TestSize.Level1)
1631 {
1632     /**
1633      * @tc.steps: step1. new store and get connection now ref count is 2.
1634      * @tc.expected: Succeed.
1635      */
1636     auto store = new (std::nothrow) SQLiteRelationalStore();
1637     ASSERT_NE(store, nullptr);
1638     RelationalDBProperties properties;
1639     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1640     EXPECT_EQ(store->Open(properties), E_OK);
1641     int errCode = E_OK;
1642     auto connection = store->GetDBConnection(errCode);
1643     EXPECT_EQ(errCode, E_OK);
1644     ASSERT_NE(connection, nullptr);
__anona733078b0302(const std::string &, const std::string &) 1645     errCode = store->RegisterLifeCycleCallback([](const std::string &, const std::string &) {
1646     });
1647     EXPECT_EQ(errCode, E_OK);
1648     errCode = store->RegisterLifeCycleCallback(nullptr);
1649     EXPECT_EQ(errCode, E_OK);
1650     auto syncInterface = store->GetStorageEngine();
1651     ASSERT_NE(syncInterface, nullptr);
1652     RefObject::IncObjRef(syncInterface);
1653     /**
1654      * @tc.steps: step2. release store.
1655      * @tc.expected: Succeed.
1656      */
1657     store->ReleaseDBConnection(1, connection); // 1 is connection id
1658     RefObject::DecObjRef(store);
1659     store = nullptr;
1660     std::this_thread::sleep_for(std::chrono::seconds(1));
1661 
1662     /**
1663      * @tc.steps: step3. try trigger heart beat after store release.
1664      * @tc.expected: No crash.
1665      */
1666     Timestamp maxTimestamp = 0u;
1667     syncInterface->GetMaxTimestamp(maxTimestamp);
1668     RefObject::DecObjRef(syncInterface);
1669 }
1670 
1671 /**
1672  * @tc.name: ReleaseContinueTokenTest001
1673  * @tc.desc: Test relaese continue token
1674  * @tc.type: FUNC
1675  * @tc.require:
1676  * @tc.author: zhangshijie
1677  */
1678 HWTEST_F(DistributedDBRelationalGetDataTest, ReleaseContinueTokenTest001, TestSize.Level1)
1679 {
1680     /**
1681      * @tc.steps: step1. open store prepare data.
1682      * @tc.expected: Succeed.
1683      */
1684     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1685     ASSERT_NE(g_delegate, nullptr);
1686     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1687 
1688     for (int i = 1; i <= 5; ++i) { // 5 is loop count
1689         EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK);  // 1024*1024 equals 1M.
1690     }
1691 
1692     EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
1693     g_delegate = nullptr;
1694 
1695     /**
1696      * @tc.steps: step2. call GetSyncData.
1697      * @tc.expected: return -E_UNFINISHED.
1698      */
1699     auto store = new(std::nothrow) SQLiteRelationalStore();
1700     ASSERT_NE(store, nullptr);
1701     RelationalDBProperties properties;
1702     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1703     EXPECT_EQ(store->Open(properties), E_OK);
1704     int errCode = E_OK;
1705     auto connection = store->GetDBConnection(errCode);
1706     EXPECT_EQ(errCode, E_OK);
1707     ASSERT_NE(connection, nullptr);
__anona733078b0402(const std::string &, const std::string &) 1708     errCode = store->RegisterLifeCycleCallback([](const std::string &, const std::string &) {
1709     });
1710     EXPECT_EQ(errCode, E_OK);
1711     errCode = store->RegisterLifeCycleCallback(nullptr);
1712     EXPECT_EQ(errCode, E_OK);
1713     auto syncInterface = store->GetStorageEngine();
1714     ASSERT_NE(syncInterface, nullptr);
1715 
1716     ContinueToken token = nullptr;
1717     QueryObject query(Query::Select(g_tableName));
1718     std::vector<SingleVerKvEntry *> entries;
1719 
1720     DataSizeSpecInfo sizeInfo;
1721     sizeInfo.blockSize = 1 * 1024 * 1024;  // permit 1M.
1722     EXPECT_EQ(syncInterface->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries), -E_UNFINISHED);
1723     EXPECT_NE(token, nullptr);
1724     syncInterface->ReleaseContinueToken(token);
1725     RefObject::IncObjRef(syncInterface);
1726 
1727     SingleVerKvEntry::Release(entries);
1728     store->ReleaseDBConnection(1, connection); // 1 is connection id
1729     RefObject::DecObjRef(store);
1730     store = nullptr;
1731     std::this_thread::sleep_for(std::chrono::seconds(1));
1732     RefObject::DecObjRef(syncInterface);
1733 }
1734 
1735 /**
1736  * @tc.name: StopSync001
1737  * @tc.desc: Test Relational Stop Sync Action.
1738  * @tc.type: FUNC
1739  * @tc.require: AR000H2QPN
1740  * @tc.author: zhangqiquan
1741  */
1742 HWTEST_F(DistributedDBRelationalGetDataTest, StopSync001, TestSize.Level1)
1743 {
1744     RelationalDBProperties properties;
1745     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1746     properties.SetBoolProp(DBProperties::SYNC_DUAL_TUPLE_MODE, true);
1747     const int loopCount = 1000;
__anona733078b0502() 1748     std::thread userChangeThread([]() {
1749         for (int i = 0; i < loopCount; ++i) {
1750             RuntimeConfig::NotifyUserChanged();
1751             std::this_thread::sleep_for(std::chrono::milliseconds(1));
1752         }
1753     });
1754     std::string hashIdentifier = properties.GetStringProp(RelationalDBProperties::IDENTIFIER_DATA, "");
1755     properties.SetStringProp(DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, hashIdentifier);
1756     OpenDbProperties option;
1757     option.uri = properties.GetStringProp(DBProperties::DATA_DIR, "");
1758     option.createIfNecessary = true;
1759     for (int i = 0; i < loopCount; ++i) {
1760         auto sqliteStorageEngine = std::make_shared<SQLiteSingleRelationalStorageEngine>(properties);
1761         ASSERT_NE(sqliteStorageEngine, nullptr);
1762         StorageEngineAttr poolSize = {1, 1, 0, 16}; // at most 1 write 16 read.
1763         int errCode = sqliteStorageEngine->InitSQLiteStorageEngine(poolSize, option, hashIdentifier);
1764         EXPECT_EQ(errCode, E_OK);
1765         auto storageEngine = new (std::nothrow) RelationalSyncAbleStorage(sqliteStorageEngine);
1766         ASSERT_NE(storageEngine, nullptr);
1767         auto syncAbleEngine = std::make_unique<SyncAbleEngine>(storageEngine);
1768         ASSERT_NE(syncAbleEngine, nullptr);
1769         syncAbleEngine->WakeUpSyncer();
1770         syncAbleEngine->Close();
1771         RefObject::KillAndDecObjRef(storageEngine);
1772     }
1773     userChangeThread.join();
1774 }
1775 
1776 /**
1777  * @tc.name: EraseDeviceWaterMark001
1778  * @tc.desc: Test Relational erase water mark.
1779  * @tc.type: FUNC
1780  * @tc.require: AR000H2QPN
1781  * @tc.author: zhangqiquan
1782  */
1783 HWTEST_F(DistributedDBRelationalGetDataTest, EraseDeviceWaterMark001, TestSize.Level1)
1784 {
1785     auto syncAbleEngine = std::make_unique<SyncAbleEngine>(nullptr);
1786     ASSERT_NE(syncAbleEngine, nullptr);
1787     EXPECT_EQ(syncAbleEngine->EraseDeviceWaterMark("", true), -E_INVALID_ARGS);
1788 }
1789 }
1790 #endif
1791