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