• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include <queue>
18 #include <random>
19 
20 #include "cloud_db_sync_utils_test.h"
21 #include "cloud/cloud_db_types.h"
22 #include "db_common.h"
23 #include "distributeddb_data_generate_unit_test.h"
24 #include "distributeddb_tools_unit_test.h"
25 #include "log_print.h"
26 #include "platform_specific.h"
27 #include "relational_store_client.h"
28 #include "relational_store_manager.h"
29 #include "relational_store_sqlite_ext.h"
30 #include "relational_virtual_device.h"
31 #include "runtime_config.h"
32 #include "virtual_relational_ver_sync_db_interface.h"
33 
34 using namespace testing::ext;
35 using namespace DistributedDB;
36 using namespace DistributedDBUnitTest;
37 using namespace std;
38 
39 namespace {
40     constexpr const char *DB_SUFFIX = ".db";
41     constexpr const char *STORE_ID = "Relational_Store_tracker";
42     constexpr const char *STORE_ID2 = "Relational_Store_tracker2";
43     std::string g_testDir;
44     std::string g_dbDir;
45     const string TABLE_NAME1 = "worKer1";
46     const string TABLE_NAME2 = "worKer2";
47     const string TABLE_NAME3 = "worKer3";
48     DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
49     RelationalStoreDelegate *g_delegate = nullptr;
50     VirtualCommunicatorAggregator *g_communicatorAggregator = nullptr;
51     sqlite3 *g_db = nullptr;
52     const int HALF = 2;
53 
54     const std::string CREATE_LOCAL_TABLE_SQL =
55     "CREATE TABLE IF NOT EXISTS " + TABLE_NAME1 + "(" \
56     "name TEXT PRIMARY KEY," \
57     "height REAL ," \
58     "married BOOLEAN ," \
59     "photo BLOB NOT NULL," \
60     "assert BLOB," \
61     "age INT);";
62 
63     const std::string CREATE_LOCAL_PK_TABLE_SQL =
64     "CREATE TABLE IF NOT EXISTS " + TABLE_NAME2 + "(" \
65     "id INTEGER PRIMARY KEY AUTOINCREMENT," \
66     "name TEXT ," \
67     "height REAL ," \
68     "photo BLOB ," \
69     "asserts BLOB," \
70     "age INT);";
71 
72     const std::string CREATE_LOCAL_PK_TABLE_SQL2 =
73     "CREATE TABLE IF NOT EXISTS " + TABLE_NAME3 + "(" \
74     "id INTEGER PRIMARY KEY," \
75     "name asseT ," \
76     "age ASSETs);";
77 
78     const std::string EXTEND_COL_NAME1 = "xxx";
79     const std::string EXTEND_COL_NAME2 = "name";
80     const std::string EXTEND_COL_NAME3 = "age";
81     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET1 = { "name1" };
82     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET2 = { "name" };
83     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET3 = { "height" };
84     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET4 = { "height", "name" };
85     const std::set<std::string> LOCAL_TABLE_TRACKER_NAME_SET5 = { "name", "" };
86     TrackerSchema g_normalSchema1 = {
87         .tableName = TABLE_NAME2, .extendColNames = {EXTEND_COL_NAME2}, .trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2
88     };
89     TrackerSchema g_normalSchema2 = {
90         .tableName = TABLE_NAME2, .extendColNames = {EXTEND_COL_NAME3}, .trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2
91     };
92     TrackerSchema g_normalSchema3 = {
93         .tableName = TABLE_NAME2, .extendColNames = {EXTEND_COL_NAME3}, .trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET4
94     };
95 
CreateMultiTable()96     void CreateMultiTable()
97     {
98         g_db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
99         ASSERT_NE(g_db, nullptr);
100         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
101         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_TABLE_SQL), SQLITE_OK);
102         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
103         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL2), SQLITE_OK);
104     }
105 
BatchInsertTableName2Data(uint64_t num)106     void BatchInsertTableName2Data(uint64_t num)
107     {
108         for (size_t i = 0; i < num; i++) {
109             string sql = "INSERT INTO " + TABLE_NAME2
110                 + " (name, height, photo, asserts, age) VALUES ('Local" + std::to_string(i) +
111                 "', '175.8', 175.88888888888, 'x', '18');";
112             EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
113         }
114     }
115 
BatchUpdateTableName2Data(uint64_t num,const std::set<std::string> & colNames)116     void BatchUpdateTableName2Data(uint64_t num, const std::set<std::string> &colNames)
117     {
118         std::string sql = "UPDATE " + TABLE_NAME2 + " SET ";
119         for (const auto &col: colNames) {
120             sql += col + " = '1',";
121         }
122         sql.pop_back();
123         sql += " where id = ";
124         for (size_t i = 1; i <= num; i++) {
125             EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql + std::to_string(i)), SQLITE_OK);
126         }
127     }
128 
BatchDeleteTableName2Data(uint64_t num)129     void BatchDeleteTableName2Data(uint64_t num)
130     {
131         std::string sql = "DELETE FROM " + TABLE_NAME2 + " WHERE id <= " + std::to_string(num);
132         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
133     }
134 
BatchOperatorTableName2Data(uint64_t num,const std::set<std::string> & colNames)135     void BatchOperatorTableName2Data(uint64_t num, const std::set<std::string> &colNames)
136     {
137         for (int i = 0; i < HALF; i++) {
138             BatchInsertTableName2Data(num);
139         }
140         BatchUpdateTableName2Data(num, colNames);
141         BatchDeleteTableName2Data(num);
142     }
143 
CheckExtendAndCursor(uint64_t num,int start,const std::string & tableName,bool addNum=true)144     void CheckExtendAndCursor(uint64_t num, int start, const std::string &tableName, bool addNum = true)
145     {
146         int index = 0;
147         string querySql = "select json_extract(extend_field, '$.name'), cursor from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName +
148             "_log" + " where data_key <= " + std::to_string(num);
149         sqlite3_stmt *stmt = nullptr;
150         EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
151         while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
152             std::string extendVal;
153             EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
154             ASSERT_NE(num, 0uL);
155             EXPECT_EQ(extendVal, "Local" + std::to_string(index % num));
156             std::string cursorVal;
157             EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
158             auto expectCursor = (++index) + start;
159             auto expectCursorStr = addNum ? std::to_string(num + expectCursor) : std::to_string(expectCursor);
160             EXPECT_EQ(cursorVal, expectCursorStr);
161         }
162         int errCode;
163         SQLiteUtils::ResetStatement(stmt, true, errCode);
164     }
165 
CheckExtendAndCursor(uint64_t num,int start)166     void CheckExtendAndCursor(uint64_t num, int start)
167     {
168         CheckExtendAndCursor(num, start, TABLE_NAME2);
169     }
170 
OpenStore()171     void OpenStore()
172     {
173         if (g_db == nullptr) {
174             g_db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
175             ASSERT_NE(g_db, nullptr);
176         }
177         DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, g_delegate);
178         EXPECT_EQ(status, OK);
179         ASSERT_NE(g_delegate, nullptr);
180     }
181 
CloseStore()182     void CloseStore()
183     {
184         if (g_db != nullptr) {
185             EXPECT_EQ(sqlite3_close_v2(g_db), SQLITE_OK);
186             g_db = nullptr;
187         }
188         if (g_delegate != nullptr) {
189             EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
190             g_delegate = nullptr;
191         }
192     }
193 
CheckDropTableAndReopenDb(bool isDistributed)194     void CheckDropTableAndReopenDb(bool isDistributed)
195     {
196         /**
197          * @tc.steps:step1. SetTrackerTable, init data and drop table
198          * @tc.expected: step1. Return OK.
199          */
200         CreateMultiTable();
201         OpenStore();
202         if (isDistributed) {
203             EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
204         }
205         TrackerSchema schema = g_normalSchema1;
206         EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
207         uint64_t num = 10;
208         BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
209         std::string sql = "drop table if exists " + TABLE_NAME2;
210         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
211         CloseStore();
212 
213         /**
214          * @tc.steps:step2. reopen db, check log table
215          * @tc.expected: step2. Return OK.
216          */
217         OpenStore();
218         sql = "select count(*) from sqlite_master where name = '" + std::string(DBConstant::RELATIONAL_PREFIX) +
219             TABLE_NAME2 + "_log'";
220         EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
221             reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
222 
223         /**
224          * @tc.steps:step3. check tracker schema
225          * @tc.expected: step3. Return OK.
226          */
227         const Key schemaKey(DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY,
228             DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY + strlen(DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY));
229         sql = "SELECT value FROM " + std::string(DBConstant::RELATIONAL_PREFIX) + "metadata WHERE key=?;";
230         sqlite3_stmt *stmt = nullptr;
231         EXPECT_EQ(SQLiteUtils::GetStatement(g_db, sql, stmt), E_OK);
232         EXPECT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, schemaKey, false), E_OK);
233         Value schemaVal;
234         while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
235             SQLiteUtils::GetColumnBlobValue(stmt, 0, schemaVal);
236         }
237         EXPECT_TRUE(schemaVal.size() != 0);
238         int errCode;
239         SQLiteUtils::ResetStatement(stmt, true, errCode);
240         std::string schemaStr;
241         DBCommon::VectorToString(schemaVal, schemaStr);
242         RelationalSchemaObject schemaObject;
243         EXPECT_EQ(schemaObject.ParseFromTrackerSchemaString(schemaStr), E_OK);
244         EXPECT_EQ(schemaObject.GetTrackerTable(TABLE_NAME2).IsEmpty(), true);
245         CloseStore();
246     }
247 
248     class DistributedDBInterfacesRelationalTrackerTableTest : public testing::Test {
249     public:
250         static void SetUpTestCase(void);
251 
252         static void TearDownTestCase(void);
253 
254         void SetUp();
255 
256         void TearDown();
257     };
258 
SetUpTestCase(void)259     void DistributedDBInterfacesRelationalTrackerTableTest::SetUpTestCase(void)
260     {
261         DistributedDBToolsUnitTest::TestDirInit(g_testDir);
262         LOGD("Test dir is %s", g_testDir.c_str());
263         g_dbDir = g_testDir + "/";
264         DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
265     }
266 
TearDownTestCase(void)267     void DistributedDBInterfacesRelationalTrackerTableTest::TearDownTestCase(void)
268     {
269     }
270 
SetUp(void)271     void DistributedDBInterfacesRelationalTrackerTableTest::SetUp(void)
272     {
273         g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
274         ASSERT_TRUE(g_communicatorAggregator != nullptr);
275         RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
276         if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
277             LOGE("rm test db files error.");
278         }
279         DistributedDBToolsUnitTest::PrintTestCaseInfo();
280     }
281 
TearDown(void)282     void DistributedDBInterfacesRelationalTrackerTableTest::TearDown(void)
283     {
284         DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
285         RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
286     }
287 
SetTrackerTableTest(const TrackerSchema & schema,DBStatus expect)288 void SetTrackerTableTest(const TrackerSchema &schema, DBStatus expect)
289 {
290     CreateMultiTable();
291     OpenStore();
292     EXPECT_EQ(g_delegate->SetTrackerTable(schema), expect);
293     CloseStore();
294 }
295 
296 /**
297   * @tc.name: TrackerTableTest001
298   * @tc.desc: Test set tracker table with invalid table name
299   * @tc.type: FUNC
300   * @tc.require:
301   * @tc.author: bty
302   */
303 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest001, TestSize.Level0)
304 {
305     CreateMultiTable();
306     OpenStore();
307     /**
308      * @tc.steps:step1. table name is empty
309      * @tc.expected: step1. Return INVALID_ARGS.
310      */
311     TrackerSchema schema;
312     EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
313 
314     /**
315      * @tc.steps:step2. table name is no exist
316      * @tc.expected: step2. Return NOT_FOUND.
317      */
318     schema.tableName = "xx";
319     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
320 
321     /**
322      * @tc.steps:step3. table name is illegal table name
323      * @tc.expected: step3. Return INVALID_ARGS.
324      */
325     schema.tableName = std::string(DBConstant::SYSTEM_TABLE_PREFIX) + "_1";
326     EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
327     CloseStore();
328 }
329 
330 /**
331   * @tc.name: TrackerTableTest002
332   * @tc.desc: Test set tracker table with empty colNames
333   * @tc.type: FUNC
334   * @tc.require:
335   * @tc.author: bty
336   */
337 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest002, TestSize.Level0)
338 {
339     /**
340      * @tc.steps:step1. trackerColNames is empty
341      * @tc.expected: step1. Return OK.
342      */
343     TrackerSchema schema;
344     schema.tableName = TABLE_NAME1;
345     SetTrackerTableTest(schema, OK);
346 
347     /**
348      * @tc.steps:step2. trackerColNames is empty but extendColName is no exist
349      * @tc.expected: step2. Return OK.
350      */
351     schema.extendColNames = {EXTEND_COL_NAME1};
352     SetTrackerTableTest(schema, SCHEMA_MISMATCH);
353 
354     /**
355      * @tc.steps:step3. param valid but extend name is empty
356      * @tc.expected: step3. Return OK.
357      */
358     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
359     schema.extendColNames = {};
360     SetTrackerTableTest(schema, OK);
361     SetTrackerTableTest(schema, OK);
362 }
363 
364 /**
365   * @tc.name: TrackerTableTest003
366   * @tc.desc: Test set tracker table with invalid col name
367   * @tc.type: FUNC
368   * @tc.require:
369   * @tc.author: bty
370   */
371 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest003, TestSize.Level1)
372 {
373     /**
374      * @tc.steps:step1. tracker col name is no exist
375      * @tc.expected: step1. Return SCHEMA_MISMATCH.
376      */
377     TrackerSchema schema;
378     schema.tableName = TABLE_NAME1;
379     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET1;
380     SetTrackerTableTest(schema, SCHEMA_MISMATCH);
381 
382     /**
383      * @tc.steps:step2. tracker col names contains empty name
384      * @tc.expected: step2. Return INVALID_ARGS.
385      */
386     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET5;
387     SetTrackerTableTest(schema, INVALID_ARGS);
388 
389     /**
390      * @tc.steps:step3. extend name is no exist
391      * @tc.expected: step3. Return SCHEMA_MISMATCH.
392      */
393     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
394     schema.extendColNames = {EXTEND_COL_NAME1};
395     SetTrackerTableTest(schema, SCHEMA_MISMATCH);
396 
397     /**
398      * @tc.steps:step4. extend name is no exist when tracker col name is enpty
399      * @tc.expected: step4. Return SCHEMA_MISMATCH.
400      */
401     schema.trackerColNames.clear();
402     schema.extendColNames = {EXTEND_COL_NAME1};
403     SetTrackerTableTest(schema, SCHEMA_MISMATCH);
404 }
405 
406 /**
407   * @tc.name: TrackerTableTest005
408   * @tc.desc: Test set tracker table in same delegate
409   * @tc.type: FUNC
410   * @tc.require:
411   * @tc.author: bty
412   */
413 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest005, TestSize.Level1)
414 {
415     /**
416      * @tc.steps:step1. SetTrackerTable twice in same delegate
417      * @tc.expected: step1. Return WITH_INVENTORY_DATA for the first time, return OK again
418      */
419     TrackerSchema schema = g_normalSchema1;
420     CreateMultiTable();
421     OpenStore();
422     uint64_t num = 10;
423     BatchInsertTableName2Data(num);
424     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
425     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
426     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
427 
428     /**
429      * @tc.steps:step2. SetTrackerTable again with different schema
430      * @tc.expected: step2. Return OK.
431      */
432     schema = g_normalSchema3;
433     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
434     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
435     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
436 
437     /**
438      * @tc.steps:step3. SetTrackerTable again with different table
439      * @tc.expected: step3. Return OK.
440      */
441     schema.tableName = TABLE_NAME1;
442     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
443     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
444 
445     /**
446      * @tc.steps:step4. unSetTrackerTable
447      * @tc.expected: step4. Return OK.
448      */
449     schema.tableName = TABLE_NAME2;
450     schema.trackerColNames = {};
451     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
452     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
453     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
454     CloseStore();
455 }
456 
457 /**
458   * @tc.name: TrackerTableTest006
459   * @tc.desc: Test set tracker table in diff delegate
460   * @tc.type: FUNC
461   * @tc.require:
462   * @tc.author: bty
463   */
464 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest006, TestSize.Level1)
465 {
466     /**
467      * @tc.steps:step1. SetTrackerTable
468      * @tc.expected: step1. Return OK.
469      */
470     TrackerSchema schema = g_normalSchema1;
471     CreateMultiTable();
472     OpenStore();
473     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
474     uint64_t num = 10;
475     BatchInsertTableName2Data(num);
476     CloseStore();
477 
478     /**
479      * @tc.steps:step2. reopen db and SetTrackerTable
480      * @tc.expected: step2. Return OK.
481      */
482     OpenStore();
483     schema = g_normalSchema2;
484     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
485     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
486     CloseStore();
487 
488     /**
489      * @tc.steps:step3. reopen db and SetTrackerTable with diff table
490      * @tc.expected: step3. Return OK.
491      */
492     OpenStore();
493     schema.tableName = TABLE_NAME1;
494     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
495     CloseStore();
496 
497     /**
498      * @tc.steps:step4. reopen db and unSetTrackerTable
499      * @tc.expected: step4. Return OK.
500      */
501     OpenStore();
502     schema.trackerColNames = {};
503     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
504     CloseStore();
505 }
506 
507 /**
508   * @tc.name: TrackerTableTest007
509   * @tc.desc: Test set tracker table to upgrade inventory data
510   * @tc.type: FUNC
511   * @tc.require:
512   * @tc.author: bty
513   */
514 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest007, TestSize.Level0)
515 {
516     /**
517      * @tc.steps:step1. SetTrackerTable when the db exist data
518      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
519      */
520     uint64_t num = 10;
521     CreateMultiTable();
522     BatchInsertTableName2Data(num);
523     OpenStore();
524     TrackerSchema schema = g_normalSchema3;
525     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
526 
527     /**
528      * @tc.steps:step2. SetTrackerTable again with diff tracker schema
529      * @tc.expected: step2. Return OK.
530      */
531     schema = g_normalSchema1;
532     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
533 
534     /**
535      * @tc.steps:step3. check extend_field and cursor
536      * @tc.expected: step3. Return OK.
537      */
538     CheckExtendAndCursor(num, 0);
539 
540     /**
541      * @tc.steps:step4. update extend field and check
542      * @tc.expected: step4. Return OK.
543      */
544     EXPECT_EQ(g_delegate->SetTrackerTable(g_normalSchema3), OK);
545     std::string sql = "UPDATE " + TABLE_NAME2 + " SET age='666'";
546     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
547     sql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
548         " where json_extract(extend_field, '$.age')=666;";
549     char *errmsg;
550     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
551         reinterpret_cast<void *>(num), &errmsg), SQLITE_OK);
552     CloseStore();
553 }
554 
555 /**
556   * @tc.name: TrackerTableTest008
557   * @tc.desc: Test set tracker table to check extend_field and cursor
558   * @tc.type: FUNC
559   * @tc.require:
560   * @tc.author: bty
561   */
562 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest008, TestSize.Level0)
563 {
564     /**
565      * @tc.steps:step1. SetTrackerTable on table2
566      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
567      */
568     uint64_t num = 10;
569     CreateMultiTable();
570     BatchInsertTableName2Data(num);
571     OpenStore();
572     TrackerSchema schema = g_normalSchema1;
573     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
574 
575     /**
576      * @tc.steps:step2. Update non tracker columns,then check extend_field and cursor
577      * @tc.expected: step2. Return OK.
578      */
579     uint64_t updateNum = 2;
580     BatchUpdateTableName2Data(updateNum, LOCAL_TABLE_TRACKER_NAME_SET3);
581     int index = 0;
582     string querySql = "select json_extract(extend_field, '$.name'), cursor from " +
583        DBCommon::GetLogTableName(TABLE_NAME2) + " where data_key <= " + std::to_string(updateNum);
584     sqlite3_stmt *stmt = nullptr;
585     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
586     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
587         std::string extendVal;
588         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
589         EXPECT_EQ(extendVal, "Local" + std::to_string(index % num));
590         std::string cursorVal;
591         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
592         EXPECT_EQ(cursorVal, std::to_string(++index));
593     }
594     int errCode;
595     SQLiteUtils::ResetStatement(stmt, true, errCode);
596 
597     /**
598      * @tc.steps:step3. Update tracker columns,then check extend_field and cursor
599      * @tc.expected: step3. Return OK.
600      */
601     BatchUpdateTableName2Data(updateNum, LOCAL_TABLE_TRACKER_NAME_SET2);
602     stmt = nullptr;
603     index = 0;
604     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
605     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
606         std::string extendVal;
607         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
608         EXPECT_EQ(extendVal, "1");
609         std::string cursorVal;
610         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
611         EXPECT_EQ(cursorVal, std::to_string(num + (++index)));
612     }
613     SQLiteUtils::ResetStatement(stmt, true, errCode);
614     CloseStore();
615 }
616 
617 /**
618   * @tc.name: TrackerTableTest009
619   * @tc.desc: Test set tracker table to check extend_field and cursor after delete
620   * @tc.type: FUNC
621   * @tc.require:
622   * @tc.author: bty
623   */
624 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest009, TestSize.Level0)
625 {
626     /**
627      * @tc.steps:step1. SetTrackerTable on table2
628      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
629      */
630     uint64_t num = 10;
631     CreateMultiTable();
632     BatchInsertTableName2Data(num);
633     OpenStore();
634     TrackerSchema schema = g_normalSchema1;
635     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
636 
637     /**
638      * @tc.steps:step2. select extend_field and cursor after delete
639      * @tc.expected: step2. Return OK.
640      */
641     BatchDeleteTableName2Data(num);
642     CheckExtendAndCursor(num, 0);
643 
644     /**
645      * @tc.steps:step3. Set tracker, where extendColNames changed, then check the extend_field of deleted data
646      * @tc.expected: step3. Return OK.
647      */
648     EXPECT_EQ(g_delegate->SetTrackerTable(g_normalSchema2), OK);
649     CheckExtendAndCursor(num, 0);
650 
651     /**
652      * @tc.steps:step4. Set tracker, where extendColNames no changed, then check the extend_field of deleted data
653      * @tc.expected: step4. Return OK.
654      */
655     EXPECT_EQ(g_delegate->SetTrackerTable(g_normalSchema3), OK);
656     CheckExtendAndCursor(num, 0);
657     CloseStore();
658 }
659 
660 /**
661   * @tc.name: TrackerTableTest010
662   * @tc.desc: Test set tracker table after unSetTrackerTable
663   * @tc.type: FUNC
664   * @tc.require:
665   * @tc.author: bty
666   */
667 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest010, TestSize.Level0)
668 {
669     /**
670      * @tc.steps:step1. SetTrackerTable on table2
671      * @tc.expected: step1. Return OK.
672      */
673     CreateMultiTable();
674     OpenStore();
675     TrackerSchema schema = g_normalSchema1;
676     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
677 
678     /**
679      * @tc.steps:step2. unSetTrackerTable
680      * @tc.expected: step2. Return OK.
681      */
682     schema.trackerColNames = {};
683     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
684 
685     /**
686      * @tc.steps:step3. SetTrackerTable again
687      * @tc.expected: step3. Return OK.
688      */
689     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
690     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
691 
692     /**
693      * @tc.steps:step4. operator data
694      * @tc.expected: step4. Return OK.
695      */
696     uint64_t num = 10;
697     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
698     CloseStore();
699 }
700 
701 /**
702   * @tc.name: TrackerTableTest011
703   * @tc.desc: Test CreateDistributedTable after set tracker table
704   * @tc.type: FUNC
705   * @tc.require:
706   * @tc.author: bty
707   */
708 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest011, TestSize.Level1)
709 {
710     /**
711      * @tc.steps:step1. SetTrackerTable on table2
712      * @tc.expected: step1. Return OK.
713      */
714     CreateMultiTable();
715     OpenStore();
716     TrackerSchema schema = g_normalSchema1;
717     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
718 
719     /**
720      * @tc.steps:step2. CreateDistributedTable on table2 and insert data
721      * @tc.expected: step2. Return OK.
722      */
723     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
724     uint64_t num = 10;
725     BatchInsertTableName2Data(num);
726 
727     /**
728      * @tc.steps:step3. CreateDistributedTable on table2 again, but schema not change
729      * @tc.expected: step3. Return OK.
730      */
731     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
732     CheckExtendAndCursor(num, -num);
733 
734     /**
735      * @tc.steps:step4. operator data on table2
736      * @tc.expected: step4. Return OK.
737      */
738     std::string sql = "ALTER TABLE " + TABLE_NAME2 + " ADD COLUMN xxx INT";
739     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, sql), E_OK);
740     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
741     CheckExtendAndCursor(num, 0);
742 
743     /**
744      * @tc.steps:step5. unSetTrackerTable
745      * @tc.expected: step5. Return OK.
746      */
747     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
748     schema.trackerColNames = {};
749     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
750 
751     /**
752      * @tc.steps:step6. operator data on table2
753      * @tc.expected: step6. Return OK.
754      */
755     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
756     CloseStore();
757 }
758 
759 /**
760   * @tc.name: TrackerTableTest012
761   * @tc.desc: Test CreateDistributedTable after set tracker table
762   * @tc.type: FUNC
763   * @tc.require:
764   * @tc.author: bty
765   */
766 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest012, TestSize.Level1)
767 {
768     /**
769      * @tc.steps:step1. SetTrackerTable on table2
770      * @tc.expected: step1. Return OK.
771      */
772     CreateMultiTable();
773     OpenStore();
774     TrackerSchema schema = g_normalSchema1;
775     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
776 
777     /**
778      * @tc.steps:step2. CreateDistributedTable on table2 without data
779      * @tc.expected: step2. Return OK.
780      */
781     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
782 
783     /**
784      * @tc.steps:step3. CreateDistributedTable on table1
785      * @tc.expected: step3. Return OK.
786      */
787     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME1, CLOUD_COOPERATION), DBStatus::OK);
788 
789     /**
790      * @tc.steps:step4. operator data on table2
791      * @tc.expected: step4. Return OK.
792      */
793     uint64_t num = 10;
794     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
795 
796     /**
797      * @tc.steps:step5. unSetTrackerTable
798      * @tc.expected: step5. Return OK.
799      */
800     schema.trackerColNames = {};
801     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
802 
803     /**
804      * @tc.steps:step6. operator data on table2
805      * @tc.expected: step6. Return OK.
806      */
807     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
808     CloseStore();
809 }
810 
811 /**
812   * @tc.name: TrackerTableTest013
813   * @tc.desc: Test CreateDistributedTable after clean table data
814   * @tc.type: FUNC
815   * @tc.require:
816   * @tc.author: bty
817   */
818 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest013, TestSize.Level0)
819 {
820     /**
821      * @tc.steps:step1. init data and SetTrackerTable on table2
822      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
823      */
824     uint64_t num = 10;
825     CreateMultiTable();
826     BatchInsertTableName2Data(num);
827     OpenStore();
828     TrackerSchema schema = g_normalSchema1;
829     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
830 
831     /**
832      * @tc.steps:step2. CreateDistributedTable on table2
833      * @tc.expected: step2. Return NOT_SUPPORT.
834      */
835     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
836 
837     /**
838      * @tc.steps:step3. delete all data but keep the log , then CreateDistributedTable
839      * @tc.expected: step3. Return OK.
840      */
841     BatchDeleteTableName2Data(num);
842     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
843     BatchInsertTableName2Data(num);
844 
845     /**
846      * @tc.steps:step4. Set tracker, where extendColNames changed, then check the extend_field of deleted data
847      * @tc.expected: step4. Return OK.
848      */
849     EXPECT_EQ(g_delegate->SetTrackerTable(g_normalSchema2), OK);
850     CheckExtendAndCursor(num, 0);
851     CloseStore();
852 }
853 
854 /**
855   * @tc.name: TrackerTableTest014
856   * @tc.desc: Test SetTrackerTable after CreateDistributedTable
857   * @tc.type: FUNC
858   * @tc.require:
859   * @tc.author: bty
860   */
861 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest014, TestSize.Level1)
862 {
863     /**
864      * @tc.steps:step1. CreateDistributedTable on table2
865      * @tc.expected: step1. Return OK.
866      */
867     CreateMultiTable();
868     OpenStore();
869     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
870 
871     /**
872      * @tc.steps:step2. SetTrackerTable on table2
873      * @tc.expected: step2. Return OK.
874      */
875     TrackerSchema schema = g_normalSchema1;
876     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
877 
878     /**
879      * @tc.steps:step3. operator data and check extend_filed and cursor
880      * @tc.expected: step3. Return OK.
881      */
882     uint64_t num = 10;
883     int begin = -10;
884     BatchInsertTableName2Data(num);
885     CheckExtendAndCursor(num, begin);
886     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
887 
888     /**
889      * @tc.steps:step4. unSetTrackerTable
890      * @tc.expected: step4. Return OK.
891      */
892     schema.trackerColNames = {};
893     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
894     CloseStore();
895 }
896 
897 /**
898   * @tc.name: TrackerTableTest015
899   * @tc.desc: Test operator data on Distributed tracker table
900   * @tc.type: FUNC
901   * @tc.require:
902   * @tc.author: bty
903   */
904 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest015, TestSize.Level1)
905 {
906     /**
907      * @tc.steps:step1. CreateDistributedTable on table2
908      * @tc.expected: step1. Return OK.
909      */
910     CreateMultiTable();
911     OpenStore();
912     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
913 
914     /**
915      * @tc.steps:step2. operator data
916      * @tc.expected: step2. Return OK.
917      */
918     uint64_t num = 10;
919     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
920 
921     /**
922      * @tc.steps:step3. SetTrackerTable on table2
923      * @tc.expected: step3. Return WITH_INVENTORY_DATA.
924      */
925     TrackerSchema schema = g_normalSchema1;
926     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
927     string querySql = "select json_extract(extend_field, '$.name') from " + DBCommon::GetLogTableName(TABLE_NAME2) +
928         " where data_key = 15;";
929     sqlite3_stmt *stmt = nullptr;
930     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
931     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
932         std::string extendVal;
933         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
934         EXPECT_EQ(extendVal, "Local4");
935     }
936     int errCode;
937     SQLiteUtils::ResetStatement(stmt, true, errCode);
938 
939     /**
940      * @tc.steps:step4. operator data
941      * @tc.expected: step4. Return OK.
942      */
943     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
944     CloseStore();
945 }
946 
947 /**
948   * @tc.name: TrackerTableTest016
949   * @tc.desc: Test operator data on tracker Distributed table
950   * @tc.type: FUNC
951   * @tc.require:
952   * @tc.author: bty
953   */
954 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest016, TestSize.Level1)
955 {
956     /**
957      * @tc.steps:step1. SetTrackerTable on table2
958      * @tc.expected: step1. Return OK.
959      */
960     CreateMultiTable();
961     OpenStore();
962     TrackerSchema schema = g_normalSchema1;
963     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
964 
965     /**
966      * @tc.steps:step2. reopen store and create distributed table
967      * @tc.expected: step2. Return OK.
968      */
969     CloseStore();
970     OpenStore();
971     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
972 
973     /**
974      * @tc.steps:step3. operator data
975      * @tc.expected: step3. Return OK.
976      */
977     uint64_t num = 10;
978     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
979     CloseStore();
980 }
981 
982 /**
983   * @tc.name: TrackerTableTest017
984   * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
985   * @tc.type: FUNC
986   * @tc.require:
987   * @tc.author: bty
988   */
989 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest017, TestSize.Level1)
990 {
991     /**
992      * @tc.steps:step1. SetTrackerTable on table2
993      * @tc.expected: step1. Return OK.
994      */
995     CreateMultiTable();
996     OpenStore();
997     TrackerSchema schema = g_normalSchema1;
998     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
999 
1000     /**
1001      * @tc.steps:step2. Create DEVICE_COOPERATION DistributedTable
1002      * @tc.expected: step2. Return NOT_SUPPORT.
1003      */
1004     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::OK);
1005 
1006     /**
1007      * @tc.steps:step3. operator data on table2
1008      * @tc.expected: step3. Return OK.
1009      */
1010     uint64_t num = 10;
1011     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1012 
1013     /**
1014      * @tc.steps:step4. unSetTrackerTable
1015      * @tc.expected: step4. Return OK.
1016      */
1017     schema.trackerColNames = {};
1018     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1019 
1020     /**
1021      * @tc.steps:step5. There is still data in the table
1022      * @tc.expected: step5. Return NOT_SUPPORT.
1023      */
1024     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), OK);
1025 
1026     /**
1027      * @tc.steps:step6. clear all data and create DEVICE_COOPERATION table
1028      * @tc.expected: step6. Return OK.
1029      */
1030     BatchDeleteTableName2Data(num + num);
1031     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), OK);
1032 
1033     /**
1034      * @tc.steps:step7. operator data on table2
1035      * @tc.expected: step7. Return OK.
1036      */
1037     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1038     CloseStore();
1039 }
1040 
1041 /**
1042   * @tc.name: TrackerTableTest018
1043   * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
1044   * @tc.type: FUNC
1045   * @tc.require:
1046   * @tc.author: bty
1047   */
1048 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest018, TestSize.Level1)
1049 {
1050     /**
1051      * @tc.steps:step1. Create DEVICE_COOPERATION DistributedTable
1052      * @tc.expected: step1. Return OK.
1053      */
1054     CreateMultiTable();
1055     OpenStore();
1056     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::OK);
1057 
1058     /**
1059      * @tc.steps:step2. SetTrackerTable on table2
1060      * @tc.expected: step2. Return OK.
1061      */
1062     TrackerSchema schema = g_normalSchema1;
1063     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1064 
1065     /**
1066      * @tc.steps:step3. operator data on table2
1067      * @tc.expected: step3. Return OK.
1068      */
1069     uint64_t num = 10;
1070     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1071 
1072     /**
1073      * @tc.steps:step4. unSetTrackerTable
1074      * @tc.expected: step4. Return OK.
1075      */
1076     schema.trackerColNames = {};
1077     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1078 
1079     /**
1080      * @tc.steps:step5. operator data on table2
1081      * @tc.expected: step5. Return OK.
1082      */
1083     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1084     CloseStore();
1085 }
1086 
1087 /**
1088   * @tc.name: TrackerTableTest019
1089   * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
1090   * @tc.type: FUNC
1091   * @tc.require:
1092   * @tc.author: bty
1093   */
1094 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest019, TestSize.Level0)
1095 {
1096     /**
1097      * @tc.steps:step1. SetTrackerTable
1098      * @tc.expected: step1. Return OK.
1099      */
1100     CreateMultiTable();
1101     OpenStore();
1102     TrackerSchema schema = g_normalSchema1;
1103     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1104 
1105     /**
1106      * @tc.steps:step2. CleanTrackerData with table name no exist
1107      * @tc.expected: step2. Return DB_ERROR.
1108      */
1109     uint64_t num = 10;
1110     BatchInsertTableName2Data(num);
1111     BatchDeleteTableName2Data(num / HALF);
1112     EXPECT_EQ(g_delegate->CleanTrackerData("xx", num), DB_ERROR);
1113 
1114     /**
1115      * @tc.steps:step3. CleanTrackerData with empty table name
1116      * @tc.expected: step3. Return INVALID_ARGS.
1117      */
1118     EXPECT_EQ(g_delegate->CleanTrackerData("", num), INVALID_ARGS);
1119 
1120     /**
1121      * @tc.steps:step4. CleanTrackerData
1122      * @tc.expected: step4. Return OK.
1123      */
1124     EXPECT_EQ(g_delegate->CleanTrackerData(TABLE_NAME2, num + (num / HALF)), OK);
1125     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
1126         " where extend_field is NULL;";
1127     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1128         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1129     CloseStore();
1130 }
1131 
1132 /**
1133   * @tc.name: TrackerTableTest020
1134   * @tc.desc: Test drop and rebuild table in same delegate
1135   * @tc.type: FUNC
1136   * @tc.require:
1137   * @tc.author: bty
1138   */
1139 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest020, TestSize.Level0)
1140 {
1141     /**
1142      * @tc.steps:step1. SetTrackerTable and init data
1143      * @tc.expected: step1. Return OK.
1144      */
1145     CreateMultiTable();
1146     OpenStore();
1147     TrackerSchema schema = g_normalSchema1;
1148     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1149     uint64_t num = 10;
1150     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1151 
1152     /**
1153      * @tc.steps:step2. drop and rebuild table, then SetTrackerTable
1154      * @tc.expected: step2. Return OK.
1155      */
1156     std::string sql = "drop table if exists " + TABLE_NAME2;
1157     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1158     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
1159     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1160 
1161     /**
1162      * @tc.steps:step3. check the extend_field and cursor is null
1163      * @tc.expected: step3. Return OK.
1164      */
1165     sql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
1166         " where extend_field is NULL " + " AND cursor is NULL";
1167     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1168         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1169 
1170     /**
1171      * @tc.steps:step4. set diff schema, check the extend_field and cursor is null
1172      * @tc.expected: step4. Return OK.
1173      */
1174     schema.extendColNames = {EXTEND_COL_NAME3};
1175     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1176     sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 +
1177         "_log where extend_field is NULL " + " AND cursor is NULL";
1178     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1179         reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1180     CloseStore();
1181 }
1182 
1183 /**
1184   * @tc.name: TrackerTableTest021
1185   * @tc.desc: Test non distributed table delete table and reopen db
1186   * @tc.type: FUNC
1187   * @tc.require:
1188   * @tc.author: bty
1189   */
1190 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest021, TestSize.Level0)
1191 {
1192     CheckDropTableAndReopenDb(false);
1193 }
1194 
1195 /**
1196   * @tc.name: TrackerTableTest022
1197   * @tc.desc: Test distributed table delete table and reopen db
1198   * @tc.type: FUNC
1199   * @tc.require:
1200   * @tc.author: bty
1201   */
1202 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest022, TestSize.Level1)
1203 {
1204     CheckDropTableAndReopenDb(true);
1205 }
1206 
1207 /**
1208   * @tc.name: TrackerTableTest023
1209   * @tc.desc: Test drop and rebuild table,then insert data and set tracker table
1210   * @tc.type: FUNC
1211   * @tc.require:
1212   * @tc.author: bty
1213   */
1214 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest023, TestSize.Level0)
1215 {
1216     /**
1217      * @tc.steps:step1. SetTrackerTable and init data
1218      * @tc.expected: step1. Return OK.
1219      */
1220     CreateMultiTable();
1221     OpenStore();
1222     TrackerSchema schema = g_normalSchema1;
1223     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1224     uint64_t num = 10;
1225     BatchInsertTableName2Data(num);
1226     BatchDeleteTableName2Data(num);
1227 
1228     /**
1229      * @tc.steps:step2. drop and rebuild table,then insert data and set tracker table
1230      * @tc.expected: step2. Return OK.
1231      */
1232     std::string sql = "drop table if exists " + TABLE_NAME2;
1233     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1234     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
1235     BatchInsertTableName2Data(num);
1236     schema = g_normalSchema2;
1237     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1238 
1239     /**
1240      * @tc.steps:step3. query cursor
1241      * @tc.expected: step3. Return OK.
1242      */
1243     string querySql = "select cursor from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log";
1244     sqlite3_stmt *stmt = nullptr;
1245     int index = 20;
1246     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
1247     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1248         std::string cursorVal;
1249         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, cursorVal), E_OK);
1250         EXPECT_EQ(cursorVal, std::to_string(++index));
1251     }
1252     int errCode;
1253     SQLiteUtils::ResetStatement(stmt, true, errCode);
1254     CloseStore();
1255 }
1256 
1257 /**
1258   * @tc.name: TrackerTableTest024
1259   * @tc.desc: Test set tracker table and set extend col as the asset type
1260   * @tc.type: FUNC
1261   * @tc.require:
1262   * @tc.author: bty
1263   */
1264 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest024, TestSize.Level0)
1265 {
1266     CreateMultiTable();
1267     OpenStore();
1268     TrackerSchema schema;
1269     schema.tableName = TABLE_NAME3;
1270     schema.extendColNames = {EXTEND_COL_NAME3};
1271     schema.trackerColNames = { EXTEND_COL_NAME3 };
1272     EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
1273     CloseStore();
1274 }
1275 
1276 /**
1277   * @tc.name: TrackerTableTest025
1278   * @tc.desc: Test CreateDistributedTable after insert data and set tracker table
1279   * @tc.type: FUNC
1280   * @tc.require:
1281   * @tc.author: lijun
1282   */
1283 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest025, TestSize.Level0)
1284 {
1285     CreateMultiTable();
1286     OpenStore();
1287     uint64_t num = 10;
1288 
1289     /**
1290      * @tc.steps:step1. insert data
1291      * @tc.expected: step1. OK.
1292      */
1293     BatchInsertTableName2Data(num);
1294     TrackerSchema schema = g_normalSchema1;
1295 
1296     /**
1297      * @tc.steps:step2. SetTrackerTable on table2
1298      * @tc.expected: step2. Return WITH_INVENTORY_DATA.
1299      */
1300     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
1301 
1302     /**
1303      * @tc.steps:step3. check cursor before and after CreateDistributedTable
1304      * @tc.expected: step3. Cursor is no change.
1305      */
1306     CheckExtendAndCursor(num, -num);
1307     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
1308     CheckExtendAndCursor(num, -num);
1309     CloseStore();
1310 }
1311 
1312 /**
1313   * @tc.name: ExecuteSql001
1314   * @tc.desc: Test ExecuteSql with invalid param
1315   * @tc.type: FUNC
1316   * @tc.require:
1317   * @tc.author: bty
1318   */
1319 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql001, TestSize.Level0)
1320 {
1321     /**
1322      * @tc.steps:step1. init db data
1323      * @tc.expected: step1. Return OK.
1324      */
1325     uint64_t num = 10;
1326     CreateMultiTable();
1327     BatchInsertTableName2Data(num);
1328     OpenStore();
1329 
1330     /**
1331      * @tc.steps:step2. sql is empty
1332      * @tc.expected: step2. Return INVALID_ARGS.
1333      */
1334     SqlCondition condition;
1335     std::vector<VBucket> records;
1336     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1337 
1338     /**
1339      * @tc.steps:step3. SQL does not have placeholders but there are bind args present
1340      * @tc.expected: step3. Return INVALID_ARGS.
1341      */
1342     std::string querySql = "select * from " + TABLE_NAME2 + " where id = 1;";
1343     condition.sql = querySql;
1344     condition.bindArgs = {"1"};
1345     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1346 
1347     /**
1348      * @tc.steps:step4. More SQL binding parameters than SQL placeholders
1349      * @tc.expected: step4. Return INVALID_ARGS.
1350      */
1351     querySql = "select * from " + TABLE_NAME2 + " where id > ?;";
1352     condition.sql = querySql;
1353     condition.bindArgs = {};
1354     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1355 
1356     /**
1357      * @tc.steps:step5. More SQL placeholders than SQL binding parameters
1358      * @tc.expected: step5. Return INVALID_ARGS.
1359      */
1360     condition.bindArgs = {"1", "2"};
1361     condition.sql = querySql;
1362     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1363     CloseStore();
1364 }
1365 
1366 /**
1367   * @tc.name: ExecuteSql002
1368   * @tc.desc: Test ExecuteSql and check query result
1369   * @tc.type: FUNC
1370   * @tc.require:
1371   * @tc.author: bty
1372   */
1373 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql002, TestSize.Level0)
1374 {
1375     /**
1376      * @tc.steps:step1. init db data
1377      * @tc.expected: step1. Return OK.
1378      */
1379     uint64_t num = 10;
1380     CreateMultiTable();
1381     BatchInsertTableName2Data(num);
1382     OpenStore();
1383 
1384     /**
1385      * @tc.steps:step2. execute query sql and check result
1386      * @tc.expected: step2. Return OK.
1387      */
1388     int64_t beginId = 1;
1389     SqlCondition condition;
1390     std::vector<VBucket> records;
1391     std::string querySql = "select * from " + TABLE_NAME2 + " where id > ?;";
1392     condition.sql = querySql;
1393     condition.bindArgs = {beginId};
1394     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1395     EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1396     for (const VBucket &item: records) {
1397         auto iter = item.find("id");
1398         ASSERT_NE(iter, item.end());
1399         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<int64_t>);
1400         EXPECT_EQ(std::get<int64_t>(iter->second), beginId + 1);
1401 
1402         iter = item.find("name");
1403         ASSERT_NE(iter, item.end());
1404         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<std::string>);
1405         EXPECT_EQ(std::get<std::string>(iter->second), "Local" + std::to_string(beginId));
1406 
1407         iter = item.find("height");
1408         ASSERT_NE(iter, item.end());
1409         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<double>);
1410         EXPECT_EQ(std::get<double>(iter->second), 175.8);
1411 
1412         iter = item.find("photo");
1413         ASSERT_NE(iter, item.end());
1414         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<double>);
1415         EXPECT_EQ(std::get<double>(iter->second), 175.88888888888);
1416 
1417         iter = item.find("asserts");
1418         ASSERT_NE(iter, item.end());
1419         ASSERT_TRUE(iter->second.index() == TYPE_INDEX<std::string>);
1420         EXPECT_EQ(std::get<std::string>(iter->second), "x");
1421         beginId++;
1422     }
1423     CloseStore();
1424 }
1425 
1426 /**
1427   * @tc.name: ExecuteSql003
1428   * @tc.desc: Test ExecuteSql and check update and delete result
1429   * @tc.type: FUNC
1430   * @tc.require:
1431   * @tc.author: bty
1432   */
1433 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql003, TestSize.Level0)
1434 {
1435     /**
1436      * @tc.steps:step1. init db data
1437      * @tc.expected: step1. Return OK.
1438      */
1439     uint64_t num = 10;
1440     CreateMultiTable();
1441     BatchInsertTableName2Data(num);
1442     OpenStore();
1443 
1444     /**
1445      * @tc.steps:step2. update sql
1446      * @tc.expected: step2. Return OK.
1447      */
1448     int64_t beginId = 1;
1449     SqlCondition condition;
1450     std::vector<VBucket> records;
1451     std::string updateSql = "update " + TABLE_NAME2 + " set age = 3 where id = ?;";
1452     condition.sql = updateSql;
1453     condition.bindArgs = {beginId};
1454     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1455     EXPECT_EQ(records.size(), 0u);
1456 
1457     std::string delSql = "delete from " + TABLE_NAME2 + " where id = ?;";
1458     condition.sql = delSql;
1459     condition.bindArgs = {beginId + 1};
1460     std::vector<VBucket> records2;
1461     EXPECT_EQ(g_delegate->ExecuteSql(condition, records2), OK);
1462     EXPECT_EQ(records2.size(), 0u);
1463 
1464     string insSql = "INSERT INTO " + TABLE_NAME2 +
1465         " (name, height, photo, asserts, age) VALUES ('Local" + std::to_string(num + 1) +
1466         "', '175.8', '0', 'x', ?);";
1467     condition.sql = insSql;
1468     condition.bindArgs = {beginId};
1469     std::vector<VBucket> records3;
1470     EXPECT_EQ(g_delegate->ExecuteSql(condition, records3), OK);
1471     EXPECT_EQ(records3.size(), 0u);
1472     CloseStore();
1473 }
1474 
1475 /**
1476   * @tc.name: ExecuteSql004
1477   * @tc.desc: Test ExecuteSql after SetTrackerTable
1478   * @tc.type: FUNC
1479   * @tc.require:
1480   * @tc.author: bty
1481   */
1482 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql004, TestSize.Level0)
1483 {
1484     /**
1485      * @tc.steps:step1. SetTrackerTable
1486      * @tc.expected: step1. Return OK.
1487      */
1488     CreateMultiTable();
1489     OpenStore();
1490     TrackerSchema schema = g_normalSchema1;
1491     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1492 
1493     /**
1494      * @tc.steps:step2. batch insert
1495      * @tc.expected: step2. Return OK.
1496      */
1497     uint64_t num = 10;
1498     BatchInsertTableName2Data(num);
1499 
1500     /**
1501      * @tc.steps:step3. execute query sql and check result
1502      * @tc.expected: step3. Return OK.
1503      */
1504     int64_t begin = 0;
1505     SqlCondition condition;
1506     std::vector<VBucket> records;
1507     std::string querySql = "select " + TABLE_NAME2 + ".* from " + TABLE_NAME2 + " join ";
1508     querySql += std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" + " as a on " + TABLE_NAME2 +
1509         "._rowid_ = ";
1510     querySql += "a.data_key where a.cursor > ?;";
1511     condition.sql = querySql;
1512     condition.bindArgs = {begin};
1513     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1514     EXPECT_EQ(records.size(), num);
1515 
1516     /**
1517      * @tc.steps:step4. update
1518      * @tc.expected: step4. Return OK.
1519      */
1520     std::string updateSql = "update " + TABLE_NAME2 + " set name = '3' where _rowid_ <= 5;";
1521     condition.sql = updateSql;
1522     condition.bindArgs = {};
1523     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1524 
1525     /**
1526      * @tc.steps:step5. query after updating
1527      * @tc.expected: step5. Return OK.
1528      */
1529     records.clear();
1530     begin = 10;
1531     condition.sql = querySql;
1532     condition.bindArgs = {begin};
1533     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1534     EXPECT_EQ(records.size(), 5u); // 5 is the num of update
1535     CloseStore();
1536 }
1537 
1538 /**
1539   * @tc.name: ExecuteSql005
1540   * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1541   * @tc.type: FUNC
1542   * @tc.require:
1543   * @tc.author: bty
1544   */
1545 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql005, TestSize.Level0)
1546 {
1547     /**
1548      * @tc.steps:step1. init db data
1549      * @tc.expected: step1. Return OK.
1550      */
1551     uint64_t num = 10;
1552     CreateMultiTable();
1553     BatchInsertTableName2Data(num);
1554     OpenStore();
1555 
1556     /**
1557      * @tc.steps:step2. execute query sql but the table is no exist
1558      * @tc.expected: step2. Return DB_ERROR.
1559      */
1560     int64_t beginId = 1;
1561     SqlCondition condition;
1562     std::vector<VBucket> records;
1563     std::string querySql = "select * from " + TABLE_NAME2 + " where id > 1;";
1564     querySql += "select _rowid_ from " + TABLE_NAME2 + " where id = 1;";
1565     condition.sql = querySql;
1566     condition.bindArgs = {};
1567     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1568     EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1569 
1570     /**
1571      * @tc.steps:step3. execute multi query sql and the num of bindArgs is greater than the first sql
1572      * @tc.expected: step3. Return INVALID_ARGS.
1573      */
1574     records = {};
1575     std::string querySql2 = "select * from " + TABLE_NAME2 + " where id > ?;";
1576     querySql2 += "select _rowid_ from " + TABLE_NAME2 + " where id = ?;";
1577     condition.sql = querySql2;
1578     condition.bindArgs = {beginId, beginId};
1579     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1580     EXPECT_EQ(records.size(), 0u);
1581 
1582     /**
1583      * @tc.steps:step4. execute multi query sql and the num of bindArgs is equal to the first sql
1584      * @tc.expected: step4. Return OK.
1585      */
1586     records = {};
1587     condition.bindArgs = {beginId};
1588     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1589     EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1590     CloseStore();
1591 }
1592 
1593 /**
1594   * @tc.name: ExecuteSql006
1595   * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1596   * @tc.type: FUNC
1597   * @tc.require:
1598   * @tc.author: bty
1599   */
1600 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql006, TestSize.Level0)
1601 {
1602     /**
1603      * @tc.steps:step1. init db data
1604      * @tc.expected: step1. Return OK.
1605      */
1606     uint64_t num = 10;
1607     CreateMultiTable();
1608     BatchInsertTableName2Data(num);
1609     OpenStore();
1610 
1611     /**
1612      * @tc.steps:step2. execute multi update sql
1613      * @tc.expected: step2. Return OK.
1614      */
1615     SqlCondition condition;
1616     std::vector<VBucket> records;
1617     std::string updateSql = "update " + TABLE_NAME2 + " SET age = 100; ";
1618     updateSql += "update " + TABLE_NAME2 + " SET age = 50;";
1619     condition.sql = updateSql;
1620     condition.bindArgs = {};
1621     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1622 
1623     /**
1624      * @tc.steps:step3. execute query sql where age is 100
1625      * @tc.expected: step3. Return OK.
1626      */
1627     records = {};
1628     std::string querySql = "select * from " + TABLE_NAME2 + " where age = 100;";
1629     condition.sql = querySql;
1630     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1631     EXPECT_EQ(records.size(), num);
1632 
1633     /**
1634      * @tc.steps:step4. execute update sql and query sql
1635      * @tc.expected: step4. Return OK.
1636      */
1637     updateSql = "update " + TABLE_NAME2 + " SET age = 88; ";
1638     updateSql += "select * from " + TABLE_NAME2;
1639     condition.sql = updateSql;
1640     condition.bindArgs = {};
1641     records = {};
1642     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1643     EXPECT_EQ(records.size(), 0u);
1644 
1645     /**
1646      * @tc.steps:step5. execute multi delete sql
1647      * @tc.expected: step5. Return OK.
1648      */
1649     records = {};
1650     std::string delSql = "DELETE FROM " + TABLE_NAME2 + " WHERE age = 100; ";
1651     delSql += "DELETE FROM " + TABLE_NAME2 + " WHERE age = 88;";
1652     condition.sql = delSql;
1653     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1654 
1655     /**
1656      * @tc.steps:step6. execute query sql where age is 100
1657      * @tc.expected: step6. Return OK.
1658      */
1659     records = {};
1660     condition.sql = "select * from " + TABLE_NAME2 + " where age = 88;";
1661     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1662     EXPECT_EQ(records.size(), num);
1663     CloseStore();
1664 }
1665 
1666 /**
1667   * @tc.name: ExecuteSql006
1668   * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1669   * @tc.type: FUNC
1670   * @tc.require:
1671   * @tc.author: bty
1672   */
1673 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql007, TestSize.Level0)
1674 {
1675     /**
1676      * @tc.steps:step1. init db data
1677      * @tc.expected: step1. Return OK.
1678      */
1679     uint64_t num = 10;
1680     CreateMultiTable();
1681     BatchInsertTableName2Data(num);
1682     OpenStore();
1683 
1684     /**
1685      * @tc.steps:step2. ExecuteSql with transaction
1686      * @tc.expected: step2. Return OK.
1687      */
1688     SqlCondition condition;
1689     std::vector<VBucket> records;
1690     condition.sql = "BEGIN";
1691     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1692     condition.sql = "COMMIT;";
1693     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1694     condition.sql = "BEGIN";
1695     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1696     condition.sql = "ROLLBACK;";
1697     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1698     condition.sql = "BEGIN TRANSACTION;";
1699     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1700     condition.sql = "END TRANSACTION;";
1701     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1702     condition.sql = "BEGIN IMMEDIATE TRANSACTION;";
1703     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1704     condition.sql = "COMMIT;";
1705     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1706 
1707     /**
1708      * @tc.steps:step3. ExecuteSql with attach and detach
1709      * @tc.expected: step3. Return OK.
1710      */
1711     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID2 + DB_SUFFIX);
1712     EXPECT_NE(db, nullptr);
1713     condition.sql = "ATTACH DATABASE '" + g_dbDir + STORE_ID2 + DB_SUFFIX + "' AS TEST";
1714     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1715     condition.sql = "DETACH DATABASE TEST";
1716     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1717     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1718     db = nullptr;
1719     CloseStore();
1720 }
1721 
1722 /**
1723   * @tc.name: ExecuteSql008
1724   * @tc.desc: Test the ExecSql interface for bool type results
1725   * @tc.type: FUNC
1726   * @tc.require:
1727   * @tc.author: bty
1728   */
1729 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql008, TestSize.Level0)
1730 {
1731     /**
1732      * @tc.steps:step1. init db data
1733      * @tc.expected: step1. Return OK.
1734      */
1735     CreateMultiTable();
1736     OpenStore();
1737     uint64_t num = 10;
1738     for (size_t i = 0; i < num; i++) {
1739         string sql = "INSERT OR REPLACE INTO " + TABLE_NAME1 +
1740             " (name, height, married, photo, assert, age) VALUES ('Tom" + std::to_string(i) +
1741             "', '175.8', '0', '', '' , '18');";
1742         EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1743     }
1744 
1745     /**
1746      * @tc.steps:step2. check if the result is of bool type
1747      * @tc.expected: step2. Return OK.
1748      */
1749     SqlCondition condition;
1750     condition.sql = "select * from " + TABLE_NAME1;
1751     std::vector<VBucket> records;
1752     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1753     EXPECT_EQ(records.size(), num);
1754     EXPECT_NE(records[0].find("married"), records[0].end());
1755     if (records[0].find("married") != records[0].end()) {
1756         Type married = records[0].find("married")->second;
1757         EXPECT_TRUE(married.index() == TYPE_INDEX<bool>);
1758     }
1759     CloseStore();
1760 }
1761 
1762 /**
1763   * @tc.name: ExecuteSql009
1764   * @tc.desc: Test ExecuteSql update using the parameter "readOnly"
1765   * @tc.type: FUNC
1766   * @tc.require:
1767   * @tc.author: liaoyonghuang
1768   */
1769 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql009, TestSize.Level0)
1770 {
1771     /**
1772      * @tc.steps:step1. init db data
1773      * @tc.expected: step1. Return OK.
1774      */
1775     uint64_t num = 10;
1776     CreateMultiTable();
1777     BatchInsertTableName2Data(num);
1778     OpenStore();
1779     /**
1780      * @tc.steps:step2. ExecuteSql update using the parameter "readOnly"
1781      * @tc.expected: step2. Return OK.
1782      */
1783     SqlCondition condition;
1784     std::vector<VBucket> records;
1785     condition.readOnly = true;
1786     condition.sql = "update " + TABLE_NAME2 + " set name = 'new_name' where age = 18";
1787     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1788     CloseStore();
1789 }
1790 
1791 /**
1792   * @tc.name: ExecuteSql010
1793   * @tc.desc: Test ExecuteSql with temp table
1794   * @tc.type: FUNC
1795   * @tc.require:
1796   * @tc.author: bty
1797   */
1798 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql010, TestSize.Level0)
1799 {
1800     /**
1801      * @tc.steps:step1. init db data
1802      * @tc.expected: step1. Return OK.
1803      */
1804     uint64_t num = 10;
1805     CreateMultiTable();
1806     OpenStore();
1807     SqlCondition condition;
1808     Bytes photo = { 1, 2, 3, 4 };
1809     std::vector<VBucket> records;
1810     for (size_t i = 0; i < num; i++) {
1811         condition.sql = "INSERT INTO " + TABLE_NAME2
1812             + " (name, height, photo, asserts, age) VALUES ('Local" + std::to_string(i) +
1813             "', '175.8', ?, 'x', '18');";
1814         condition.bindArgs = {photo};
1815         EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1816     }
1817 
1818     /**
1819      * @tc.steps:step2. ExecuteSql with transaction
1820      * @tc.expected: step2. Return OK.
1821      */
1822     condition.sql = "create temp table AA as select * from " + TABLE_NAME2;
1823     condition.bindArgs = {};
1824     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1825     condition.sql = "select * from " + TABLE_NAME2;
1826     condition.readOnly = true;
1827     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1828     EXPECT_EQ(records.size(), num);
1829 
1830     /**
1831      * @tc.steps:step3. ExecuteSql again
1832      * @tc.expected: step3. Return OK.
1833      */
1834     records.clear();
1835     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1836     EXPECT_EQ(records.size(), num);
1837     CloseStore();
1838 }
1839 
1840 /**
1841   * @tc.name: ExecuteSql011
1842   * @tc.desc: Test ExecuteSql concurrently
1843   * @tc.type: FUNC
1844   * @tc.require:
1845   * @tc.author: liaoyonghuang
1846   */
1847 
1848 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql011, TestSize.Level1)
1849 {
1850     /**
1851      * @tc.steps:step1. init db data
1852      * @tc.expected: step1. Return OK.
1853      */
1854     uint64_t num = 10;
1855     CreateMultiTable();
1856     BatchInsertTableName2Data(num);
1857     OpenStore();
1858     /**
1859      * @tc.steps:step2. ExecuteSql concurrently
1860      * @tc.expected: step2. Return OK.
1861      */
__anonbdb5d9010202()1862     std::thread readThread([&](){
1863         SqlCondition condition;
1864         std::vector<VBucket> records;
1865         condition.readOnly = true;
1866         condition.sql = "select * from " + TABLE_NAME2;
1867         for (int i = 0; i < 100; i++) {
1868             EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1869         }
1870     });
__anonbdb5d9010302()1871     std::thread transactionThread([&](){
1872         SqlCondition condition;
1873         condition.readOnly = true;
1874         std::vector<VBucket> records;
1875         for (int i = 0; i < 100; i++) {
1876             condition.sql = "BEGIN;";
1877             EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1878             condition.sql = "select * from " + TABLE_NAME2;
1879             EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1880             condition.sql = "COMMIT;";
1881             EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1882         }
1883     });
1884     readThread.join();
1885     transactionThread.join();
1886     CloseStore();
1887 }
1888 
1889 /**
1890   * @tc.name: TrackerTableTest026
1891   * @tc.desc: Test tracker table with case sensitive table name
1892   * @tc.type: FUNC
1893   * @tc.require:
1894   * @tc.author: bty
1895   */
1896 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest026, TestSize.Level1)
1897 {
1898     /**
1899      * @tc.steps:step1. SetTrackerTable on table2
1900      * @tc.expected: step1. Return OK.
1901      */
1902     CreateMultiTable();
1903     OpenStore();
1904     TrackerSchema schema = g_normalSchema1;
1905     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1906 
1907     /**
1908      * @tc.steps:step2. SetTrackerTable on table2 with case different
1909      * @tc.expected: step2. Return NOT_FOUND.
1910      */
1911     schema.tableName = "worker2";
1912     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1913     uint64_t num = 10;
1914     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1915     schema.tableName = "workeR2";
1916     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1917     schema.trackerColNames = {};
1918     schema.tableName = "WorkeR2";
1919     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1920     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1921 
1922     schema = g_normalSchema1;
1923     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1924     CloseStore();
1925 }
1926 
1927 /**
1928   * @tc.name: TrackerTableTest027
1929   * @tc.desc: Test tracker table with case sensitive distributed table name
1930   * @tc.type: FUNC
1931   * @tc.require:
1932   * @tc.author: bty
1933   */
1934 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest027, TestSize.Level1)
1935 {
1936     /**
1937      * @tc.steps:step1. create distributed table on table2 with case different
1938      * @tc.expected: step1. Return OK.
1939      */
1940     CreateMultiTable();
1941     OpenStore();
1942     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
1943     TrackerSchema schema = g_normalSchema1;
1944     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1945     EXPECT_EQ(g_delegate->CreateDistributedTable("worker2", CLOUD_COOPERATION), DBStatus::OK);
1946 
1947     /**
1948      * @tc.steps:step2. SetTrackerTable on table2 with case different
1949      * @tc.expected: step2. Return NOT_FOUND.
1950      */
1951     schema.tableName = "Worker2";
1952     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1953     uint64_t num = 10;
1954     BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1955     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1956     schema.tableName = "WOrker2";
1957     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1958     schema.trackerColNames = {};
1959     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1960     schema.tableName = "Worker2";
1961     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1962 
1963     /**
1964      * @tc.steps:step3. SetTrackerTable with "worKer2"
1965      * @tc.expected: step3. Return NOT_FOUND.
1966      */
1967     schema.tableName = g_normalSchema1.tableName;
1968     EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1969 
1970     /**
1971      * @tc.steps:step4. SetTrackerTable with "worKer2" after reopening db
1972      * @tc.expected: step4. Return OK.
1973      */
1974     CloseStore();
1975     OpenStore();
1976     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1977     schema.trackerColNames = {};
1978     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1979     CloseStore();
1980 }
1981 
1982 /**
1983   * @tc.name: TrackerTableTest028
1984   * @tc.desc: Test set tracker table colNames from not empty to empty
1985   * @tc.type: FUNC
1986   * @tc.require:
1987   * @tc.author: zqq
1988   */
1989 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest028, TestSize.Level1)
1990 {
1991     /**
1992      * @tc.steps:step1. trackerColNames is empty
1993      * @tc.expected: step1. Return OK.
1994      */
1995     TrackerSchema schema;
1996     schema.tableName = TABLE_NAME2;
1997     SetTrackerTableTest(schema, OK);
1998 
1999     /**
2000      * @tc.steps:step2. trackerColNames is not empty
2001      * @tc.expected: step2. Return OK.
2002      */
2003     schema.extendColNames = {EXTEND_COL_NAME2};
2004     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
2005     SetTrackerTableTest(schema, OK);
2006 
2007     /**
2008      * @tc.steps:step3. trackerColNames is empty and track action
2009      * @tc.expected: step3. Return OK.
2010      */
2011     schema.trackerColNames = {};
2012     schema.isTrackAction = true;
2013     SetTrackerTableTest(schema, OK);
2014     SetTrackerTableTest(schema, OK);
2015 
2016     OpenStore();
2017     uint64_t num = 10;
2018     BatchInsertTableName2Data(num);
2019     CheckExtendAndCursor(num, 0, schema.tableName, false);
2020     BatchUpdateTableName2Data(num, {"age"});
2021     CheckExtendAndCursor(num, num, schema.tableName, false);
2022     CloseStore();
2023 }
2024 
2025 /**
2026   * @tc.name: TrackerTableTest029
2027   * @tc.desc: Test set tracker table with force upgrade
2028   * @tc.type: FUNC
2029   * @tc.require:
2030   * @tc.author: zqq
2031   */
2032 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest029, TestSize.Level0)
2033 {
2034     CreateMultiTable();
2035     OpenStore();
2036     /**
2037      * @tc.steps:step1. set tracker table
2038      * @tc.expected: step1. Return OK.
2039      */
2040     TrackerSchema schema;
2041     schema.tableName = TABLE_NAME2;
2042     schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
2043     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2044     /**
2045      * @tc.steps:step2. rebuild table and insert data
2046      * @tc.expected: step2. Return OK.
2047      */
2048     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, "DROP TABLE " + schema.tableName), SQLITE_OK);
2049     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
2050     uint64_t num = 10;
2051     BatchInsertTableName2Data(num);
2052     /**
2053      * @tc.steps:step3. rebuild table and insert data
2054      * @tc.expected: step3. Return OK.
2055      */
2056     schema.isForceUpgrade = true;
2057     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2058     CloseStore();
2059 }
2060 
2061 /**
2062   * @tc.name: TrackerTableTest030
2063   * @tc.desc: Test clean trackTable when table is distributedTable
2064   * @tc.type: FUNC
2065   * @tc.require:
2066   * @tc.author: wangxiangdong
2067   */
2068 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest030, TestSize.Level0)
2069 {
2070     /**
2071      * @tc.steps:step1. SetTrackerTable
2072      * @tc.expected: step1. Return OK.
2073      */
2074     CreateMultiTable();
2075 
2076     OpenStore();
2077     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2), OK);
2078 
2079     /**
2080      * @tc.steps:step2. Insert data to table2
2081      * @tc.expected: step2. Return E_OK.
2082      */
2083     uint64_t num = 10;
2084     BatchInsertTableName2Data(num);
2085     BatchDeleteTableName2Data(num / HALF);
2086 
2087     /**
2088      * @tc.steps:step3. CleanTrackerData
2089      * @tc.expected: step3. Return OK.
2090      */
2091     EXPECT_EQ(g_delegate->CleanTrackerData(TABLE_NAME2, num + (num / HALF)), OK);
2092     std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" +
2093         " where extend_field is NULL;";
2094     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2095         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2096     CloseStore();
2097 }
2098 
2099 /**
2100  * @tc.name: TrackerTableTest031
2101  * @tc.desc: Test set tracker table with trackerColNames emtpy
2102  * @tc.type: FUNC
2103  * @tc.require:
2104  * @tc.author: luoguo
2105  */
2106 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest031, TestSize.Level0)
2107 {
2108     CreateMultiTable();
2109     OpenStore();
2110 
2111     /**
2112      * @tc.steps:step1. create distributed table and set data.
2113      * @tc.expected: step1. Return OK.
2114      */
2115     uint64_t num = 10;
2116     BatchInsertTableName2Data(num);
2117     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
2118 
2119     /**
2120      * @tc.steps:step2. set tracker table
2121      * @tc.expected: step2. Return OK.
2122      */
2123     TrackerSchema schema;
2124     schema.tableName = TABLE_NAME2;
2125     schema.extendColNames = {EXTEND_COL_NAME2};
2126     schema.trackerColNames = {};
2127     schema.isForceUpgrade = false;
2128     schema.isTrackAction = true;
2129     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
2130 
2131     /**
2132      * @tc.steps:step3. check cursor count.
2133      * @tc.expected: step3. Return OK.
2134      */
2135     std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" +
2136                       " where extend_field is NULL;";
2137     EXPECT_EQ(sqlite3_exec(
2138                   g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast<void *>(0u), nullptr),
2139         SQLITE_OK);
2140     CloseStore();
2141 }
2142 
2143 /**
2144  * @tc.name: TrackerTableTest032
2145  * @tc.desc: Test after create distributed table cursor increace
2146  * @tc.type: FUNC
2147  * @tc.require:
2148  * @tc.author: tankaisheng
2149  */
2150 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest032, TestSize.Level0)
2151 {
2152     CreateMultiTable();
2153     OpenStore();
2154 
2155     /**
2156      * @tc.steps:step1. create distributed table and set data.
2157      * @tc.expected: step1. Return OK.
2158      */
2159     uint64_t num = 10;
2160     BatchInsertTableName2Data(num);
2161     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
2162 
2163     /**
2164      * @tc.steps:step2. check cursor count.
2165      * @tc.expected: step2. Return OK.
2166      */
2167     std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log" +
2168         " where cursor = 10;";
2169     EXPECT_EQ(sqlite3_exec(
2170                   g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast<void *>(1u), nullptr),
2171         SQLITE_OK);
2172     CloseStore();
2173 }
2174 
2175 /**
2176  * @tc.name: TrackerTableTest033
2177  * @tc.desc: Test CreateDistributedTable after insert data and set tracker table
2178  * @tc.type: FUNC
2179  * @tc.require:
2180  * @tc.author: luoguo
2181  */
2182 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest033, TestSize.Level0)
2183 {
2184     CreateMultiTable();
2185     OpenStore();
2186     uint64_t num = 10;
2187 
2188     /**
2189      * @tc.steps:step1. insert data
2190      * @tc.expected: step1. OK.
2191      */
2192     BatchInsertTableName2Data(num);
2193     TrackerSchema schema = g_normalSchema1;
2194 
2195     /**
2196      * @tc.steps:step2. SetTrackerTable on table2 and set status to 2.
2197      * @tc.expected: step2. ok.
2198      */
2199     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
2200     std::string sql = "UPDATE " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log SET status = 2;";
2201     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
2202     /**
2203      * @tc.steps:step3. check status after CreateDistributedTable
2204      * @tc.expected: step3. status is 0.
2205      */
2206     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
2207     sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log where status = 0;";
2208     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2209         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2210     CloseStore();
2211 }
2212 
2213 /**
2214  * @tc.name: TrackerTableTest034
2215  * @tc.desc: Test set tracker table with multi extend names
2216  * @tc.type: FUNC
2217  * @tc.require:
2218  * @tc.author: liaoyonghuang
2219  */
2220 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest034, TestSize.Level0)
2221 {
2222     /**
2223      * @tc.steps:step1. Init db and set tracker table with multi extend names
2224      * @tc.expected: step1. Return OK.
2225      */
2226     CreateMultiTable();
2227     OpenStore();
2228     TrackerSchema schema = g_normalSchema1;
2229     schema.extendColNames = {EXTEND_COL_NAME2, EXTEND_COL_NAME3};
2230     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2231     /**
2232      * @tc.steps:step2. Insert data to table2
2233      * @tc.expected: step2. Return E_OK.
2234      */
2235     uint64_t num = 10;
2236     BatchInsertTableName2Data(num);
2237     /**
2238      * @tc.steps:step3. Check extend_field
2239      * @tc.expected: step3. Return E_OK.
2240      */
2241     std::string checkValidJsonSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2242         " where json_valid(extend_field) = 1";
2243     EXPECT_EQ(sqlite3_exec(g_db, checkValidJsonSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2244         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2245 
2246     std::string checkAgeSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2247         " where json_extract(extend_field, '$.age') = 18";
2248     EXPECT_EQ(sqlite3_exec(g_db, checkAgeSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2249         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2250 
2251     for (uint64_t i = 0; i < num; i++) {
2252         std::string expectName = "Local" + std::to_string(i);
2253         std::string checkNameSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2254             " where json_extract(extend_field, '$.name') = 'Local" + std::to_string(i) + "'";
2255         EXPECT_EQ(sqlite3_exec(g_db, checkNameSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2256             reinterpret_cast<void *>(1u), nullptr), SQLITE_OK);
2257     }
2258     CloseStore();
2259 }
2260 
2261 /**
2262  * @tc.name: TrackerTableTest035
2263  * @tc.desc: Test set tracker table with multi extend names repeatedly
2264  * @tc.type: FUNC
2265  * @tc.require:
2266  * @tc.author: liaoyonghuang
2267  */
2268 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest035, TestSize.Level0)
2269 {
2270     /**
2271      * @tc.steps:step1. Init db and set tracker table with multi extend names
2272      * @tc.expected: step1. Return OK.
2273      */
2274     CreateMultiTable();
2275     OpenStore();
2276     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
2277     TrackerSchema schema = g_normalSchema1;
2278     schema.extendColNames = {EXTEND_COL_NAME3};
2279     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2280     /**
2281      * @tc.steps:step2. Insert data to table2
2282      * @tc.expected: step2. Return E_OK.
2283      */
2284     uint64_t num = 10;
2285     BatchInsertTableName2Data(num);
2286     std::string sql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2287         " where json_valid(extend_field) = 1 and json_extract(extend_field, '$.name') is not null";
2288     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2289         reinterpret_cast<void *>(0u), nullptr), SQLITE_OK);
2290     /**
2291      * @tc.steps:step3. Set tracker table repeatedly
2292      * @tc.expected: step3. Return E_OK.
2293      */
2294     schema.extendColNames = {EXTEND_COL_NAME2, EXTEND_COL_NAME3};
2295     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2296     /**
2297      * @tc.steps:step4. Check extend_field
2298      * @tc.expected: step4. Return E_OK.
2299      */
2300     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2301         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2302     for (uint64_t i = 0; i < num; i++) {
2303         std::string expectName = "Local" + std::to_string(i);
2304         std::string checkNameSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2305             " where json_extract(extend_field, '$.name') = 'Local" + std::to_string(i) + "'";
2306         EXPECT_EQ(sqlite3_exec(g_db, checkNameSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2307             reinterpret_cast<void *>(1u), nullptr), SQLITE_OK);
2308     }
2309     CloseStore();
2310 }
2311 
SetLowVersionSchema(sqlite3 * db,const std::string & extendColName)2312 void SetLowVersionSchema(sqlite3 *db, const std::string &extendColName)
2313 {
2314     std::string sql = "update naturalbase_rdb_aux_metadata set value = "
2315         "json_insert(value,'$.TABLES[0].EXTEND_NAME', '" + extendColName + "')"
2316         "where json_valid(value)=1 and json_extract(value, '$.TABLES[0].EXTEND_NAMES') is not null";
2317     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK);
2318     sql = "update naturalbase_rdb_aux_metadata set value = json_remove(value,'$.TABLES[0].EXTEND_NAMES')"
2319         "where json_valid(value)=1 and json_extract(value, '$.TABLES[0].EXTEND_NAMES') is not null";
2320     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK);
2321 }
2322 
2323 /**
2324  * @tc.name: TrackerTableTest036
2325  * @tc.desc: Test Upgrade extend field
2326  * @tc.type: FUNC
2327  * @tc.require:
2328  * @tc.author: liaoyonghuang
2329  */
2330 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest036, TestSize.Level1)
2331 {
2332     /**
2333      * @tc.steps:step1. Init db and init extend field to old version data
2334      * @tc.expected: step1. Return OK.
2335      */
2336     CreateMultiTable();
2337     OpenStore();
2338     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
2339     TrackerSchema schema = g_normalSchema1;
2340     schema.extendColNames = {EXTEND_COL_NAME3};
2341     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2342     uint64_t num = 10;
2343     BatchInsertTableName2Data(num);
2344     std::string sql = "delete from " + TABLE_NAME2 + " where _rowid_ % 2 = 0";
2345     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
2346     sql = "update " + DBCommon::GetLogTableName(TABLE_NAME2) + " set extend_field = 'old_age'";
2347     EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
2348     SetLowVersionSchema(g_db, "age");
2349     CloseStore();
2350     OpenStore();
2351     /**
2352      * @tc.steps:step2. Set tracker table
2353      * @tc.expected: step2. Return E_OK.
2354      */
2355     schema.extendColNames = {EXTEND_COL_NAME2, EXTEND_COL_NAME3};
2356     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2357     /**
2358      * @tc.steps:step3. Check extend_field
2359      * @tc.expected: step3. Return E_OK.
2360      */
2361     std::string checkValidJsonSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2362         " where json_valid(extend_field) = 1";
2363     EXPECT_EQ(sqlite3_exec(g_db, checkValidJsonSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2364         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2365 
2366     std::string checkAgeSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2367         " where json_extract(extend_field, '$.age') = 18";
2368     EXPECT_EQ(sqlite3_exec(g_db, checkAgeSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2369         reinterpret_cast<void *>(num / 2), nullptr), SQLITE_OK);
2370     checkAgeSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2371         " where json_extract(extend_field, '$.age') = 'old_age'";
2372     EXPECT_EQ(sqlite3_exec(g_db, checkAgeSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2373         reinterpret_cast<void *>(num / 2), nullptr), SQLITE_OK);
2374 
2375     checkAgeSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2376         " where json_extract(extend_field, '$.name') is null";
2377     EXPECT_EQ(sqlite3_exec(g_db, checkAgeSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2378         reinterpret_cast<void *>(num / 2), nullptr), SQLITE_OK);
2379     for (uint64_t i = 0; i < num; i += 2) {
2380         std::string expectName = "Local" + std::to_string(i);
2381         std::string checkNameSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2382             " where json_extract(extend_field, '$.name') = 'Local" + std::to_string(i) + "'";
2383         EXPECT_EQ(sqlite3_exec(g_db, checkNameSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2384             reinterpret_cast<void *>(1u), nullptr), SQLITE_OK);
2385     }
2386     CloseStore();
2387 }
2388 
2389 /**
2390  * @tc.name: TrackerTableTest037
2391  * @tc.desc: Test open low version db which extend name is empty
2392  * @tc.type: FUNC
2393  * @tc.require:
2394  * @tc.author: liaoyonghuang
2395  */
2396 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest037, TestSize.Level0)
2397 {
2398     /**
2399      * @tc.steps:step1. Init db
2400      * @tc.expected: step1. Return OK.
2401      */
2402     CreateMultiTable();
2403     OpenStore();
2404     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
2405     TrackerSchema schema = g_normalSchema1;
2406     schema.extendColNames = {EXTEND_COL_NAME3};
2407     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2408     /**
2409      * @tc.steps:step2. Set schema as low version which extend name is empty
2410      * @tc.expected: step2. Return E_OK.
2411      */
2412     SetLowVersionSchema(g_db, "");
2413     /**
2414      * @tc.steps:step3. close and open DB
2415      * @tc.expected: step3. Return E_OK.
2416      */
2417     CloseStore();
2418     OpenStore();
2419     CloseStore();
2420 }
2421 
2422 /**
2423   * @tc.name: TrackerTableTest038
2424   * @tc.desc: Test create distributed table with DEVICE_COOPERATION mode then set tracker table
2425   * @tc.type: FUNC
2426   * @tc.require:
2427   * @tc.author: tankaisheng
2428   */
2429 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest038, TestSize.Level0)
2430 {
2431     /**
2432      * @tc.steps:step1. Create DEVICE_COOPERATION DistributedTable
2433      * @tc.expected: step1. Return OK.
2434      */
2435     CreateMultiTable();
2436     OpenStore();
2437     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::OK);
2438 
2439     /**
2440      * @tc.steps:step2. SetTrackerTable on table2
2441      * @tc.expected: step2. Return OK.
2442      */
2443     TrackerSchema schema = g_normalSchema1;
2444     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2445 
2446     /**
2447      * @tc.steps:step3. Insert data to table2 then check tracker table data
2448      * @tc.expected: step3. Return E_OK.
2449      */
2450     uint64_t num = 10;
2451     BatchInsertTableName2Data(num);
2452     std::string checkInsertSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2453         " where cursor='10';";
2454     ASSERT_EQ(sqlite3_exec(g_db, checkInsertSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2455         reinterpret_cast<void *>(1), nullptr), SQLITE_OK);
2456 
2457     /**
2458      * @tc.steps:step4. Update data to table2 then check tracker table data
2459      * @tc.expected: step4. Return E_OK.
2460      */
2461     uint64_t updateNum = 2;
2462     BatchUpdateTableName2Data(updateNum, LOCAL_TABLE_TRACKER_NAME_SET2);
2463     int index = 0;
2464     string checkUpdateSql = "select json_extract(extend_field, '$.name'), cursor from " +
2465        DBCommon::GetLogTableName(TABLE_NAME2) + " where data_key <= " + std::to_string(updateNum);
2466     sqlite3_stmt *stmt = nullptr;
2467     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, checkUpdateSql, stmt), E_OK);
2468     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
2469         std::string extendVal;
2470         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
2471         EXPECT_EQ(extendVal, "1");
2472         std::string cursorVal;
2473         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
2474         EXPECT_EQ(cursorVal, std::to_string(num + (++index)));
2475     }
2476     int errCode;
2477     SQLiteUtils::ResetStatement(stmt, true, errCode);
2478 
2479     /**
2480      * @tc.steps:step5. Delete data to table2 then check tracker table data
2481      * @tc.expected: step5. Return E_OK.
2482      */
2483     BatchDeleteTableName2Data(num / HALF);
2484     std::string checkDeleteSql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2485         " where cursor='17';";
2486     ASSERT_EQ(sqlite3_exec(g_db, checkDeleteSql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2487         reinterpret_cast<void *>(1), nullptr), SQLITE_OK);
2488     CloseStore();
2489 }
2490 
2491 /**
2492   * @tc.name: TrackerTableTest039
2493   * @tc.desc: Test SetTrackerTable repeatedly and delete trigger
2494   * @tc.type: FUNC
2495   * @tc.require:
2496   * @tc.author: liaoyonghuang
2497   */
2498 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest039, TestSize.Level0)
2499 {
2500     /**
2501      * @tc.steps:step1. Init db
2502      * @tc.expected: step1. Return OK.
2503      */
2504     CreateMultiTable();
2505     OpenStore();
2506     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
2507     TrackerSchema schema = g_normalSchema1;
2508     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2509     /**
2510      * @tc.steps:step2. delete triggers
2511      * @tc.expected: step2. Return OK.
2512      */
2513     std::vector<std::string> triggerTypes = {"INSERT", "UPDATE", "DELETE"};
2514     for (const auto &triggerType : triggerTypes) {
2515         std::string sql = "DROP TRIGGER IF EXISTS naturalbase_rdb_" + TABLE_NAME2 + "_ON_" + triggerType;
2516         SQLiteUtils::ExecuteRawSQL(g_db, sql);
2517     }
2518     /**
2519      * @tc.steps:step3. SetTrackerTable repeatedly
2520      * @tc.expected: step3. Return OK.
2521      */
2522     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2523     /**
2524      * @tc.steps:step4. Check if the trigger exists
2525      * @tc.expected: step4. Check OK.
2526      */
2527     for (const auto &triggerType : triggerTypes) {
2528         std::string sql = "select count(*) from sqlite_master where type = 'trigger' and tbl_name = '" + TABLE_NAME2 +
2529             "' and name = 'naturalbase_rdb_" + TABLE_NAME2 + "_ON_" + triggerType + "';";
2530         EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2531             reinterpret_cast<void *>(1), nullptr), SQLITE_OK);
2532     }
2533     CloseStore();
2534 }
2535 
2536 /**
2537   * @tc.name: TrackerTableTest040
2538   * @tc.desc: Test set tracker table with invalid col name
2539   * @tc.type: FUNC
2540   * @tc.require:
2541   * @tc.author: liaoyonghuang
2542   */
2543 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest040, TestSize.Level0)
2544 {
2545     /**
2546      * @tc.steps:step1. Init db and init extend field to old version data
2547      * @tc.expected: step1. Return OK.
2548      */
2549     CreateMultiTable();
2550     OpenStore();
2551     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
2552     /**
2553      * @tc.steps:step2. Set tracker table with invalid col name
2554      * @tc.expected: step2. Return E_OK.
2555      */
2556     TrackerSchema schema = g_normalSchema1;
2557     schema.extendColNames = {EXTEND_COL_NAME1};
2558     EXPECT_EQ(g_delegate->SetTrackerTable(schema), SCHEMA_MISMATCH);
2559     CloseStore();
2560 }
2561 
2562 /**
2563   * @tc.name: TrackerTableTest042
2564   * @tc.desc: tracker table update timestamp
2565   * @tc.type: FUNC
2566   * @tc.require:
2567   * @tc.author: tankaisheng
2568   */
2569 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest042, TestSize.Level0)
2570 {
2571     /**
2572      * @tc.steps:step1. SetTrackerTable
2573      * @tc.expected: step1. Return OK.
2574      */
2575     TrackerSchema schema = g_normalSchema1;
2576     CreateMultiTable();
2577     OpenStore();
2578     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2579 
2580     /**
2581      * @tc.steps:step2. Insert data to table2
2582      * @tc.expected: step2. Return E_OK.
2583      */
2584     uint64_t num = 10;
2585     BatchInsertTableName2Data(num);
2586     sqlite3_stmt *stmt = nullptr;
2587     EXPECT_EQ(SQLiteUtils::GetStatement(
2588         g_db, "select timestamp,wtimestamp from naturalbase_rdb_aux_worKer2_log where data_key = 1", stmt), E_OK);
2589     ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt, false), SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
2590     int64_t beforTime = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
2591     int64_t beforWTime = static_cast<int64_t>(sqlite3_column_int64(stmt, 1));
2592     int errCode;
2593     SQLiteUtils::ResetStatement(stmt, true, errCode);
2594 
2595     /**
2596      * @tc.steps:step3. CreateDistributedTable then checkout data
2597      * @tc.expected: step3. Return E_OK.
2598      */
2599     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), OK);
2600     stmt = nullptr;
2601     EXPECT_EQ(SQLiteUtils::GetStatement(
2602         g_db, "select timestamp,wtimestamp from naturalbase_rdb_aux_worKer2_log where data_key = 1", stmt), E_OK);
2603     ASSERT_EQ(SQLiteUtils::StepWithRetry(stmt, false), SQLiteUtils::MapSQLiteErrno(SQLITE_ROW));
2604     int64_t afterTime = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
2605     int64_t afterWTime = static_cast<int64_t>(sqlite3_column_int64(stmt, 1));
2606     SQLiteUtils::ResetStatement(stmt, true, errCode);
2607     EXPECT_NE(beforTime, afterTime);
2608     EXPECT_NE(beforWTime, afterWTime);
2609     CloseStore();
2610 }
2611 
2612 /**
2613   * @tc.name: TrackerTableTest043
2614   * @tc.desc: Test whether to save syncType after setting up the tracking table
2615   * @tc.type: FUNC
2616   * @tc.require:
2617   * @tc.author: liaoyonghuang
2618   */
2619 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest043, TestSize.Level0)
2620 {
2621     /**
2622      * @tc.steps:step1. SetTrackerTable
2623      * @tc.expected: step1. Return OK.
2624      */
2625     TrackerSchema schema = g_normalSchema1;
2626     CreateMultiTable();
2627     OpenStore();
2628     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2629     /**
2630      * @tc.steps:step2. Check sync type in metatable
2631      * @tc.expected: step2. Return E_OK.
2632      */
2633     std::string metaTableName = "naturalbase_rdb_aux_metadata";
2634     std::string sql = "select count(*) from " + metaTableName + " where key = ?";
2635     sqlite3_stmt* stmt = nullptr;
2636     SQLiteUtils::GetStatement(g_db, sql, stmt);
2637     std::string keyStr = "sync_table_type_" + schema.tableName;
2638     Key key(keyStr.begin(), keyStr.end());
2639     SQLiteUtils::BindBlobToStatement(stmt, 1, key);
2640     SQLiteUtils::StepWithRetry(stmt);
2641 
2642     int count = static_cast<int>(sqlite3_column_int(stmt, 0));
2643     EXPECT_EQ(count, 1);
2644     int errCode = E_OK;
2645     SQLiteUtils::ResetStatement(stmt, true, errCode);
2646     CloseStore();
2647 }
2648 
CheckCursor(int begin,int end,sqlite3 * db)2649 void CheckCursor(int begin, int end, sqlite3 *db)
2650 {
2651     std::string querySql = "select cursor from " + DBCommon::GetLogTableName(TABLE_NAME2) + " order by data_key;";
2652     sqlite3_stmt *stmt = nullptr;
2653     EXPECT_EQ(SQLiteUtils::GetStatement(db, querySql, stmt), E_OK);
2654     int64_t cursor = begin;
2655     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
2656         std::string extendVal;
2657         int64_t actualCursor = sqlite3_column_int64(stmt, 0);
2658         EXPECT_EQ(actualCursor, cursor);
2659         cursor++;
2660     }
2661     EXPECT_EQ(cursor, end + 1);
2662     int errCode = E_OK;
2663     SQLiteUtils::ResetStatement(stmt, true, errCode);
2664 }
2665 
2666 /**
2667   * @tc.name: TrackerTableTest044
2668   * @tc.desc: Test SetTrackerTable and CreateDistributedTable when there is data in the table
2669   * @tc.type: FUNC
2670   * @tc.require:
2671   * @tc.author: liaoyonghuang
2672   */
2673 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest044, TestSize.Level0)
2674 {
2675     /**
2676      * @tc.steps:step1. SetTrackerTable on table2
2677      * @tc.expected: step1. Return OK.
2678      */
2679     CreateMultiTable();
2680     OpenStore();
2681     TrackerSchema schema = g_normalSchema1;
2682     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2683     /**
2684      * @tc.steps:step2. CreateDistributedTable on table2 and insert data
2685      * @tc.expected: step2. Return OK.
2686      */
2687     uint64_t num = 10;
2688     BatchInsertTableName2Data(num);
2689     CheckCursor(1, 10, g_db);
2690     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::OK);
2691     /**
2692      * @tc.steps:step3. Check log table
2693      * @tc.expected: step3. Return OK.
2694      */
2695     string querySql = "select json_extract(extend_field, '$.name') from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2696         " order by data_key;";
2697     sqlite3_stmt *stmt = nullptr;
2698     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
2699     int count = 0;
2700     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
2701         std::string extendVal;
2702         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
2703         EXPECT_EQ(extendVal, "Local" + std::to_string(count));
2704         count++;
2705     }
2706     EXPECT_EQ(count, 10);
2707     int errCode = E_OK;
2708     SQLiteUtils::ResetStatement(stmt, true, errCode);
2709     CheckCursor(11, 20, g_db);
2710     CloseStore();
2711 }
2712 
2713 /**
2714   * @tc.name: TrackerTableTest045
2715   * @tc.desc: Test SetTrackerTable and CreateDistributedTable when there is data in the table
2716   * @tc.type: FUNC
2717   * @tc.require:
2718   * @tc.author: liaoyonghuang
2719   */
2720 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest045, TestSize.Level0)
2721 {
2722     /**
2723      * @tc.steps:step1. CreateDistributedTable on table2 and insert data
2724      * @tc.expected: step1. Return OK.
2725      */
2726     CreateMultiTable();
2727     OpenStore();
2728     uint64_t num = 10;
2729     BatchInsertTableName2Data(num);
2730     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::OK);
2731     /**
2732      * @tc.steps:step2. Check cursor
2733      * @tc.expected: step2. Return OK.
2734      */
2735     CheckCursor(1, 10, g_db);
2736     /**
2737      * @tc.steps:step3. SetTrackerTable on table2
2738      * @tc.expected: step3. Return WITH_INVENTORY_DATA.
2739      */
2740     TrackerSchema schema = g_normalSchema1;
2741     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
2742     /**
2743      * @tc.steps:step4. Check cursor
2744      * @tc.expected: step4. Return OK.
2745      */
2746     CheckCursor(11, 20, g_db);
2747     CloseStore();
2748 }
2749 
2750 /**
2751   * @tc.name: TrackerTableTest046
2752   * @tc.desc: Test clear log of mismatched data
2753   * @tc.type: FUNC
2754   * @tc.require:
2755   * @tc.author: bty
2756   */
2757 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest046, TestSize.Level0)
2758 {
2759     /**
2760      * @tc.steps:step1. SetTrackerTable on table2
2761      * @tc.expected: step1. Return OK.
2762      */
2763     CreateMultiTable();
2764     OpenStore();
2765     int num = 10;
2766     BatchInsertTableName2Data(num);
2767     TrackerSchema schema = g_normalSchema1;
2768     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
2769 
2770     /**
2771      * @tc.steps:step2. Recreate table2 by rename
2772      * @tc.expected: step2. Return OK.
2773      */
2774     std::string sql = "ALTER TABLE " + TABLE_NAME2 + " RENAME TO xxx";
2775     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, sql), E_OK);
2776     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, CREATE_LOCAL_PK_TABLE_SQL), E_OK);
2777     sql = "INSERT INTO " + TABLE_NAME2 + " SELECT id,name,height,photo,asserts,age FROM xxx";
2778     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, sql), E_OK);
2779     sql = "DROP TABLE xxx";
2780     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, sql), E_OK);
2781     sql = "DELETE FROM " + TABLE_NAME2 + " WHERE id in ('7', '9')";
2782     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, sql), E_OK);
2783 
2784     /**
2785      * @tc.steps:step3. Set tracker and check log count
2786      * @tc.expected: step3. Return OK.
2787      */
2788     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2789     sql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2);
2790     num = 8;
2791     EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2792         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2793     CloseStore();
2794 }
2795 
2796 /**
2797   * @tc.name: TrackerTableTest047
2798   * @tc.desc: Test recover log for extend_field is NULL
2799   * @tc.type: FUNC
2800   * @tc.require:
2801   * @tc.author: bty
2802   */
2803 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest047, TestSize.Level0)
2804 {
2805     /**
2806      * @tc.steps:step1. SetTrackerTable on table2
2807      * @tc.expected: step1. Return WITH_INVENTORY_DATA.
2808      */
2809     CreateMultiTable();
2810     OpenStore();
2811     int num = 10;
2812     BatchInsertTableName2Data(num);
2813     TrackerSchema schema = g_normalSchema1;
2814     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
2815 
2816     /**
2817      * @tc.steps:step2. Construct a log with invalid extend_field
2818      * @tc.expected: step2. Return OK.
2819      */
2820     std::string sql = "UPDATE " + DBCommon::GetLogTableName(TABLE_NAME2) + " SET extend_field = NULL"
2821         " WHERE data_key=1";
2822     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, sql), E_OK);
2823     std::string querySql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
2824         " WHERE json_type(extend_field) IS 'object'";
2825     num = 9;
2826     EXPECT_EQ(sqlite3_exec(g_db, querySql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2827         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2828 
2829     /**
2830      * @tc.steps:step3. Set tracker and check log count
2831      * @tc.expected: step3. Return OK.
2832      */
2833     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2834     num = 10;
2835     EXPECT_EQ(sqlite3_exec(g_db, querySql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
2836         reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
2837     CloseStore();
2838 }
2839 
2840 /**
2841   * @tc.name: TrackerTableTest048
2842   * @tc.desc: Test set tracker table after create cloud distributed table
2843   * @tc.type: FUNC
2844   * @tc.require:
2845   * @tc.author: liaoyonghuang
2846   */
2847 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest048, TestSize.Level0)
2848 {
2849     /**
2850      * @tc.steps:step1. Create cloud distributed table
2851      * @tc.expected: step1. Return OK.
2852      */
2853     CreateMultiTable();
2854     OpenStore();
2855     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
2856     /**
2857      * @tc.steps:step2. Set tracker table
2858      * @tc.expected: step2. Return OK.
2859      */
2860     TrackerSchema schema = g_normalSchema1;
2861     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2862     /**
2863      * @tc.steps:step3. Register client observer
2864      * @tc.expected: step3. Return OK.
2865      */
2866     std::vector<ClientChangedData> clientChangedData;
__anonbdb5d9010402(ClientChangedData &changedData) 2867     ClientObserver observer = [&clientChangedData](ClientChangedData &changedData) {
2868         clientChangedData.push_back(changedData);
2869     };
2870     RegisterClientObserver(g_db, observer);
2871     RegisterDbHook(g_db);
2872     /**
2873      * @tc.steps:step4. Insert data and check change data
2874      * @tc.expected: step4. Return OK.
2875      */
2876     uint32_t num = 10;
2877     BatchInsertTableName2Data(num);
2878     int waitTimes = 0;
2879     while (waitTimes < 10 && clientChangedData.size() != num) { // 10 is max wait times
2880         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms
2881         waitTimes++;
2882     }
2883     ASSERT_EQ(clientChangedData.size(), num);
2884     for (const auto &changedData : clientChangedData) {
2885         for (const auto &[tableName, prop] : changedData.tableData) {
2886             EXPECT_EQ(tableName, TABLE_NAME2);
2887             EXPECT_TRUE(prop.isCloudSyncDataChange);
2888             EXPECT_TRUE(prop.isTrackedDataChange);
2889         }
2890     }
2891 
2892     UnRegisterClientObserver(g_db);
2893     UnregisterDbHook(g_db);
2894     CloseStore();
2895 }
2896 
2897 /**
2898   * @tc.name: SchemaStrTest001
2899   * @tc.desc: Test open reOpen stroe when schemaStr is empty
2900   * @tc.type: FUNC
2901   * @tc.require:
2902   * @tc.author: bty
2903   */
2904 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, SchemaStrTest001, TestSize.Level1)
2905 {
2906     /**
2907      * @tc.steps:step1. set empty for relational schema str, reopen store
2908      * @tc.expected: step1. Return OK.
2909      */
2910     std::string updMetaSql = "UPDATE naturalbase_rdb_aux_metadata SET value=? where key=?;";
2911     CreateMultiTable();
2912     OpenStore();
2913     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
2914     SqlCondition condition;
2915     std::vector<VBucket> records;
2916     condition.sql = updMetaSql;
2917     Key relationKey;
2918     DBCommon::StringToVector(DBConstant::RELATIONAL_SCHEMA_KEY, relationKey);
2919     condition.bindArgs = { std::string(""), relationKey };
2920     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
2921     CloseStore();
2922     OpenStore();
2923 
2924     /**
2925      * @tc.steps:step2. set empty for relational schema str, reopen store to upgrade
2926      * @tc.expected: step2. Return OK.
2927      */
2928     Value verVal;
2929     DBCommon::StringToVector("5.0", verVal);
2930     Key verKey;
2931     DBCommon::StringToVector("log_table_version", verKey);
2932     condition.bindArgs = { verVal, verKey };
2933     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
2934     condition.bindArgs = { std::string(""), relationKey };
2935     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
2936     CloseStore();
2937     OpenStore();
2938 
2939     /**
2940      * @tc.steps:step3. set empty for tracker schema str, reopen store to upgrade
2941      * @tc.expected: step3. Return OK.
2942      */
2943     TrackerSchema schema = g_normalSchema1;
2944     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2945     condition.bindArgs = { verVal, verKey };
2946     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
2947     condition.bindArgs = { std::string(""), relationKey };
2948     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
2949     Key trackerKey;
2950     DBCommon::StringToVector("relational_tracker_schema", trackerKey);
2951     condition.bindArgs = { std::string(""), trackerKey };
2952     EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
2953     CloseStore();
2954     OpenStore();
2955 
2956     /**
2957      * @tc.steps:step4. try to create distributed table and set tracker table again
2958      * @tc.expected: step4. Return OK.
2959      */
2960     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
2961     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME1, CLOUD_COOPERATION), DBStatus::OK);
2962     EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
2963     CloseStore();
2964 }
2965 
2966 /**
2967  * @tc.name: TrackerTableTest041
2968  * @tc.desc: Test cursor increases when set tracker table after create distributed table by DEVICE_COOPERATION type
2969  * @tc.type: FUNC
2970  * @tc.require:
2971  * @tc.author: suyue
2972  */
2973 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest041, TestSize.Level0)
2974 {
2975     CreateMultiTable();
2976     OpenStore();
2977 
2978     /**
2979      * @tc.steps:step1. create distributed table by DEVICE_COOPERATION type and insert data
2980      * @tc.expected: step1. return OK
2981      */
2982     EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::OK);
2983     BatchInsertTableName2Data(10); // insert 10 data
2984 
2985     /**
2986      * @tc.steps:step2. set tracker table on table2 and check cursor
2987      * @tc.expected: step2. cursor increases
2988      */
2989     string querySql = "select cursor from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + "_log";
2990     sqlite3_stmt *stmt = nullptr;
2991     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
2992     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
2993         std::string cursorVal;
2994         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, cursorVal), E_OK);
2995         EXPECT_EQ(cursorVal, "0");
2996     }
2997     int errCode;
2998     SQLiteUtils::ResetStatement(stmt, true, errCode);
2999 
3000     TrackerSchema schema = g_normalSchema1;
3001     EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
3002     int index = 0;
3003     stmt = nullptr;
3004     EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
3005     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
3006         std::string cursorVal;
3007         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, cursorVal), E_OK);
3008         EXPECT_EQ(cursorVal, std::to_string(++index));
3009     }
3010     SQLiteUtils::ResetStatement(stmt, true, errCode);
3011     CloseStore();
3012 }
3013 }
3014