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