• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, " + std::string(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:
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:
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:
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:
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 " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName +
530         "_log WHERE flag&0x01=0x01;", 0U);  // g_tableName has no data, therefore no delete log
531     ExpectCount(db, "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName +
532         "_log WHERE flag&0x01=0x01;", 2U);  // 2 deleted log
533     ExpectCount(db, "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" +
534         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceA)) + ";", 3U);  // 3 records in A
535     ExpectCount(db, "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" +
536         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceB)) + ";", RECORD_COUNT);  // 5 records in B
537 
538     sqlite3_close(db);
539     RefObject::DecObjRef(g_store);
540 }
541 
542 /**
543  * @tc.name: GetQuerySyncData1
544  * @tc.desc: GetSyncData interface.
545  * @tc.type: FUNC
546  * @tc.require:
547  * @tc.author: lidongwei
548  */
549 HWTEST_F(DistributedDBRelationalGetDataTest, GetQuerySyncData1, TestSize.Level1)
550 {
551     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
552     ASSERT_NE(g_delegate, nullptr);
553     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
554 
555     /**
556      * @tc.steps: step1. Put 100 records.
557      * @tc.expected: Succeed, return OK.
558      */
559     const size_t RECORD_COUNT = 100; // 100 records.
560     for (size_t i = 0; i < RECORD_COUNT; ++i) {
561         EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
562     }
563 
564     /**
565      * @tc.steps: step2. Get data limit 80, offset 30.
566      * @tc.expected: Get 70 records.
567      */
568     auto store = GetRelationalStore();
569     ASSERT_NE(store, nullptr);
570     ContinueToken token = nullptr;
571     const unsigned int LIMIT = 80; // limit as 80.
572     const unsigned int OFFSET = 30; // offset as 30.
573     const unsigned int EXPECT_COUNT = RECORD_COUNT - OFFSET; // expect 70 records.
574     QueryObject query(Query::Select(g_tableName).Limit(LIMIT, OFFSET));
575     std::vector<SingleVerKvEntry *> entries;
576 
577     int errCode = store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries);
578     EXPECT_EQ(entries.size(), EXPECT_COUNT);
579     EXPECT_EQ(errCode, E_OK);
580     EXPECT_EQ(token, nullptr);
581     SingleVerKvEntry::Release(entries);
582     RefObject::DecObjRef(g_store);
583 }
584 
585 /**
586  * @tc.name: GetQuerySyncData2
587  * @tc.desc: GetSyncData interface.
588  * @tc.type: FUNC
589  * @tc.require:
590  * @tc.author: lidongwei
591  */
592 HWTEST_F(DistributedDBRelationalGetDataTest, GetQuerySyncData2, TestSize.Level1)
593 {
594     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
595     ASSERT_NE(g_delegate, nullptr);
596     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
597 
598     /**
599      * @tc.steps: step1. Put 100 records.
600      * @tc.expected: Succeed, return OK.
601      */
602     const size_t RECORD_COUNT = 100; // 100 records.
603     for (size_t i = 0; i < RECORD_COUNT; ++i) {
604         EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
605     }
606 
607     /**
608      * @tc.steps: step2. Get record whose key is not equal to 10 and value is not equal to 20, order by key desc.
609      * @tc.expected: Succeed, Get 98 records.
610      */
611     auto store = GetRelationalStore();
612     ASSERT_NE(store, nullptr);
613     ContinueToken token = nullptr;
614 
615     Query query = Query::Select(g_tableName).NotEqualTo("key", 10).And().NotEqualTo("value", 20).OrderBy("key", false);
616     QueryObject queryObj(query);
617     queryObj.SetSchema(store->GetSchemaInfo());
618 
619     std::vector<SingleVerKvEntry *> entries;
620     EXPECT_EQ(store->GetSyncData(queryObj, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
621     EXPECT_EQ(token, nullptr);
622     size_t expectCount = 98;  // expect 98 records.
623     EXPECT_EQ(entries.size(), expectCount);
624     for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
625         auto nextOne = std::next(iter, 1);
626         if (nextOne != entries.end()) {
627             EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
628         }
629     }
630     SingleVerKvEntry::Release(entries);
631 
632     /**
633      * @tc.steps: step3. Get record whose key is equal to 10 or value is equal to 20, order by key asc.
634      * @tc.expected: Succeed, Get 98 records.
635      */
636     query = Query::Select(g_tableName).EqualTo("key", 10).Or().EqualTo("value", 20).OrderBy("key", true);
637     queryObj = QueryObject(query);
638     queryObj.SetSchema(store->GetSchemaInfo());
639 
640     EXPECT_EQ(store->GetSyncData(queryObj, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
641     EXPECT_EQ(token, nullptr);
642     expectCount = 2;  // expect 2 records.
643     EXPECT_EQ(entries.size(), expectCount);
644     for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
645         auto nextOne = std::next(iter, 1);
646         if (nextOne != entries.end()) {
647             EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
648         }
649     }
650     SingleVerKvEntry::Release(entries);
651     RefObject::DecObjRef(g_store);
652 }
653 
654 /**
655  * @tc.name: GetIncorrectTypeData1
656  * @tc.desc: GetSyncData and PutSyncDataWithQuery interface.
657  * @tc.type: FUNC
658  * @tc.require:
659  * @tc.author: lidongwei
660  */
661 HWTEST_F(DistributedDBRelationalGetDataTest, GetIncorrectTypeData1, TestSize.Level1)
662 {
663     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
664     ASSERT_NE(g_delegate, nullptr);
665     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
666 
667     /**
668      * @tc.steps: step1. Create 2 index for table "data".
669      * @tc.expected: Succeed, return OK.
670      */
671     sqlite3 *db = nullptr;
672     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
673 
674     ExecSqlAndAssertOK(db, {"CREATE INDEX index1 ON " + g_tableName + "(value);",
675                             "CREATE UNIQUE INDEX index2 ON " + g_tableName + "(value,key);"});
676 
677     /**
678      * @tc.steps: step2. Create distributed table "dataPlus".
679      * @tc.expected: Succeed, return OK.
680      */
681     const string tableName = g_tableName + "Plus";
682     string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
683     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
684     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
685 
686     /**
687      * @tc.steps: step3. Put 5 records with different type into "dataPlus" table.
688      * @tc.expected: Succeed, return OK.
689      */
690     const size_t RECORD_COUNT = 5;  // 5 sqls
691     ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
692                             "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
693                             "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
694                             "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
695                             "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');"});
696 
697     /**
698      * @tc.steps: step4. Get all data from "dataPlus" table.
699      * @tc.expected: Succeed and the count is right.
700      */
701     auto store = GetRelationalStore();
702     ASSERT_NE(store, nullptr);
703     ContinueToken token = nullptr;
704     QueryObject query(Query::Select(tableName));
705     std::vector<SingleVerKvEntry *> entries;
706     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
707     EXPECT_EQ(entries.size(), RECORD_COUNT);
708 
709     /**
710      * @tc.steps: step5. Put data into "data" table from deviceA.
711      * @tc.expected: Succeed, return OK.
712      */
713     QueryObject queryPlus(Query::Select(g_tableName));
714     const DeviceID deviceID = "deviceA";
715     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
716         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
717     ASSERT_EQ(E_OK, SQLiteUtils::CloneIndexes(db, g_tableName,
718         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
719 
720     SetRemoteSchema(store, deviceID);
721     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
722     SingleVerKvEntry::Release(entries);
723 
724     /**
725      * @tc.steps: step6. Check data.
726      * @tc.expected: All data in the two tables are same.
727      */
728     ExpectCount(db, "SELECT count(*) FROM " + tableName + " as a, " + std::string(DBConstant::RELATIONAL_PREFIX) +
729         g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b "
730         "WHERE a.key=b.key AND (a.value=b.value OR (a.value is NULL AND b.value is NULL));", RECORD_COUNT);
731 
732     /**
733      * @tc.steps: step7. Check index.
734      * @tc.expected: 2 index for deviceA's data table exists.
735      */
736     ExpectCount(db,
737         "SELECT count(*) FROM sqlite_master WHERE type='index' AND tbl_name='" +
738         std::string(DBConstant::RELATIONAL_PREFIX) +
739         g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "'", 2U); // 2 index
740     sqlite3_close(db);
741     RefObject::DecObjRef(g_store);
742 }
743 
744 /**
745  * @tc.name: UpdateData1
746  * @tc.desc: UpdateData succeed when the table has primary key.
747  * @tc.type: FUNC
748  * @tc.require:
749  * @tc.author: lidongwei
750  */
751 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateData1, TestSize.Level1)
752 {
753     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
754     ASSERT_NE(g_delegate, nullptr);
755     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
756 
757     /**
758      * @tc.steps: step1. Create distributed table "dataPlus".
759      * @tc.expected: Succeed, return OK.
760      */
761     const string tableName = g_tableName + "Plus";
762     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
763     sqlite3 *db = nullptr;
764     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
765     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
766     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
767 
768     /**
769      * @tc.steps: step2. Put 5 records with different type into "dataPlus" table.
770      * @tc.expected: Succeed, return OK.
771      */
772     vector<string> sqls = {
773         "INSERT INTO " + tableName + " VALUES(NULL, 1);",
774         "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
775         "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
776         "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
777         "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');",
778     };
779     const size_t RECORD_COUNT = sqls.size();
780     for (const auto &item : sqls) {
781         ASSERT_EQ(sqlite3_exec(db, item.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
782     }
783 
784     /**
785      * @tc.steps: step3. Get all data from "dataPlus" table.
786      * @tc.expected: Succeed and the count is right.
787      */
788     auto store = GetRelationalStore();
789     ASSERT_NE(store, nullptr);
790     ContinueToken token = nullptr;
791     QueryObject query(Query::Select(tableName));
792     std::vector<SingleVerKvEntry *> entries;
793     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
794     EXPECT_EQ(entries.size(), RECORD_COUNT);
795 
796     /**
797      * @tc.steps: step4. Put data into "data" table from deviceA for 10 times.
798      * @tc.expected: Succeed, return OK.
799      */
800     query = QueryObject(Query::Select(g_tableName));
801     const DeviceID deviceID = "deviceA";
802     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
803         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
804 
805     SetRemoteSchema(store, deviceID);
806     for (uint32_t i = 0; i < 10; ++i) {  // 10 for test.
807         EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
808     }
809     SingleVerKvEntry::Release(entries);
810 
811     /**
812      * @tc.steps: step5. Check data.
813      * @tc.expected: There is 5 data in table.
814      */
815     sql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" +
816         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
817     size_t count = 0;
818     EXPECT_EQ(GetCount(db, sql, count), E_OK);
819     EXPECT_EQ(count, RECORD_COUNT);
820 
821     sql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_log;";
822     count = 0;
823     EXPECT_EQ(GetCount(db, sql, count), E_OK);
824     EXPECT_EQ(count, RECORD_COUNT);
825 
826     sqlite3_close(db);
827     RefObject::DecObjRef(g_store);
828 }
829 
830 /**
831  * @tc.name: UpdateDataWithMulDevData1
832  * @tc.desc: UpdateData succeed when there is multiple devices data exists.
833  * @tc.type: FUNC
834  * @tc.require:
835  * @tc.author: lidongwei
836  */
837 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateDataWithMulDevData1, TestSize.Level1)
838 {
839     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
840     ASSERT_NE(g_delegate, nullptr);
841     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
842     /**
843      * @tc.steps: step1. Create distributed table "dataPlus".
844      * @tc.expected: Succeed, return OK.
845      */
846     const string tableName = g_tableName + "Plus";
847     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
848     sqlite3 *db = nullptr;
849     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
850     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
851     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
852     /**
853      * @tc.steps: step2. Put k1v1 into "dataPlus" table.
854      * @tc.expected: Succeed, return OK.
855      */
856     sql = "INSERT INTO " + tableName + " VALUES(1, 1);"; // k1v1
857     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
858     /**
859      * @tc.steps: step3. Get k1v1 from "dataPlus" table.
860      * @tc.expected: Succeed and the count is right.
861      */
862     auto store = GetRelationalStore();
863     ASSERT_NE(store, nullptr);
864     ContinueToken token = nullptr;
865     QueryObject query(Query::Select(tableName));
866     std::vector<SingleVerKvEntry *> entries;
867     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
868     /**
869      * @tc.steps: step4. Put k1v1 into "data" table from deviceA.
870      * @tc.expected: Succeed, return OK.
871      */
872     query = QueryObject(Query::Select(g_tableName));
873     const DeviceID deviceID = "deviceA";
874     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
875         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
876 
877     SetRemoteSchema(store, deviceID);
878     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
879     SingleVerKvEntry::Release(entries);
880     /**
881      * @tc.steps: step4. Put k1v1 into "data" table.
882      * @tc.expected: Succeed, return OK.
883      */
884     EXPECT_EQ(AddOrUpdateRecord(1, 1), E_OK); // k1v1
885     /**
886      * @tc.steps: step5. Change k1v1 to k1v2
887      * @tc.expected: Succeed, return OK.
888      */
889     sql = "UPDATE " + g_tableName + " SET value=2 WHERE key=1;"; // k1v1
890     EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); // change k1v1 to k1v2
891 
892     sqlite3_close(db);
893     RefObject::DecObjRef(g_store);
894 }
895 
896 /**
897  * @tc.name: MissQuery1
898  * @tc.desc: Check REMOTE_DEVICE_DATA_MISS_QUERY flag succeed.
899  * @tc.type: FUNC
900  * @tc.require:
901  * @tc.author: lidongwei
902  */
903 HWTEST_F(DistributedDBRelationalGetDataTest, MissQuery1, TestSize.Level1)
904 {
905     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
906     ASSERT_NE(g_delegate, nullptr);
907     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
908     /**
909      * @tc.steps: step1. Create distributed table "dataPlus".
910      * @tc.expected: Succeed, return OK.
911      */
912     const string tableName = g_tableName + "Plus";
913     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
914     sqlite3 *db = nullptr;
915     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
916     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
917     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
918 
919     /**
920      * @tc.steps: step2. Put 5 records with different type into "dataPlus" table.
921      * @tc.expected: Succeed, return OK.
922      */
923     ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
924         "INSERT INTO " + tableName + " VALUES(NULL, 2);", "INSERT INTO " + tableName + " VALUES(NULL, 3);",
925         "INSERT INTO " + tableName + " VALUES(NULL, 4);", "INSERT INTO " + tableName + " VALUES(NULL, 5);"});
926 
927     /**
928      * @tc.steps: step3. Get all data from "dataPlus" table.
929      * @tc.expected: Succeed and the count is right.
930      */
931     auto store = GetRelationalStore();
932     ASSERT_NE(store, nullptr);
933     ContinueToken token = nullptr;
934     SyncTimeRange timeRange;
935     QueryObject query(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4));
936     std::vector<SingleVerKvEntry *> entries;
937     EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK);
938     timeRange.lastQueryTime = (*(entries.rbegin()))->GetTimestamp();
939     EXPECT_EQ(entries.size(), 3U);  // 3 for test
940 
941     /**
942      * @tc.steps: step4. Put data into "data" table from deviceA for 10 times.
943      * @tc.expected: Succeed, return OK.
944      */
945     query = QueryObject(Query::Select(g_tableName));
946     const DeviceID deviceID = "deviceA";
947     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
948         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
949 
950     SetRemoteSchema(store, deviceID);
951     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
952     SingleVerKvEntry::Release(entries);
953 
954     /**
955      * @tc.steps: step5. Check data.
956      * @tc.expected: There is 3 data in table.
957      */
958     std::string getDataSql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_" +
959         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
960     ExpectCount(db, getDataSql, 3);  // 2,3,4
961 
962     std::string getLogSql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName +
963         "_log;";
964     ExpectCount(db, getLogSql, 3);  // 2,3,4
965 
966     /**
967      * @tc.steps: step6. Update data. k2v2 to k2v102, k3v3 to k3v103, k4v4 to k4v104.
968      * @tc.expected: Update succeed.
969      */
970     ExecSqlAndAssertOK(db, {"INSERT OR REPLACE INTO " + tableName + " VALUES(2, 102);",
971                             "UPDATE " + tableName + " SET value=103 WHERE value=3;",
972                             "DELETE FROM " + tableName + " WHERE key=4;",
973                             "INSERT INTO " + tableName + " VALUES(4, 104);"});
974 
975     /**
976      * @tc.steps: step7. Get all data from "dataPlus" table.
977      * @tc.expected: Succeed and the count is right.
978      */
979     query = QueryObject(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4));
980     EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK);
981     EXPECT_EQ(entries.size(), 3U);  // 3 miss query data.
982 
983     /**
984      * @tc.steps: step8. Put data into "data" table from deviceA for 10 times.
985      * @tc.expected: Succeed, return OK.
986      */
987     SetRemoteSchema(store, deviceID);
988     query = QueryObject(Query::Select(g_tableName));
989     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
990     SingleVerKvEntry::Release(entries);
991 
992     /**
993      * @tc.steps: step9. Check data.
994      * @tc.expected: There is 0 data in table.
995      */
996     ExpectCount(db, getDataSql, 0U);  // 0 data exists
997     ExpectCount(db, getLogSql, 0U);  // 0 data exists
998 
999     sqlite3_close(db);
1000     RefObject::DecObjRef(g_store);
1001 }
1002 
1003 /**
1004  * @tc.name: CompatibleData1
1005  * @tc.desc: Check compatibility.
1006  * @tc.type: FUNC
1007  * @tc.require:
1008  * @tc.author: lidongwei
1009  */
1010 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData1, TestSize.Level1)
1011 {
1012     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1013     ASSERT_NE(g_delegate, nullptr);
1014     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1015     /**
1016      * @tc.steps: step1. Create distributed table "dataPlus".
1017      * @tc.expected: Succeed, return OK.
1018      */
1019     const string tableName = g_tableName + "Plus";
1020     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1021         extra_field TEXT NOT NULL DEFAULT 'default_value');";
1022     sqlite3 *db = nullptr;
1023     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1024     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1025     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1026     /**
1027      * @tc.steps: step2. Put 1 record into data and dataPlus table.
1028      * @tc.expected: Succeed, return OK.
1029      */
1030     ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1031     sql = "INSERT INTO " + tableName + " VALUES(2, 102, 'f3');"; // k2v102
1032     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1033     /**
1034      * @tc.steps: step3. Get all data from "data" table.
1035      * @tc.expected: Succeed and the count is right.
1036      */
1037     auto store = GetRelationalStore();
1038     ASSERT_NE(store, nullptr);
1039     ContinueToken token = nullptr;
1040     QueryObject query(Query::Select(g_tableName));
1041     std::vector<SingleVerKvEntry *> entries;
1042     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1043     EXPECT_EQ(entries.size(), 1UL);
1044     /**
1045      * @tc.steps: step4. Put data into "data_plus" table from deviceA.
1046      * @tc.expected: Succeed, return OK.
1047      */
1048     QueryObject queryPlus(Query::Select(tableName));
1049     const DeviceID deviceID = "deviceA";
1050     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName),
1051         DBCommon::GetDistributedTableName(deviceID, tableName)));
1052 
1053     SetRemoteSchema(store, deviceID);
1054     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1055     SingleVerKvEntry::Release(entries);
1056     /**
1057      * @tc.steps: step4. Get all data from "dataPlus" table.
1058      * @tc.expected: Succeed and the count is right.
1059      */
1060     EXPECT_EQ(store->GetSyncData(queryPlus, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1061     EXPECT_EQ(entries.size(), 1UL);
1062     /**
1063      * @tc.steps: step5. Put data into "data" table from deviceA.
1064      * @tc.expected: Succeed, return OK.
1065      */
1066     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
1067         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
1068     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
1069     SingleVerKvEntry::Release(entries);
1070     /**
1071      * @tc.steps: step6. Check data.
1072      * @tc.expected: All data in the two tables are same.
1073      */
1074     sql = "SELECT count(*) FROM " + g_tableName + " as a," + std::string(DBConstant::RELATIONAL_PREFIX) +
1075         tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " +
1076         "WHERE a.key=b.key AND a.value=b.value;";
1077     size_t count = 0;
1078     EXPECT_EQ(GetCount(db, sql, count), E_OK);
1079     EXPECT_EQ(count, 1UL);
1080     sql = "SELECT count(*) FROM " + tableName + " as a," + std::string(DBConstant::RELATIONAL_PREFIX) +
1081         g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " +
1082         "WHERE a.key=b.key AND a.value=b.value;";
1083     count = 0;
1084     EXPECT_EQ(GetCount(db, sql, count), E_OK);
1085     EXPECT_EQ(count, 1UL);
1086     sqlite3_close(db);
1087     RefObject::DecObjRef(g_store);
1088 }
1089 
1090 /**
1091  * @tc.name: GetDataSortByTime1
1092  * @tc.desc: All query get data sort by time asc.
1093  * @tc.type: FUNC
1094  * @tc.require:
1095  * @tc.author: lidongwei
1096  */
1097 HWTEST_F(DistributedDBRelationalGetDataTest, GetDataSortByTime1, TestSize.Level1)
1098 {
1099     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1100     ASSERT_NE(g_delegate, nullptr);
1101     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1102     /**
1103      * @tc.steps: step2. Add 3 record into data. k1v105, k2v104, k3v103, timestamp desc.
1104      * @tc.expected: Succeed, return OK.
1105      */
1106     sqlite3 *db = nullptr;
1107     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1108     std::string sql = "INSERT INTO " + g_tableName + " VALUES(1, 101);"; // k1v101
1109     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1110     sql = "INSERT INTO " + g_tableName + " VALUES(2, 102);"; // k2v102
1111     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1112     sql = "INSERT INTO " + g_tableName + " VALUES(3, 103);"; // k3v103
1113     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1114     sql = "UPDATE " + g_tableName + " SET value=104 WHERE key=2;"; // k2v104
1115     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1116     sql = "UPDATE " + g_tableName + " SET value=105 WHERE key=1;"; // k1v105
1117     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1118     /**
1119      * @tc.steps: step3. Get all data from "data" table by all query.
1120      * @tc.expected: Succeed and the count is right.
1121      */
1122     auto store = GetRelationalStore();
1123     ASSERT_NE(store, nullptr);
1124     ContinueToken token = nullptr;
1125     QueryObject query(Query::Select(g_tableName));
1126     std::vector<SingleVerKvEntry *> entries;
1127     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1128     ExpectMissQueryCnt(entries, 3UL);  // 3 data
1129     SingleVerKvEntry::Release(entries);
1130 
1131     query = QueryObject(Query::Select(g_tableName).EqualTo("key", 1).Or().EqualTo("key", 3));
1132     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1133     ExpectMissQueryCnt(entries, 2UL);  // 2 data
1134     SingleVerKvEntry::Release(entries);
1135 
1136     query = QueryObject(Query::Select(g_tableName).OrderBy("key", false));
1137     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1138     ExpectMissQueryCnt(entries, 3UL);  // 3 data
1139     SingleVerKvEntry::Release(entries);
1140 
1141     query = QueryObject(Query::Select(g_tableName).OrderBy("value", false));
1142     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1143     ExpectMissQueryCnt(entries, 3UL);  // 3 data
1144     SingleVerKvEntry::Release(entries);
1145 
1146     query = QueryObject(Query::Select(g_tableName).Limit(2));
1147     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1148     ExpectMissQueryCnt(entries, 2UL);  // 2 data
1149     SingleVerKvEntry::Release(entries);
1150 
1151     sqlite3_close(db);
1152     RefObject::DecObjRef(g_store);
1153 }
1154 
1155 /**
1156  * @tc.name: SameFieldWithLogTable1
1157  * @tc.desc: Get query data OK when the table has same field with log table.
1158  * @tc.type: FUNC
1159  * @tc.require:
1160  * @tc.author: lidongwei
1161  */
1162 HWTEST_F(DistributedDBRelationalGetDataTest, SameFieldWithLogTable1, TestSize.Level1)
1163 {
1164     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1165     ASSERT_NE(g_delegate, nullptr);
1166     /**
1167      * @tc.steps: step1. Create distributed table "dataPlus".
1168      * @tc.expected: Succeed, return OK.
1169      */
1170     const string tableName = g_tableName + "Plus";
1171     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, flag INTEGER NOT NULL, \
1172         device TEXT NOT NULL DEFAULT 'default_value');";
1173     sqlite3 *db = nullptr;
1174     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1175     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1176     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1177     /**
1178      * @tc.steps: step2. Put 1 record into dataPlus table.
1179      * @tc.expected: Succeed, return OK.
1180      */
1181     sql = "INSERT INTO " + tableName + " VALUES(1, 101, 'f3');"; // k1v101
1182     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1183     /**
1184      * @tc.steps: step3. Get all data from dataPlus table.
1185      * @tc.expected: Succeed and the count is right.
1186      */
1187     auto store = GetRelationalStore();
1188     ASSERT_NE(store, nullptr);
1189     ContinueToken token = nullptr;
1190     QueryObject query(Query::Select(tableName).EqualTo("flag", 101).OrderBy("device", false));
1191     std::vector<SingleVerKvEntry *> entries;
1192     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1193     EXPECT_EQ(entries.size(), 1UL);
1194     SingleVerKvEntry::Release(entries);
1195     sqlite3_close(db);
1196     RefObject::DecObjRef(g_store);
1197 }
1198 
1199 /**
1200  * @tc.name: CompatibleData2
1201  * @tc.desc: Check compatibility.
1202  * @tc.type: FUNC
1203  * @tc.require:
1204  * @tc.author: lidongwei
1205  */
1206 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData2, TestSize.Level1)
1207 {
1208     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1209     ASSERT_NE(g_delegate, nullptr);
1210     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1211 
1212     sqlite3 *db = nullptr;
1213     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1214 
1215     auto store = GetRelationalStore();
1216     ASSERT_NE(store, nullptr);
1217 
1218     /**
1219      * @tc.steps: step1. Create distributed table from deviceA.
1220      * @tc.expected: Succeed, return OK.
1221      */
1222     const DeviceID deviceID = "deviceA";
1223     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
1224         DBCommon::GetDistributedTableName(deviceID, g_tableName)));
1225 
1226     /**
1227      * @tc.steps: step2. Alter "data" table and create distributed table again.
1228      * @tc.expected: Succeed.
1229      */
1230     std::string sql = "ALTER TABLE " + g_tableName + " ADD COLUMN integer_type INTEGER DEFAULT 123 not null;"
1231         "ALTER TABLE " + g_tableName + " ADD COLUMN text_type TEXT DEFAULT 'high_version' not null;"
1232         "ALTER TABLE " + g_tableName + " ADD COLUMN real_type REAL DEFAULT 123.123456 not null;"
1233         "ALTER TABLE " + g_tableName + " ADD COLUMN blob_type BLOB DEFAULT 123 not null;";
1234     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1235     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1236 
1237     /**
1238      * @tc.steps: step3. Check deviceA's distributed table.
1239      * @tc.expected: The create sql is correct.
1240      */
1241     std::string expectSql = "CREATE TABLE 'naturalbase_rdb_aux_data_"
1242         "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f' ('key' 'integer' NOT NULL,'value' 'integer',"
1243         " 'integer_type' 'integer' NOT NULL DEFAULT 123, 'text_type' 'text' NOT NULL DEFAULT 'high_version', "
1244         "'real_type' 'real' NOT NULL DEFAULT 123.123456, 'blob_type' 'blob' NOT NULL DEFAULT 123, PRIMARY KEY ('key'))";
1245     sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName +
1246         "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';";
1247     EXPECT_EQ(GetOneText(db, sql), expectSql);
1248 
1249     sqlite3_close(db);
1250     RefObject::DecObjRef(g_store);
1251 }
1252 
1253 /**
1254  * @tc.name: PutSyncDataConflictDataTest001
1255  * @tc.desc: Check put with conflict sync data.
1256  * @tc.type: FUNC
1257  * @tc.require:
1258  * @tc.author: lianhuix
1259  */
1260 HWTEST_F(DistributedDBRelationalGetDataTest, PutSyncDataConflictDataTest001, TestSize.Level1)
1261 {
1262     const DeviceID deviceID_A = "deviceA";
1263     const DeviceID deviceID_B = "deviceB";
1264     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath);
1265     RelationalTestUtils::CreateDeviceTable(db, g_tableName, deviceID_B);
1266 
1267     DBStatus status = g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate);
1268     EXPECT_EQ(status, DBStatus::OK);
1269     ASSERT_NE(g_delegate, nullptr);
1270     EXPECT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1271 
1272     auto store = const_cast<RelationalSyncAbleStorage *>(GetRelationalStore());
1273     ASSERT_NE(store, nullptr);
1274 
1275     RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1001,'VAL_1');");
1276     RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1002,'VAL_2');");
1277     RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1003,'VAL_3');");
1278 
1279     DataSizeSpecInfo sizeInfo {MTU_SIZE, 50};
1280     ContinueToken token = nullptr;
1281     QueryObject query(Query::Select(g_tableName));
1282     std::vector<SingleVerKvEntry *> entries;
1283     int errCode = store->GetSyncData(query, {}, sizeInfo, token, entries);
1284     EXPECT_EQ(errCode, E_OK);
1285 
1286     SetRemoteSchema(store, deviceID_B);
1287     errCode = store->PutSyncDataWithQuery(query, entries, deviceID_B);
1288     EXPECT_EQ(errCode, E_OK);
1289     GenericSingleVerKvEntry::Release(entries);
1290 
1291     QueryObject query2(Query::Select(g_tableName).EqualTo("key", 1001));
1292     std::vector<SingleVerKvEntry *> entries2;
1293     store->GetSyncData(query2, {}, sizeInfo, token, entries2);
1294 
1295     errCode = store->PutSyncDataWithQuery(query, entries2, deviceID_B);
1296     EXPECT_EQ(errCode, E_OK);
1297     GenericSingleVerKvEntry::Release(entries2);
1298 
1299     RefObject::DecObjRef(g_store);
1300 
1301     std::string deviceTable = DBCommon::GetDistributedTableName(deviceID_B, g_tableName);
1302     EXPECT_EQ(RelationalTestUtils::CheckTableRecords(db, deviceTable), 3);
1303     sqlite3_close_v2(db);
1304 }
1305 
1306 /**
1307  * @tc.name: SaveNonexistDevdata1
1308  * @tc.desc: Save non-exist device data and check errCode.
1309  * @tc.type: FUNC
1310  * @tc.require:
1311  * @tc.author: lidongwei
1312  */
1313 HWTEST_F(DistributedDBRelationalGetDataTest, SaveNonexistDevdata1, TestSize.Level1)
1314 {
1315     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1316     ASSERT_NE(g_delegate, nullptr);
1317     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1318     /**
1319      * @tc.steps: step1. Create distributed table "dataPlus".
1320      * @tc.expected: Succeed, return OK.
1321      */
1322     const string tableName = g_tableName + "Plus";
1323     std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1324         extra_field TEXT NOT NULL DEFAULT 'default_value');";
1325     sqlite3 *db = nullptr;
1326     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1327     ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1328     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1329     /**
1330      * @tc.steps: step2. Put 1 record into data table.
1331      * @tc.expected: Succeed, return OK.
1332      */
1333     ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1334 
1335     /**
1336      * @tc.steps: step3. Get all data from "data" table.
1337      * @tc.expected: Succeed and the count is right.
1338      */
1339     auto store = GetRelationalStore();
1340     ASSERT_NE(store, nullptr);
1341     ContinueToken token = nullptr;
1342     QueryObject query(Query::Select(g_tableName));
1343     std::vector<SingleVerKvEntry *> entries;
1344     EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1345     EXPECT_EQ(entries.size(), 1UL);
1346 
1347     /**
1348      * @tc.steps: step4. Put data into "data_plus" table from deviceA and deviceA does not exist.
1349      * @tc.expected: Succeed, return OK.
1350      */
1351     query = QueryObject(Query::Select(tableName));
1352     const DeviceID deviceID = "deviceA";
1353     SetRemoteSchema(store, deviceID);
1354     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
1355     SingleVerKvEntry::Release(entries);
1356 
1357     sqlite3_close(db);
1358     RefObject::DecObjRef(g_store);
1359 }
1360 
1361 /**
1362  * @tc.name: GetMaxTimestamp1
1363  * @tc.desc: Get max timestamp.
1364  * @tc.type: FUNC
1365  * @tc.require:
1366  * @tc.author: lidongwei
1367  */
1368 HWTEST_F(DistributedDBRelationalGetDataTest, GetMaxTimestamp1, TestSize.Level1)
1369 {
1370     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1371     ASSERT_NE(g_delegate, nullptr);
1372     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1373     /**
1374      * @tc.steps: step1. Create distributed table "dataPlus".
1375      * @tc.expected: Succeed, return OK.
1376      */
1377     sqlite3 *db = nullptr;
1378     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1379     const string tableName = g_tableName + "Plus";
1380     ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1381         extra_field TEXT NOT NULL DEFAULT 'default_value');");
1382     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1383 
1384     /**
1385      * @tc.steps: step2. Get max timestamp when no data exists.
1386      * @tc.expected: Succeed and the time is 0;
1387      */
1388     auto store = GetRelationalStore();
1389     ASSERT_NE(store, nullptr);
1390 
1391     Timestamp time1 = 0;
1392     store->GetMaxTimestamp(time1);
1393     EXPECT_EQ(time1, 0uLL);
1394 
1395     /**
1396      * @tc.steps: step3. Put 1 record into data table and get max timestamp.
1397      * @tc.expected: Succeed and the time is updated.
1398      */
1399     ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1400     Timestamp time2 = 0;
1401     store->GetMaxTimestamp(time2);
1402     EXPECT_GT(time2, time1);
1403 
1404     /**
1405      * @tc.steps: step4. Put 1 record into data table and get max timestamp.
1406      * @tc.expected: Succeed and the time is updated.
1407      */
1408     ASSERT_EQ(AddOrUpdateRecord(2, 102), E_OK);
1409     Timestamp time3 = 0;
1410     store->GetMaxTimestamp(time3);
1411     EXPECT_GT(time3, time2);
1412 
1413     /**
1414      * @tc.steps: step5. Put 1 record into data table and get the max timestamp of data table.
1415      * @tc.expected: Succeed and the time is equals to max timestamp in DB.
1416      */
1417     Timestamp time4 = 0;
1418     store->GetMaxTimestamp(g_tableName, time4);
1419     EXPECT_EQ(time4, time3);
1420 
1421     /**
1422      * @tc.steps: step6. Put 1 record into data table and get the max timestamp of dataPlus table.
1423      * @tc.expected: Succeed and the time is 0.
1424      */
1425     Timestamp time5 = 0;
1426     store->GetMaxTimestamp(tableName, time5);
1427     EXPECT_EQ(time5, 0uLL);
1428 
1429     sqlite3_close(db);
1430     RefObject::DecObjRef(g_store);
1431 }
1432 
1433 /**
1434  * @tc.name: NoPkData1
1435  * @tc.desc: For no pk data.
1436  * @tc.type: FUNC
1437  * @tc.require:
1438  * @tc.author: lidongwei
1439  */
1440 HWTEST_F(DistributedDBRelationalGetDataTest, NoPkData1, TestSize.Level1)
1441 {
1442     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1443     ASSERT_NE(g_delegate, nullptr);
1444 
1445     sqlite3 *db = nullptr;
1446     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1447     ExecSqlAndAssertOK(db, "DROP TABLE IF EXISTS " + g_tableName + "; \
1448         CREATE TABLE " + g_tableName + "(key INTEGER NOT NULL, value INTEGER);");
1449     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1450 
1451     /**
1452      * @tc.steps: step1. Create distributed table "dataPlus".
1453      * @tc.expected: Succeed, return OK.
1454      */
1455     const string tableName = g_tableName + "Plus";
1456     ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER NOT NULL, value INTEGER);");
1457     ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1458 
1459     /**
1460      * @tc.steps: step2. Put 2 data into "data" table.
1461      * @tc.expected: Succeed.
1462      */
1463     ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK);
1464     ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK);
1465 
1466     /**
1467      * @tc.steps: step3. Get data from "data" table.
1468      * @tc.expected: Succeed.
1469      */
1470     auto store = GetRelationalStore();
1471     ASSERT_NE(store, nullptr);
1472 
1473     ContinueToken token = nullptr;
1474     QueryObject query(Query::Select(g_tableName));
1475     std::vector<SingleVerKvEntry *> entries;
1476     EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK);
1477     EXPECT_EQ(entries.size(), 2U);  // expect 2 data.
1478 
1479     /**
1480      * @tc.steps: step4. Put data into "data" table from deviceA.
1481      * @tc.expected: Succeed, return OK.
1482      */
1483     QueryObject queryPlus(Query::Select(tableName));
1484     const DeviceID deviceID = "deviceA";
1485     ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName),
1486         DBCommon::GetDistributedTableName(deviceID, tableName)));
1487     SetRemoteSchema(store, deviceID);
1488     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1489     SingleVerKvEntry::Release(entries);
1490 
1491     /**
1492      * @tc.steps: step5. Changet data in "data" table.
1493      * @tc.expected: Succeed.
1494      */
1495     ExecSqlAndAssertOK(db, {"UPDATE " + g_tableName + " SET value=101 WHERE key=1;",
1496                             "DELETE FROM " + g_tableName + " WHERE key=2;",
1497                             "INSERT INTO " + g_tableName + " VALUES(2, 102);"});
1498 
1499     /**
1500      * @tc.steps: step6. Get data from "data" table.
1501      * @tc.expected: Succeed.
1502      */
1503     EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK);
1504     EXPECT_EQ(entries.size(), 2U);  // expect 2 data.
1505 
1506     /**
1507      * @tc.steps: step7. Put data into "data" table from deviceA.
1508      * @tc.expected: Succeed, return OK.
1509      */
1510     EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1511     SingleVerKvEntry::Release(entries);
1512 
1513     /**
1514      * @tc.steps: step8. Check data.
1515      * @tc.expected: There is 2 data.
1516      */
1517     std::string sql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_" +
1518         DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
1519     size_t count = 0;
1520     EXPECT_EQ(GetCount(db, sql, count), E_OK);
1521     EXPECT_EQ(count, 2U); // expect 2 data.
1522 
1523     sqlite3_close(db);
1524     RefObject::DecObjRef(g_store);
1525 }
1526 
1527 /**
1528  * @tc.name: GetAfterDropTable1
1529  * @tc.desc: Get data after drop table.
1530  * @tc.type: FUNC
1531  * @tc.require:
1532  * @tc.author: lidongwei
1533  */
1534 HWTEST_F(DistributedDBRelationalGetDataTest, GetAfterDropTable1, TestSize.Level1)
1535 {
1536     /**
1537      * @tc.steps: step1. Create distributed table.
1538      * @tc.expected: Succeed, return OK.
1539      */
1540     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1541     ASSERT_NE(g_delegate, nullptr);
1542     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1543 
1544     /**
1545      * @tc.steps: step2. Insert several data.
1546      * @tc.expected: Succeed, return OK.
1547      */
1548     ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK);
1549     ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK);
1550     ASSERT_EQ(AddOrUpdateRecord(3, 3), E_OK);
1551 
1552     /**
1553      * @tc.steps: step3. Check data in distributed log table.
1554      * @tc.expected: The data in log table is in expect. All the flag in log table is 1.
1555      */
1556     sqlite3 *db = nullptr;
1557     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1558 
1559     std::string getLogSql = "SELECT count(*) FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + g_tableName + "_log "
1560                             "WHERE flag&0x01<>0;";
1561     ExpectCount(db, getLogSql, 0u);  // 0 means no deleted data.
1562 
1563     /**
1564      * @tc.steps: step4. Drop the table in another connection.
1565      * @tc.expected: Succeed.
1566      */
__anon94da83750202null1567     std::thread t1([] {
1568         sqlite3 *db = nullptr;
1569         ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1570         ExecSqlAndAssertOK(db, "DROP TABLE " + g_tableName);
1571         sqlite3_close(db);
1572     });
1573     t1.join();
1574     std::this_thread::sleep_for(std::chrono::seconds(1));
1575     /**
1576      * @tc.steps: step5. Check data in distributed log table.
1577      * @tc.expected: The data in log table is in expect. All the flag in log table is 3.
1578      */
1579     ExpectCount(db, getLogSql, 3u);  // 3 means all deleted data.
1580     sqlite3_close(db);
1581 }
1582 
1583 /**
1584   * @tc.name: SetSchema1
1585   * @tc.desc: Test invalid parameters of query_object.cpp
1586   * @tc.type: FUNC
1587   * @tc.require:
1588   * @tc.author: bty
1589   */
1590 HWTEST_F(DistributedDBRelationalGetDataTest, SetSchema1, TestSize.Level1)
1591 {
1592     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1593     ASSERT_NE(g_delegate, nullptr);
1594     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1595     auto store = GetRelationalStore();
1596     ASSERT_NE(store, nullptr);
1597     Query query = Query::Select().OrderBy("errDevice", false);
1598     QueryObject queryObj1(query);
1599     int errorNo = E_OK;
1600     errorNo = queryObj1.SetSchema(store->GetSchemaInfo());
1601     EXPECT_EQ(errorNo, -E_INVALID_ARGS);
1602     EXPECT_FALSE(queryObj1.IsQueryForRelationalDB());
1603     errorNo = queryObj1.Init();
1604     EXPECT_EQ(errorNo, -E_NOT_SUPPORT);
1605     QueryObject queryObj2(query);
1606     queryObj2.SetTableName(g_tableName);
1607     errorNo = queryObj2.SetSchema(store->GetSchemaInfo());
1608     EXPECT_EQ(errorNo, E_OK);
1609     errorNo = queryObj2.Init();
1610     EXPECT_EQ(errorNo, -E_INVALID_QUERY_FIELD);
1611     RefObject::DecObjRef(g_store);
1612 }
1613 
1614 /**
1615   * @tc.name: SetNextBeginTime001
1616   * @tc.desc: Test invalid parameters of query_object.cpp
1617   * @tc.type: FUNC
1618   * @tc.require:
1619   * @tc.author: bty
1620   */
1621 HWTEST_F(DistributedDBRelationalGetDataTest, SetNextBeginTime001, TestSize.Level1)
1622 {
1623     ASSERT_NO_FATAL_FAILURE(SetNextBeginTime001());
1624 }
1625 
1626 /**
1627  * @tc.name: CloseStore001
1628  * @tc.desc: Test Relational Store Close Action.
1629  * @tc.type: FUNC
1630  * @tc.require:
1631  * @tc.author: zhangqiquan
1632  */
1633 HWTEST_F(DistributedDBRelationalGetDataTest, CloseStore001, TestSize.Level1)
1634 {
1635     /**
1636      * @tc.steps: step1. new store and get connection now ref count is 2.
1637      * @tc.expected: Succeed.
1638      */
1639     auto store = new (std::nothrow) SQLiteRelationalStore();
1640     ASSERT_NE(store, nullptr);
1641     RelationalDBProperties properties;
1642     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1643     EXPECT_EQ(store->Open(properties), E_OK);
1644     int errCode = E_OK;
1645     auto connection = store->GetDBConnection(errCode);
1646     EXPECT_EQ(errCode, E_OK);
1647     ASSERT_NE(connection, nullptr);
__anon94da83750302(const std::string &, const std::string &) 1648     errCode = store->RegisterLifeCycleCallback([](const std::string &, const std::string &) {
1649     });
1650     EXPECT_EQ(errCode, E_OK);
1651     errCode = store->RegisterLifeCycleCallback(nullptr);
1652     EXPECT_EQ(errCode, E_OK);
1653     auto syncInterface = store->GetStorageEngine();
1654     ASSERT_NE(syncInterface, nullptr);
1655     RefObject::IncObjRef(syncInterface);
1656     /**
1657      * @tc.steps: step2. release store.
1658      * @tc.expected: Succeed.
1659      */
1660     store->ReleaseDBConnection(1, connection); // 1 is connection id
1661     RefObject::DecObjRef(store);
1662     store = nullptr;
1663     std::this_thread::sleep_for(std::chrono::seconds(1));
1664 
1665     /**
1666      * @tc.steps: step3. try trigger heart beat after store release.
1667      * @tc.expected: No crash.
1668      */
1669     Timestamp maxTimestamp = 0u;
1670     syncInterface->GetMaxTimestamp(maxTimestamp);
1671     RefObject::DecObjRef(syncInterface);
1672 }
1673 
1674 /**
1675  * @tc.name: ReleaseContinueTokenTest001
1676  * @tc.desc: Test relaese continue token
1677  * @tc.type: FUNC
1678  * @tc.require:
1679  * @tc.author: zhangshijie
1680  */
1681 HWTEST_F(DistributedDBRelationalGetDataTest, ReleaseContinueTokenTest001, TestSize.Level1)
1682 {
1683     /**
1684      * @tc.steps: step1. open store prepare data.
1685      * @tc.expected: Succeed.
1686      */
1687     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1688     ASSERT_NE(g_delegate, nullptr);
1689     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1690 
1691     for (int i = 1; i <= 5; ++i) { // 5 is loop count
1692         EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK);  // 1024*1024 equals 1M.
1693     }
1694 
1695     EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
1696     g_delegate = nullptr;
1697 
1698     /**
1699      * @tc.steps: step2. call GetSyncData.
1700      * @tc.expected: return -E_UNFINISHED.
1701      */
1702     auto store = new(std::nothrow) SQLiteRelationalStore();
1703     ASSERT_NE(store, nullptr);
1704     RelationalDBProperties properties;
1705     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1706     EXPECT_EQ(store->Open(properties), E_OK);
1707     int errCode = E_OK;
1708     auto connection = store->GetDBConnection(errCode);
1709     EXPECT_EQ(errCode, E_OK);
1710     ASSERT_NE(connection, nullptr);
__anon94da83750402(const std::string &, const std::string &) 1711     errCode = store->RegisterLifeCycleCallback([](const std::string &, const std::string &) {
1712     });
1713     EXPECT_EQ(errCode, E_OK);
1714     errCode = store->RegisterLifeCycleCallback(nullptr);
1715     EXPECT_EQ(errCode, E_OK);
1716     auto syncInterface = store->GetStorageEngine();
1717     ASSERT_NE(syncInterface, nullptr);
1718 
1719     ContinueToken token = nullptr;
1720     QueryObject query(Query::Select(g_tableName));
1721     std::vector<SingleVerKvEntry *> entries;
1722 
1723     DataSizeSpecInfo sizeInfo;
1724     sizeInfo.blockSize = 1 * 1024 * 1024;  // permit 1M.
1725     EXPECT_EQ(syncInterface->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries), -E_UNFINISHED);
1726     EXPECT_NE(token, nullptr);
1727     syncInterface->ReleaseContinueToken(token);
1728     RefObject::IncObjRef(syncInterface);
1729 
1730     SingleVerKvEntry::Release(entries);
1731     store->ReleaseDBConnection(1, connection); // 1 is connection id
1732     RefObject::DecObjRef(store);
1733     store = nullptr;
1734     std::this_thread::sleep_for(std::chrono::seconds(1));
1735     RefObject::DecObjRef(syncInterface);
1736 }
1737 
1738 /**
1739  * @tc.name: StopSync001
1740  * @tc.desc: Test Relational Stop Sync Action.
1741  * @tc.type: FUNC
1742  * @tc.require:
1743  * @tc.author: zhangqiquan
1744  */
1745 HWTEST_F(DistributedDBRelationalGetDataTest, StopSync001, TestSize.Level1)
1746 {
1747     RelationalDBProperties properties;
1748     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1749     properties.SetBoolProp(DBProperties::SYNC_DUAL_TUPLE_MODE, true);
1750     const int loopCount = 1000;
__anon94da83750502() 1751     std::thread userChangeThread([]() {
1752         for (int i = 0; i < loopCount; ++i) {
1753             RuntimeConfig::NotifyUserChanged();
1754             std::this_thread::sleep_for(std::chrono::milliseconds(1));
1755         }
1756     });
1757     std::string hashIdentifier = properties.GetStringProp(RelationalDBProperties::IDENTIFIER_DATA, "");
1758     properties.SetStringProp(DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, hashIdentifier);
1759     OpenDbProperties option;
1760     option.uri = properties.GetStringProp(DBProperties::DATA_DIR, "");
1761     option.createIfNecessary = true;
1762     for (int i = 0; i < loopCount; ++i) {
1763         auto sqliteStorageEngine = std::make_shared<SQLiteSingleRelationalStorageEngine>(properties);
1764         ASSERT_NE(sqliteStorageEngine, nullptr);
1765         StorageEngineAttr poolSize = {1, 1, 0, 16}; // at most 1 write 16 read.
1766         int errCode = sqliteStorageEngine->InitSQLiteStorageEngine(poolSize, option, hashIdentifier);
1767         EXPECT_EQ(errCode, E_OK);
1768         auto storageEngine = new (std::nothrow) RelationalSyncAbleStorage(sqliteStorageEngine);
1769         ASSERT_NE(storageEngine, nullptr);
1770         auto syncAbleEngine = std::make_unique<SyncAbleEngine>(storageEngine);
1771         ASSERT_NE(syncAbleEngine, nullptr);
1772         syncAbleEngine->WakeUpSyncer();
1773         syncAbleEngine->Close();
1774         RefObject::KillAndDecObjRef(storageEngine);
1775     }
1776     userChangeThread.join();
1777 }
1778 
1779 /**
1780  * @tc.name: EraseDeviceWaterMark001
1781  * @tc.desc: Test Relational erase water mark.
1782  * @tc.type: FUNC
1783  * @tc.require:
1784  * @tc.author: zhangqiquan
1785  */
1786 HWTEST_F(DistributedDBRelationalGetDataTest, EraseDeviceWaterMark001, TestSize.Level1)
1787 {
1788     auto syncAbleEngine = std::make_unique<SyncAbleEngine>(nullptr);
1789     ASSERT_NE(syncAbleEngine, nullptr);
1790     EXPECT_EQ(syncAbleEngine->EraseDeviceWaterMark("", true), -E_INVALID_ARGS);
1791 }
1792 }
1793 #endif
1794