• 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 <sys/time.h>
17 #include <gtest/gtest.h>
18 
19 #include "concurrent_adapter.h"
20 #include "db_common.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "relational_store_client.h"
24 #include "relational_store_delegate_impl.h"
25 #include "relational_store_manager.h"
26 #include "cloud_db_sync_utils_test.h"
27 #include "store_observer.h"
28 
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32 using namespace std;
33 
34 namespace {
35 constexpr const char *DB_SUFFIX = ".db";
36 constexpr const char *STORE_ID = "Relational_Store_ID";
37 std::string g_dbDir;
38 std::string g_testDir;
39 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
40 
41 constexpr int E_OK = 0;
42 constexpr int E_ERROR = 1;
43 const int WAIT_TIME = 1000; // 1000ms
44 constexpr static uint64_t TO_100_NS = 10; // 1us to 100ns
45 const uint64_t MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS = 1000000;
46 std::mutex g_mutex;
47 std::condition_variable g_cv;
48 bool g_alreadyNotify = false;
49 
50 class DistributedDBCloudInterfacesRelationalExtTest : public testing::Test {
51 public:
52     static void SetUpTestCase(void);
53     static void TearDownTestCase(void);
54     void SetUp() override;
55     void TearDown() override;
56     void CheckTriggerObserverTest002(const std::string &tableName, std::atomic<int> &count);
57 
ClientObserverFunc(ClientChangedData & clientChangedData)58     void ClientObserverFunc(ClientChangedData &clientChangedData)
59     {
60         for (const auto &tableEntry : clientChangedData.tableData) {
61             LOGD("client observer fired, table: %s", tableEntry.first.c_str());
62             triggerTableData_.insert_or_assign(tableEntry.first, tableEntry.second);
63         }
64         triggeredCount_++;
65         {
66             std::unique_lock<std::mutex> lock(g_mutex);
67             g_alreadyNotify = true;
68         }
69         g_cv.notify_one();
70     }
71 
ClientObserverFunc2(ClientChangedData & clientChangedData)72     void ClientObserverFunc2(ClientChangedData &clientChangedData)
73     {
74         triggeredCount2_++;
75         {
76             std::unique_lock<std::mutex> lock(g_mutex);
77             g_alreadyNotify = true;
78         }
79         g_cv.notify_one();
80     }
81 
CheckTriggerTableData(size_t dataSize,const std::string & tableName,ChangeProperties & properties,int triggerCount)82     void CheckTriggerTableData(size_t dataSize, const std::string &tableName, ChangeProperties &properties,
83         int triggerCount)
84     {
85         ASSERT_EQ(triggerTableData_.size(), dataSize);
86         EXPECT_EQ(triggerTableData_.begin()->first, tableName);
87         EXPECT_EQ(triggerTableData_.begin()->second.isTrackedDataChange, properties.isTrackedDataChange);
88         EXPECT_EQ(triggerTableData_.begin()->second.isCloudSyncDataChange, properties.isCloudSyncDataChange);
89         EXPECT_EQ(triggeredCount_, triggerCount);
90     }
91 
WaitAndResetNotify()92     void WaitAndResetNotify()
93     {
94         std::unique_lock<std::mutex> lock(g_mutex);
95         WaitAndResetNotifyWithLock(lock);
96     }
97 
WaitAndResetNotifyWithLock(std::unique_lock<std::mutex> & lock)98     void WaitAndResetNotifyWithLock(std::unique_lock<std::mutex> &lock)
99     {
100         g_cv.wait(lock, []() {
101             return g_alreadyNotify;
102         });
103         g_alreadyNotify = false;
104     }
105 
106     std::set<std::string> triggerTableNames_;
107     std::map<std::string, ChangeProperties> triggerTableData_;
108     int triggeredCount_ = 0;
109     int triggeredCount2_ = 0;
110 };
111 
SetUpTestCase(void)112 void DistributedDBCloudInterfacesRelationalExtTest::SetUpTestCase(void)
113 {
114     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
115     LOGD("Test dir is %s", g_testDir.c_str());
116     g_dbDir = g_testDir + "/";
117     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
118 }
119 
TearDownTestCase(void)120 void DistributedDBCloudInterfacesRelationalExtTest::TearDownTestCase(void)
121 {
122 }
123 
SetUp()124 void DistributedDBCloudInterfacesRelationalExtTest::SetUp()
125 {
126 }
127 
TearDown()128 void DistributedDBCloudInterfacesRelationalExtTest::TearDown()
129 {
130     g_alreadyNotify = false;
131     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
132 }
133 
CheckTriggerObserverTest002(const std::string & tableName,std::atomic<int> & count)134 void DistributedDBCloudInterfacesRelationalExtTest::CheckTriggerObserverTest002(const std::string &tableName,
135     std::atomic<int> &count)
136 {
137     count++;
138     ASSERT_EQ(triggerTableData_.size(), 1u);
139     EXPECT_EQ(triggerTableData_.begin()->first, tableName);
140     EXPECT_EQ(triggerTableData_.begin()->second.isTrackedDataChange, false);
141     EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
142     EXPECT_EQ(triggeredCount_, count);
143 }
144 
GetCurrentSysTimeIn100Ns(uint64_t & outTime)145 static int GetCurrentSysTimeIn100Ns(uint64_t &outTime)
146 {
147     struct timeval rawTime;
148     int errCode = gettimeofday(&rawTime, nullptr);
149     if (errCode < 0) {
150         return -E_ERROR;
151     }
152     outTime = static_cast<uint64_t>(rawTime.tv_sec) * MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS +
153         static_cast<uint64_t>(rawTime.tv_usec);
154     outTime *= TO_100_NS;
155     return E_OK;
156 }
157 
SetTracerSchemaTest001(const std::string & tableName)158 static void SetTracerSchemaTest001(const std::string &tableName)
159 {
160     TrackerSchema schema;
161     schema.tableName = tableName;
162     schema.extendColNames = {"id"};
163     schema.trackerColNames = {"name"};
164     RelationalStoreDelegate *delegate = nullptr;
165     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
166     EXPECT_EQ(status, OK);
167     ASSERT_NE(delegate, nullptr);
168     EXPECT_EQ(delegate->SetTrackerTable(schema), OK);
169     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
170 }
171 
ExecSqlAndWaitForObserver(sqlite3 * db,const std::string & sql,std::unique_lock<std::mutex> & lock)172 static void ExecSqlAndWaitForObserver(sqlite3 *db, const std::string &sql, std::unique_lock<std::mutex> &lock)
173 {
174     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
175     g_cv.wait(lock, []() {
176         return g_alreadyNotify;
177     });
178     g_alreadyNotify = false;
179 }
180 
181 /**
182  * @tc.name: GetRawSysTimeTest001
183  * @tc.desc: Test get_raw_sys_time has been registered in sqlite
184  * @tc.type: FUNC
185  * @tc.require:
186  * @tc.author: zhangshijie
187  */
188 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, GetRawSysTimeTest001, TestSize.Level0)
189 {
190     const std::string sql = "select get_raw_sys_time();";
191     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
192     EXPECT_NE(db, nullptr);
193     uint64_t curTime = 0;
194     int errCode = GetCurrentSysTimeIn100Ns(curTime);
195     EXPECT_EQ(errCode, E_OK);
__anonf66911750402(sqlite3_stmt *stmt) 196     errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime] (sqlite3_stmt *stmt) {
197         EXPECT_GT(static_cast<uint64_t>(sqlite3_column_int64(stmt, 0)), curTime);
198         return E_OK;
199     });
200     EXPECT_EQ(errCode, SQLITE_OK);
201     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
202 }
203 
PrepareData(const std::vector<std::string> & tableNames,bool primaryKeyIsRowId,DistributedDB::TableSyncType tableSyncType,bool userDefineRowid=true,bool createDistributeTable=true)204 void PrepareData(const std::vector<std::string> &tableNames, bool primaryKeyIsRowId,
205     DistributedDB::TableSyncType tableSyncType, bool userDefineRowid = true, bool createDistributeTable = true)
206 {
207     /**
208      * @tc.steps:step1. create db, create table.
209      * @tc.expected: step1. return ok.
210      */
211     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
212     EXPECT_NE(db, nullptr);
213     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
214     std::string sql;
215     for (const auto &tableName : tableNames) {
216         if (primaryKeyIsRowId) {
217             sql = "create table " + tableName + "(rowid INTEGER primary key, id int, name TEXT);";
218         } else {
219             if (userDefineRowid) {
220                 sql = "create table " + tableName + "(rowid int, id int, name TEXT, PRIMARY KEY(id));";
221             } else {
222                 sql = "create table " + tableName + "(id int, name TEXT, PRIMARY KEY(id));";
223             }
224         }
225         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
226     }
227     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
228 
229     /**
230      * @tc.steps:step2. create distributed table.
231      * @tc.expected: step2. return ok.
232      */
233     RelationalStoreDelegate *delegate = nullptr;
234     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
235     EXPECT_EQ(status, OK);
236     ASSERT_NE(delegate, nullptr);
237     if (createDistributeTable) {
238         for (const auto &tableName : tableNames) {
239             EXPECT_EQ(delegate->CreateDistributedTable(tableName, tableSyncType), OK);
240         }
241     }
242     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
243     delegate = nullptr;
244 }
245 
InsertTriggerTest(DistributedDB::TableSyncType tableSyncType)246 void InsertTriggerTest(DistributedDB::TableSyncType tableSyncType)
247 {
248     /**
249      * @tc.steps:step1. prepare data.
250      * @tc.expected: step1. return ok.
251      */
252     const std::string tableName = "sync_data";
253     PrepareData({tableName}, false, tableSyncType);
254 
255     /**
256      * @tc.steps:step2. insert data into sync_data.
257      * @tc.expected: step2. return ok.
258      */
259     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
260     EXPECT_NE(db, nullptr);
261     std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
262     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
263 
264     /**
265      * @tc.steps:step3. select data from log table.
266      * @tc.expected: step3. return ok.
267      */
268     sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;";
269     uint64_t curTime = 0;
270     int errCode = GetCurrentSysTimeIn100Ns(curTime);
271     EXPECT_EQ(errCode, E_OK);
272 
273     int resultCount = 0;
274     errCode = RelationalTestUtils::ExecSql(db, sql, nullptr,
275         [tableSyncType, curTime, &resultCount] (sqlite3_stmt *stmt) {
276         EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1); // 1 is row id
277         std::string device = "";
278         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
279         EXPECT_EQ(device, "");
280         std::string oriDevice = "";
281         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
282         EXPECT_EQ(oriDevice, "");
283 
284         int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
285         int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
286         int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
287         EXPECT_TRUE(wtimestamp - timestamp < diff);
288         EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
289         if (tableSyncType == DistributedDB::CLOUD_COOPERATION) {
290             EXPECT_EQ(sqlite3_column_int(stmt, 5), 0x02|0x20); // 5 is column index flag == 0x02|0x20
291         } else {
292             EXPECT_EQ(sqlite3_column_int(stmt, 5), 2); // 5 is column index flag == 2
293         }
294         resultCount++;
295         return E_OK;
296     });
297     EXPECT_EQ(errCode, SQLITE_OK);
298     EXPECT_EQ(resultCount, 1);
299     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
300 }
301 
302 /**
303  * @tc.name: InsertTriggerTest001
304  * @tc.desc: Test insert trigger in sqlite in CLOUD_COOPERATION mode
305  * @tc.type: FUNC
306  * @tc.require:
307  * @tc.author: zhangshijie
308  */
309 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest001, TestSize.Level0)
310 {
311     InsertTriggerTest(DistributedDB::CLOUD_COOPERATION);
312 }
313 
314 /**
315  * @tc.name: InsertTriggerTest002
316  * @tc.desc: Test insert trigger in sqlite in DEVICE_COOPERATION mode
317  * @tc.type: FUNC
318  * @tc.require:
319  * @tc.author: zhangshijie
320  */
321 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest002, TestSize.Level0)
322 {
323     InsertTriggerTest(DistributedDB::DEVICE_COOPERATION);
324 }
325 
326 /**
327  * @tc.name: InsertTriggerTest003
328  * @tc.desc: Test insert trigger in sqlite when use "insert or replace"
329  * @tc.type: FUNC
330  * @tc.require:
331  * @tc.author: zhangshijie
332  */
333 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest003, TestSize.Level1)
334 {
335     /**
336     * @tc.steps:step1. prepare data.
337     * @tc.expected: step1. return ok.
338     */
339     const std::string tableName = "sync_data";
340     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION);
341 
342     /**
343      * @tc.steps:step2. insert data into sync_data.
344      * @tc.expected: step2. return ok.
345      */
346     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
347     EXPECT_NE(db, nullptr);
348     std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan1');";
349     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
350 
351     // update cloud_gid in log table
352     std::string gid = "test_gid";
353     sql = "update " + DBCommon::GetLogTableName(tableName) + " set cloud_gid = '" + gid + "'";
354     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
355     // use insert or replace to update data
356     sql = "insert or replace into " + tableName + " VALUES(3, 1, 'zhangsan1');";
357     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
358 
359     /**
360      * @tc.steps:step3. select data from log table.
361      * @tc.expected: step3. return ok.
362      */
363     sql = "select data_key, device, ori_device, flag, cloud_gid from " + DBCommon::GetLogTableName(tableName);
364     int resultCount = 0;
__anonf66911750602(sqlite3_stmt *stmt) 365     int errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [&resultCount, gid] (sqlite3_stmt *stmt) {
366         EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id
367         std::string device = "";
368         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
369         EXPECT_EQ(device, "");
370         std::string oriDevice = "";
371         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
372         EXPECT_EQ(oriDevice, "");
373 
374         EXPECT_EQ(sqlite3_column_int(stmt, 3), 0x02|0x20); // 3 is column index flag == 0x02|0x20
375         std::string gidStr;
376         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 4, gidStr), E_OK); // 4 is column index
377         EXPECT_EQ(gid, gidStr);
378         resultCount++;
379         return E_OK;
380     });
381     EXPECT_EQ(errCode, SQLITE_OK);
382     EXPECT_EQ(resultCount, 1);
383     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
384 }
385 
UpdateTriggerTest(bool primaryKeyIsRowId)386 void UpdateTriggerTest(bool primaryKeyIsRowId)
387 {
388     /**
389      * @tc.steps:step1. prepare data.
390      * @tc.expected: step1. return ok.
391      */
392     const std::string tableName = "sync_data";
393     PrepareData({tableName}, primaryKeyIsRowId, DistributedDB::CLOUD_COOPERATION);
394 
395     /**
396      * @tc.steps:step2. insert data into sync_data_tmp.
397      * @tc.expected: step2. return ok.
398      */
399     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
400     EXPECT_NE(db, nullptr);
401     std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
402     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
403 
404     /**
405      * @tc.steps:step3. update data.
406      * @tc.expected: step3. return ok.
407      */
408     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
409     sql = "update " + tableName + " set name = 'lisi';";
410     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
411 
412     /**
413      * @tc.steps:step4. select data from log table.
414      * @tc.expected: step4. return ok.
415      */
416     sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;";
417     uint64_t curTime = 0;
418     int errCode = GetCurrentSysTimeIn100Ns(curTime);
419     EXPECT_EQ(errCode, E_OK);
420 
421     int resultCount = 0;
422     errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount, primaryKeyIsRowId] (
423         sqlite3_stmt *stmt) {
424         if (primaryKeyIsRowId) {
425             EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id
426         } else {
427             EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1); // 1 is row id
428         }
429 
430         EXPECT_EQ(sqlite3_column_int(stmt, 5), 0x02|0x20); // 5 is column index, flag == 0x02|0x20
431 
432         std::string device = "";
433         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
434         EXPECT_EQ(device, "");
435         std::string oriDevice = "";
436         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
437         EXPECT_EQ(oriDevice, "");
438 
439         int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
440         int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
441         int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
442         EXPECT_TRUE(timestamp - wtimestamp > diff);
443         EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
444 
445         resultCount++;
446         return E_OK;
447     });
448     EXPECT_EQ(errCode, SQLITE_OK);
449     EXPECT_EQ(resultCount, 1);
450     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
451 }
452 
453 /**
454  * @tc.name: UpdateTriggerTest001
455  * @tc.desc: Test update trigger in sqlite for primary key is not row id
456  * @tc.type: FUNC
457  * @tc.require:
458  * @tc.author: zhangshijie
459  */
460 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, UpdateTriggerTest001, TestSize.Level1)
461 {
462     UpdateTriggerTest(false);
463 }
464 
465 /**
466  * @tc.name: UpdateTriggerTest002
467  * @tc.desc: Test update trigger in sqlite for primary key is row id
468  * @tc.type: FUNC
469  * @tc.require:
470  * @tc.author: zhangshijie
471  */
472 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, UpdateTriggerTest002, TestSize.Level1)
473 {
474     UpdateTriggerTest(true);
475 }
476 
477 /**
478  * @tc.name: DeleteTriggerTest001
479  * @tc.desc: Test delete trigger in sqlite
480  * @tc.type: FUNC
481  * @tc.require:
482  * @tc.author: zhangshijie
483  */
484 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DeleteTriggerTest001, TestSize.Level1)
485 {
486     /**
487      * @tc.steps:step1. prepare data.
488      * @tc.expected: step1. return ok.
489      */
490     const std::string tableName = "sync_data";
491     PrepareData({tableName}, true, DistributedDB::CLOUD_COOPERATION);
492 
493     /**
494      * @tc.steps:step2. insert data into sync_data.
495      * @tc.expected: step2. return ok.
496      */
497     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
498     EXPECT_NE(db, nullptr);
499     std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
500     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
501 
502     /**
503      * @tc.steps:step3. delete data.
504      * @tc.expected: step3. return ok.
505      */
506     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
507     sql = "delete from " + tableName + " where name = 'zhangsan';";
508     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
509 
510     /**
511      * @tc.steps:step4. select data from log table.
512      * @tc.expected: step4. return ok.
513      */
514     sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;";
515     uint64_t curTime = 0;
516     int errCode = GetCurrentSysTimeIn100Ns(curTime);
517     EXPECT_EQ(errCode, E_OK);
518 
519     int resultCount = 0;
__anonf66911750802(sqlite3_stmt *stmt) 520     errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount] (sqlite3_stmt *stmt) {
521         EXPECT_EQ(sqlite3_column_int64(stmt, 0), -1);
522         EXPECT_EQ(sqlite3_column_int(stmt, 5), 3); // 5 is column index, flag == 3
523 
524         std::string device = "de";
525         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
526         EXPECT_EQ(device, "");
527         std::string oriDevice = "de";
528         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
529         EXPECT_EQ(oriDevice, "");
530 
531         int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
532         int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
533         int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
534         EXPECT_TRUE(timestamp - wtimestamp > diff);
535         EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
536 
537         resultCount++;
538         return E_OK;
539     });
540     EXPECT_EQ(errCode, SQLITE_OK);
541     EXPECT_EQ(resultCount, 1);
542     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
543 }
544 
545 /**
546  * @tc.name: TriggerObserverTest001
547  * @tc.desc: Test invalid args for RegisterClientObserver and UnRegisterClientObserver
548  * @tc.type: FUNC
549  * @tc.require:
550  * @tc.author: zhangshijie
551  */
552 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest001, TestSize.Level0)
553 {
554     /**
555      * @tc.steps:step1. call RegisterClientObserver and UnRegisterClientObserver with db = nullptr.
556      * @tc.expected: step1. return INVALID_ARGS.
557      */
558     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
559         this, std::placeholders::_1);
560     EXPECT_EQ(RegisterClientObserver(nullptr, clientObserver), INVALID_ARGS);
561     EXPECT_EQ(UnRegisterClientObserver(nullptr), INVALID_ARGS);
562 
563     /**
564      * @tc.steps:step2. call RegisterClientObserver with nullptr clientObserver.
565      * @tc.expected: step2. return INVALID_ARGS.
566      */
567     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
568     EXPECT_NE(db, nullptr);
569     EXPECT_EQ(RegisterClientObserver(db, nullptr), INVALID_ARGS);
570 
571     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
572 }
573 
574 /**
575  * @tc.name: TriggerObserverTest002
576  * @tc.desc: Test trigger client observer in sqlite
577  * @tc.type: FUNC
578  * @tc.require:
579  * @tc.author: zhangshijie
580  */
581 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, TestSize.Level0)
582 {
583     /**
584      * @tc.steps:step1. prepare data.
585      * @tc.expected: step1. return ok.
586      */
587     const std::string tableName = "sync_data";
588     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
589 
590     /**
591     * @tc.steps:step2. register client observer.
592     * @tc.expected: step2. return ok.
593     */
594     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
595     EXPECT_NE(db, nullptr);
596     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
597         this, std::placeholders::_1);
598     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
599     RegisterDbHook(db);
600 
601     /**
602      * @tc.steps:step3. insert data into sync_data, check observer.
603      * @tc.expected: step3. check observer ok.
604      */
605     std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
606     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
607     WaitAndResetNotify();
608     std::atomic<int> count = 0; // 0 is observer triggered counts
609     CheckTriggerObserverTest002(tableName, count);
610 
611     /**
612      * @tc.steps:step4. update data, check observer.
613      * @tc.expected: step4. check observer ok.
614      */
615     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
616     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
617     WaitAndResetNotify();
618     CheckTriggerObserverTest002(tableName, count);
619 
620     /**
621      * @tc.steps:step4. delete data, check observer.
622      * @tc.expected: step4. check observer ok.
623      */
624     sql = "delete from " + tableName + " where id = 3;";
625     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
626     WaitAndResetNotify();
627     CheckTriggerObserverTest002(tableName, count);
628 
629     /**
630      * @tc.steps:step5. register another observer, update data, check observer.
631      * @tc.expected: step5. check observer ok.
632      */
633     triggeredCount_ = 0;
634     ClientObserver clientObserver2 = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc2,
635         this, std::placeholders::_1);
636     EXPECT_EQ(RegisterClientObserver(db, clientObserver2), OK);
637     RegisterDbHook(db);
638     sql = "update " + tableName + " set name = 'lisi2' where id = 2;";
639     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
640     WaitAndResetNotify();
641     EXPECT_EQ(triggeredCount_, 0);
642     EXPECT_EQ(triggeredCount2_, 1);
643 
644     /**
645      * @tc.steps:step6. UnRegisterClientObserver, update data, check observer.
646      * @tc.expected: step6. check observer ok.
647      */
648     triggeredCount2_ = 0;
649     EXPECT_EQ(UnRegisterClientObserver(db), OK);
650     sql = "update " + tableName + " set name = 'lisi3' where id = 2;";
651     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
652     EXPECT_EQ(triggeredCount2_, 0); // observer2 will not be triggered
653     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
654 }
655 
656 /**
657  * @tc.name: TriggerObserverTest003
658  * @tc.desc: Test RegisterClientObserver and UnRegisterClientObserver concurrently
659  * @tc.type: FUNC
660  * @tc.require:
661  * @tc.author: zhangshijie
662  */
663 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest003, TestSize.Level1)
664 {
665     for (int i = 0; i < 1000; i++) { // 1000 is loop times
__anonf66911750902() 666         std::thread t1 ([this]() {
667             sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
668             EXPECT_NE(db, nullptr);
669             ClientObserver clientObserver = std::bind(
670                 &DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc, this, std::placeholders::_1);
671             EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
672             EXPECT_EQ(UnRegisterClientObserver(db), OK);
673             EXPECT_EQ(sqlite3_close_v2(db), E_OK);
674         });
675 
__anonf66911750a02() 676         std::thread t2 ([this]() {
677             sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
678             EXPECT_NE(db, nullptr);
679             ClientObserver clientObserver = std::bind(
680                 &DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc2, this, std::placeholders::_1);
681             EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
682             EXPECT_EQ(UnRegisterClientObserver(db), OK);
683             EXPECT_EQ(sqlite3_close_v2(db), E_OK);
684         });
685 
686         t1.join();
687         t2.join();
688     }
689 }
690 
691 /**
692  * @tc.name: TriggerObserverTest004
693  * @tc.desc: Test batch insert/update/delete data then trigger client observer
694  * @tc.type: FUNC
695  * @tc.require:
696  * @tc.author: zhangshijie
697  */
698 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, TestSize.Level1)
699 {
700     /**
701      * @tc.steps:step1. prepare data.
702      * @tc.expected: step1. return ok.
703      */
704     const std::string tableName = "sync_data";
705     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
706 
707     /**
708     * @tc.steps:step2. register client observer.
709     * @tc.expected: step2. return ok.
710     */
711     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
712     EXPECT_NE(db, nullptr);
713     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
714         this, std::placeholders::_1);
715     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
716     RegisterDbHook(db);
717 
718     /**
719      * @tc.steps:step3. insert data into sync_data, check observer.
720      * @tc.expected: step3. check observer ok.
721      */
722     std::string sql;
723     int dataCounts = 1000; // 1000 is count of insert options.
724     for (int i = 1; i <= dataCounts; i++) {
725         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
726         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
727     }
728     std::unique_lock<std::mutex> lock(g_mutex);
__anonf66911750b02() 729     bool isEqual = g_cv.wait_for(lock, std::chrono::seconds(1), [this, dataCounts]() { // 1 is wait time
730         return triggeredCount_ == dataCounts;
731     });
732     EXPECT_EQ(isEqual, true);
733     WaitAndResetNotifyWithLock(lock);
734     ASSERT_EQ(triggerTableData_.size(), 1u);
735     EXPECT_EQ(triggerTableData_.begin()->first, tableName);
736     EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
737     EXPECT_EQ(triggeredCount_, dataCounts);
738 
739     /**
740      * @tc.steps:step4. insert or replace, check observer.
741      * @tc.expected: step5. check observer ok.
742      */
743     triggeredCount_ = 0;
744     sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');";
745     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
__anonf66911750c02() 746     isEqual = g_cv.wait_for(lock, std::chrono::seconds(1), [this]() { // 1 is wait time
747         return triggeredCount_ == 1;
748     });
749     EXPECT_EQ(isEqual, true);
750     WaitAndResetNotifyWithLock(lock);
751     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert
752     EXPECT_EQ(UnRegisterClientObserver(db), OK);
753     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
754 }
755 
756 /**
757  * @tc.name: TriggerObserverTest005
758  * @tc.desc: Test commit and rollback for one table then trigger client observer
759  * @tc.type: FUNC
760  * @tc.require:
761  * @tc.author: chenchaohao
762  */
763 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest005, TestSize.Level1)
764 {
765     /**
766      * @tc.steps:step1. prepare data.
767      * @tc.expected: step1. return ok.
768      */
769     const std::string tableName = "sync_data";
770     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
771 
772     /**
773     * @tc.steps:step2. register client observer.
774     * @tc.expected: step2. return ok.
775     */
776     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
777     EXPECT_NE(db, nullptr);
778     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
779         this, std::placeholders::_1);
780     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
781     RegisterDbHook(db);
782 
783     /**
784      * @tc.steps:step3. begin transaction and commit.
785      * @tc.expected: step3. check observer ok.
786      */
787     std::string sql = "begin;";
788     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
789     int dataCounts = 1000; // 1000 is count of insert options.
790     for (int i = 1; i <= dataCounts; i++) {
791         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
792         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
793     }
794     sql = "commit;";
795     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
796     WaitAndResetNotify();
797     ASSERT_EQ(triggerTableData_.size(), 1u);
798     EXPECT_EQ(triggerTableData_.begin()->first, tableName);
799     EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
800     EXPECT_EQ(triggeredCount_, 1);
801 
802     /**
803      * @tc.steps:step4. begin transaction and rollback.
804      * @tc.expected: step3. check observer ok.
805      */
806     triggerTableData_.clear();
807     triggeredCount_ = 0;
808     sql = "begin;";
809     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
810     for (int i = dataCounts + 1; i <= 2 * dataCounts; i++) { // 2 is double dataCounts
811         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
812         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
813     }
814     sql = "rollback;";
815     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
816     EXPECT_TRUE(triggerTableData_.empty());
817     EXPECT_EQ(triggeredCount_, 0);
818 
819     /**
820      * @tc.steps:step5. insert or replace, check observer.
821      * @tc.expected: step5. check observer ok.
822      */
823     triggeredCount_ = 0;
824     sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');";
825     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
826     WaitAndResetNotify();
827     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert
828     EXPECT_EQ(UnRegisterClientObserver(db), OK);
829     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
830 }
831 
832 /**
833  * @tc.name: TriggerObserverTest006
834  * @tc.desc: Test commit and rollback for multi-table then trigger client observer
835  * @tc.type: FUNC
836  * @tc.require:
837  * @tc.author: chenchaohao
838  */
839 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest006, TestSize.Level1)
840 {
841     /**
842      * @tc.steps:step1. prepare data.
843      * @tc.expected: step1. return ok.
844      */
845     const std::string tableName1 = "sync_data1";
846     const std::string tableName2 = "sync_data2";
847     PrepareData({tableName1, tableName2}, false, DistributedDB::CLOUD_COOPERATION, false);
848 
849     /**
850     * @tc.steps:step2. register client observer.
851     * @tc.expected: step2. return ok.
852     */
853     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
854     EXPECT_NE(db, nullptr);
855     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
856         this, std::placeholders::_1);
857     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
858     RegisterDbHook(db);
859 
860     /**
861      * @tc.steps:step3. begin transaction and commit.
862      * @tc.expected: step3. check observer ok.
863      */
864     std::string sql = "insert into " + tableName1 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
865     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
866     WaitAndResetNotify();
867     ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size
868     EXPECT_EQ(triggerTableData_.begin()->first, tableName1);
869     EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
870     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count
871 
872     /**
873      * @tc.steps:step4. UnRegisterClientObserver and insert table2.
874      * @tc.expected: step3. check observer ok.
875      */
876     triggerTableData_.clear();
877     triggeredCount_ = 0;
878     EXPECT_EQ(UnRegisterClientObserver(db), OK);
879     sql = "insert into " + tableName2 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
880     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
881     EXPECT_TRUE(triggerTableData_.empty());
882     EXPECT_EQ(triggeredCount_, 0);
883 
884     /**
885      * @tc.steps:step5. RegisterClientObserver again and insert table1, check observer.
886      * @tc.expected: step5. check observer ok.
887      */
888     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
889     RegisterDbHook(db);
890     sql = "insert into " + tableName1 + " VALUES(7, 'zhangjiu');";
891     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
892     WaitAndResetNotify();
893     ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size
894     EXPECT_EQ(triggerTableData_.begin()->first, tableName1);
895     EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
896     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count
897     EXPECT_EQ(UnRegisterClientObserver(db), OK);
898     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
899 }
900 
901 /**
902  * @tc.name: TriggerObserverTest007
903  * @tc.desc: Test trigger client observer in tracker table
904  * @tc.type: FUNC
905  * @tc.require:
906  * @tc.author: zhangshijie
907  */
908 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest007, TestSize.Level0)
909 {
910     /**
911      * @tc.steps:step1. prepare data and set trackerTable
912      * @tc.expected: step1. return ok.
913      */
914     const std::string tableName = "sync_data";
915     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false, false);
916     SetTracerSchemaTest001(tableName);
917 
918     /**
919     * @tc.steps:step2. register client observer.
920     * @tc.expected: step2. return ok.
921     */
922     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
923     EXPECT_NE(db, nullptr);
924     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
925         this, std::placeholders::_1);
926     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
927     RegisterDbHook(db);
928 
929     /**
930      * @tc.steps:step3. insert data into sync_data, check observer.
931      * @tc.expected: step3. check observer ok.
932      */
933     std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
934     std::unique_lock<std::mutex> lock(g_mutex);
935     ExecSqlAndWaitForObserver(db, sql, lock);
936     ChangeProperties properties;
937     properties.isTrackedDataChange = true;
938     properties.isCloudSyncDataChange = false;
939     int triggerCount = 1;
940     CheckTriggerTableData(1u, tableName, properties, triggerCount);
941 
942     /**
943      * @tc.steps:step4. update data, check observer.
944      * @tc.expected: step4. check observer ok.
945      */
946     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
947     ExecSqlAndWaitForObserver(db, sql, lock);
948     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
949 
950     /**
951      * @tc.steps:step5. update to the same data again, check observer.
952      * @tc.expected: step5. check observer ok.
953      */
954     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
955     ExecSqlAndWaitForObserver(db, sql, lock);
956     properties.isTrackedDataChange = false;
957     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
958 
959     /**
960      * @tc.steps:step6. update to the same data again, set name is NULL, check observer.
961      * @tc.expected: step6. check observer ok.
962      */
963     sql = "update " + tableName + " set name = NULL where id = 2;";
964     ExecSqlAndWaitForObserver(db, sql, lock);
965     properties.isTrackedDataChange = true;
966     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
967 
968     /**
969      * @tc.steps:step7. update to the same data again, set name is empty, check observer.
970      * @tc.expected: step7. check observer ok.
971      */
972     sql = "update " + tableName + " set name = '' where id = 2;";
973     ExecSqlAndWaitForObserver(db, sql, lock);
974     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
975 
976     /**
977      * @tc.steps:step8. delete data, check observer.
978      * @tc.expected: step8. check observer ok.
979      */
980     sql = "delete from " + tableName + " where id = 2;";
981     ExecSqlAndWaitForObserver(db, sql, lock);
982     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
983     EXPECT_EQ(UnRegisterClientObserver(db), OK);
984     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
985 }
986 
987 /**
988  * @tc.name: TriggerObserverTest008
989  * @tc.desc: Test trigger client observer
990  * @tc.type: FUNC
991  * @tc.require:
992  * @tc.author: liaoyonghuang
993  */
994 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest008, TestSize.Level0)
995 {
996     /**
997      * @tc.steps:step1. prepare data
998      * @tc.expected: step1. return ok.
999      */
1000     const std::string tableName1 = "table1";
1001     PrepareData({tableName1}, false, DistributedDB::CLOUD_COOPERATION, false, true);
1002     const std::string tableName2 = "table2";
1003     PrepareData({tableName2}, false, DistributedDB::CLOUD_COOPERATION, false, true);
1004 
1005     /**
1006     * @tc.steps:step2. register client observer.
1007     * @tc.expected: step2. return ok.
1008     */
1009     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1010     EXPECT_NE(db, nullptr);
1011     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
1012         this, std::placeholders::_1);
1013     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
1014 
1015     /**
1016      * @tc.steps:step3. insert data into sync_data, check observer.
1017      * @tc.expected: step3. check observer ok.
1018      */
1019     std::string sql = "insert into " + tableName1 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
1020     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1021     EXPECT_EQ(triggerTableData_.size(), 0u);
1022 
1023     /**
1024      * @tc.steps:step4. re-register client observer and register hook
1025      * @tc.expected: step4. return ok.
1026      */
1027     EXPECT_EQ(UnRegisterClientObserver(db), OK);
1028     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
1029     RegisterDbHook(db);
1030 
1031     /**
1032      * @tc.steps:step5. insert data into sync_data, check observer.
1033      * @tc.expected: step5. check observer ok.
1034      */
1035     sql = "insert into " + tableName2 + " VALUES(4, 'aaa');";
1036     std::unique_lock<std::mutex> lock(g_mutex);
1037     ExecSqlAndWaitForObserver(db, sql, lock);
1038     EXPECT_EQ(triggerTableData_.size(), 1u);
1039     EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
1040     EXPECT_EQ(UnRegisterClientObserver(db), OK);
1041     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1042 }
1043 
InitLogicDeleteData(sqlite3 * & db,const std::string & tableName,uint64_t num)1044 void InitLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t num)
1045 {
1046     for (size_t i = 0; i < num; ++i) {
1047         std::string sql = "insert or replace into " + tableName + " VALUES('" + std::to_string(i) + "', 'zhangsan');";
1048         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1049     }
1050     std::string sql = "update " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log" +
1051         " SET flag = flag | 0x08";
1052     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1053 }
1054 
CheckLogicDeleteData(sqlite3 * & db,const std::string & tableName,uint64_t expectNum)1055 void CheckLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t expectNum)
1056 {
1057     std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log"
1058         " where flag&0x08=0x08 and flag&0x01=0";
1059     sqlite3_stmt *stmt = nullptr;
1060     EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
1061     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1062         uint64_t count = static_cast<uint64_t>(sqlite3_column_int64(stmt, 0));
1063         EXPECT_EQ(count, expectNum);
1064     }
1065     int errCode;
1066     SQLiteUtils::ResetStatement(stmt, true, errCode);
1067     stmt = nullptr;
1068     sql = "select count(*) from " + tableName;
1069     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1070         uint64_t count = static_cast<uint64_t>(sqlite3_column_int64(stmt, 0));
1071         EXPECT_EQ(count, expectNum);
1072     }
1073     SQLiteUtils::ResetStatement(stmt, true, errCode);
1074 }
1075 
1076 /**
1077  * @tc.name: DropDeleteData001
1078  * @tc.desc: Test trigger client observer in tracker table
1079  * @tc.type: FUNC
1080  * @tc.require:
1081  * @tc.author:
1082  */
1083 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DropDeleteData001, TestSize.Level0)
1084 {
1085     /**
1086      * @tc.steps:step1. prepare data.
1087      * @tc.expected: step1. return ok.
1088      */
1089     const std::string tableName = "sync_data";
1090     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1091     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1092     EXPECT_NE(db, nullptr);
1093     uint64_t num = 10;
1094     InitLogicDeleteData(db, tableName, num);
1095 
1096     /**
1097      * @tc.steps:step2. db handle is nullptr
1098      * @tc.expected: step2. return INVALID_ARGS.
1099      */
1100     EXPECT_EQ(DropLogicDeletedData(nullptr, tableName, 0u), INVALID_ARGS);
1101 
1102     /**
1103      * @tc.steps:step3. tableName is empty
1104      * @tc.expected: step3. return INVALID_ARGS.
1105      */
1106     EXPECT_EQ(DropLogicDeletedData(db, "", 0u), INVALID_ARGS);
1107 
1108     /**
1109      * @tc.steps:step4. tableName is no exist
1110      * @tc.expected: step4. return INVALID_ARGS.
1111      */
1112     EXPECT_EQ(DropLogicDeletedData(db, tableName + "_", 0u), DB_ERROR);
1113 
1114     /**
1115      * @tc.steps:step5. cursor is 0
1116      * @tc.expected: step5. return OK.
1117      */
1118     EXPECT_EQ(DropLogicDeletedData(db, tableName, 0u), OK);
1119     CheckLogicDeleteData(db, tableName, 0u);
1120 
1121     /**
1122      * @tc.steps:step6. init data again, and cursor is 15
1123      * @tc.expected: step6. return OK.
1124      */
1125     uint64_t cursor = 15;
1126     InitLogicDeleteData(db, tableName, num);
1127     EXPECT_EQ(DropLogicDeletedData(db, tableName, cursor), OK);
1128     CheckLogicDeleteData(db, tableName, cursor - num);
1129     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1130 }
1131 
1132 /**
1133  * @tc.name: FfrtTest001
1134  * @tc.desc: Test ffrt concurrency
1135  * @tc.type: FUNC
1136  * @tc.require:
1137  * @tc.author:
1138  */
1139 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest001, TestSize.Level1)
1140 {
1141     std::map<int, int> ans;
1142 #ifdef USE_FFRT
1143     ffrt::mutex mutex;
1144 #else
1145     std::mutex mutex;
1146 #endif
1147     size_t num = 1000;
1148 
1149     /**
1150      * @tc.steps:step1. submit insert map task
1151      * @tc.expected: step1. return ok.
1152      */
__anonf66911750d02() 1153     TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1154         for (size_t j = 0; j < num; j++) {
1155             ConcurrentAdapter::AdapterAutoLock(mutex);
1156             for (size_t i = 0; i < num; i++) {
1157                 ans.insert_or_assign(i, i);
1158             }
1159             ConcurrentAdapter::AdapterAutoUnLock(mutex);
1160         }
1161     }, nullptr, &ans);
1162 
1163     /**
1164      * @tc.steps:step2. submit erase map task
1165      * @tc.expected: step2. return ok.
1166      */
__anonf66911750e02() 1167     TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1168         for (size_t i = 0; i < num; i++) {
1169             ConcurrentAdapter::AdapterAutoLock(mutex);
1170             for (auto it = ans.begin(); it != ans.end();) {
1171                 it = ans.erase(it);
1172             }
1173             ConcurrentAdapter::AdapterAutoUnLock(mutex);
1174         }
1175     }, nullptr, &ans);
1176 
1177     /**
1178      * @tc.steps:step3. submit get from map task
1179      * @tc.expected: step3. return ok.
1180      */
__anonf66911750f02() 1181     TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1182         for (size_t i = 0; i < num; i++) {
1183             ConcurrentAdapter::AdapterAutoLock(mutex);
1184             for (auto it = ans.begin(); it != ans.end(); it++) {
1185                 int j = it->first;
1186                 EXPECT_GE(j, 0);
1187             }
1188             ConcurrentAdapter::AdapterAutoUnLock(mutex);
1189         }
1190     }, &ans, nullptr);
1191     ADAPTER_WAIT(h1);
1192     ADAPTER_WAIT(h2);
1193     ADAPTER_WAIT(h3);
1194     ASSERT_TRUE(ans.empty());
1195 }
1196 
1197 /**
1198  * @tc.name: FfrtTest002
1199  * @tc.desc: Test ffrt concurrency
1200  * @tc.type: FUNC
1201  * @tc.require:
1202  * @tc.author:
1203  */
1204 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest002, TestSize.Level1)
1205 {
1206     std::map<int, int> ans;
1207 #ifdef USE_FFRT
1208     ffrt::mutex mutex;
1209 #else
1210     std::mutex mutex;
1211 #endif
1212     size_t num = 1000;
1213 
1214     /**
1215      * @tc.steps:step1. subtask submit insert map task
1216      * @tc.expected: step1. return ok.
1217      */
__anonf66911751002() 1218     TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1219         TaskHandle hh1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1220             for (size_t j = 0; j < num; j++) {
1221                 ConcurrentAdapter::AdapterAutoLock(mutex);
1222                 for (size_t i = 0; i < num; i++) {
1223                     ans.insert_or_assign(i, i);
1224                 }
1225                 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1226             }
1227         }, nullptr, &ans);
1228         ADAPTER_WAIT(hh1);
1229     });
1230 
1231     /**
1232      * @tc.steps:step2. subtask submit erase map task
1233      * @tc.expected: step2. return ok.
1234      */
__anonf66911751202() 1235     TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1236         TaskHandle hh2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1237             for (size_t i = 0; i < num; i++) {
1238                 ConcurrentAdapter::AdapterAutoLock(mutex);
1239                 for (auto it = ans.begin(); it != ans.end();) {
1240                     it = ans.erase(it);
1241                 }
1242                 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1243             }
1244         }, nullptr, &ans);
1245         ADAPTER_WAIT(hh2);
1246     });
1247 
1248     /**
1249      * @tc.steps:step3. subtask submit get from map task
1250      * @tc.expected: step3. return ok.
1251      */
__anonf66911751402() 1252     TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1253         TaskHandle hh3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1254             for (size_t i = 0; i < num; i++) {
1255                 ConcurrentAdapter::AdapterAutoLock(mutex);
1256                 for (auto it = ans.begin(); it != ans.end(); it++) {
1257                     int j = it->first;
1258                     EXPECT_GE(j, 0);
1259                 }
1260                 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1261             }
1262         }, &ans, nullptr);
1263         ADAPTER_WAIT(hh3);
1264     });
1265     ADAPTER_WAIT(h1);
1266     ADAPTER_WAIT(h2);
1267     ADAPTER_WAIT(h3);
1268 }
1269 
1270 /**
1271  * @tc.name: FfrtTest003
1272  * @tc.desc: Test ffrt concurrency
1273  * @tc.type: FUNC
1274  * @tc.require:
1275  * @tc.author:
1276  */
1277 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest003, TestSize.Level1)
1278 {
1279     size_t count = 0;
1280     size_t num = 3000;
1281     std::vector<TaskHandle> waitVec;
1282 
1283     /**
1284      * @tc.steps:step1. submit increase task
1285      * @tc.expected: step1. return ok.
1286      */
1287     for (size_t j = 0; j < num; j++) {
__anonf66911751602() 1288         TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &count, num]() {
1289             for (size_t i = 0; i < num; i++) {
1290                 count++;
1291             }
1292         }, nullptr, nullptr);
1293         waitVec.push_back(std::move(h1));
1294     }
1295     for (const auto &item : waitVec) {
1296         ADAPTER_WAIT(item);
1297     }
1298 
1299     /**
1300      * @tc.steps:step2. check count
1301      * @tc.expected: step2. return ok.
1302      */
1303 #ifdef USE_FFRT
1304     EXPECT_LE(count, num * num);
1305 #else
1306     EXPECT_EQ(count, num * num);
1307 #endif
1308 }
1309 
1310 /**
1311  * @tc.name: AbnormalDelegateTest001
1312  * @tc.desc: Test delegate interface after delegate is closed
1313  * @tc.type: FUNC
1314  * @tc.require:
1315  * @tc.author: chenchaohao
1316  */
1317 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateTest001, TestSize.Level0)
1318 {
1319     /**
1320      * @tc.steps:step1. create db and open store
1321      * @tc.expected: step1. return ok.
1322      */
1323     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1324     ASSERT_NE(db, nullptr);
1325     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1326     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1327     RelationalStoreDelegate *delegate = nullptr;
1328     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1329     EXPECT_EQ(status, OK);
1330     ASSERT_NE(delegate, nullptr);
1331 
1332     /**
1333      * @tc.steps:step2. close delegate
1334      * @tc.expected: step2. return ok.
1335      */
1336     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1337     ClearMetaDataOption option;
1338     EXPECT_EQ(delegateImpl->ClearMetaData(option), OK);
1339     option.tableNameList.insert("asdad");
1340     EXPECT_EQ(delegateImpl->ClearMetaData(option), NOT_SUPPORT);
1341     status = delegateImpl->Close();
1342     EXPECT_EQ(status, OK);
1343 
1344     /**
1345      * @tc.steps:step3. test interface after delegate is closed
1346      * @tc.expected: step3. return ok.
1347      */
1348     const std::string tableName = "sync_data";
1349     EXPECT_EQ(delegateImpl->RemoveDeviceData("", tableName), DB_ERROR);
1350     EXPECT_EQ(delegate->RemoveDeviceData("", FLAG_AND_DATA), DB_ERROR);
1351     EXPECT_EQ(delegate->GetCloudSyncTaskCount(), -1); // -1 is error count
1352     EXPECT_EQ(delegate->CreateDistributedTable(tableName, CLOUD_COOPERATION), DB_ERROR);
1353     EXPECT_EQ(delegate->UnRegisterObserver(), DB_ERROR);
1354     DataBaseSchema dataBaseSchema;
1355     EXPECT_EQ(delegate->SetCloudDbSchema(dataBaseSchema), DB_ERROR);
1356     EXPECT_EQ(delegate->SetReference({}), DB_ERROR);
1357     TrackerSchema trackerSchema;
1358     EXPECT_EQ(delegate->SetTrackerTable(trackerSchema), DB_ERROR);
1359     EXPECT_EQ(delegate->CleanTrackerData(tableName, 0), DB_ERROR);
1360     bool logicDelete = true;
1361     auto data = static_cast<PragmaData>(&logicDelete);
1362     EXPECT_EQ(delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data), DB_ERROR);
1363     std::vector<VBucket> records;
1364     RecordStatus recordStatus = RecordStatus::WAIT_COMPENSATED_SYNC;
1365     EXPECT_EQ(delegate->UpsertData(tableName, records, recordStatus), DB_ERROR);
1366 
1367     /**
1368      * @tc.steps:step4. close store
1369      * @tc.expected: step4. return ok.
1370      */
1371     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1372     delegate = nullptr;
1373 }
1374 
InitDataStatus(const std::string & tableName,int count,sqlite3 * db)1375 void InitDataStatus(const std::string &tableName, int count, sqlite3 *db)
1376 {
1377     int type = 4; // the num of different status
1378     for (int i = 1; i <= type * count; i++) {
1379         std::string sql = "INSERT INTO " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" +
1380             std::to_string(i) + "');";
1381         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1382     }
1383     std::string countStr = std::to_string(count);
1384     std::string sql = "UPDATE " + DBCommon::GetLogTableName(tableName) + " SET status=(CASE WHEN data_key<=" +
1385         countStr + " THEN 0 WHEN data_key>" + countStr + " AND data_key<=2*" + countStr + " THEN 1 WHEN data_key>2*" +
1386         countStr + " AND data_key<=3*" + countStr + " THEN 2 ELSE 3 END)";
1387     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1388 }
1389 
CheckDataStatus(const std::string & tableName,const std::string & condition,sqlite3 * db,int64_t expect)1390 void CheckDataStatus(const std::string &tableName, const std::string &condition, sqlite3 *db, int64_t expect)
1391 {
1392     std::string sql = "SELECT count(1) FROM " + DBCommon::GetLogTableName(tableName) + " WHERE " + condition;
1393     sqlite3_stmt *stmt = nullptr;
1394     EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
1395     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1396         int64_t count = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
1397         EXPECT_EQ(count, expect);
1398     }
1399     int errCode;
1400     SQLiteUtils::ResetStatement(stmt, true, errCode);
1401 }
1402 
1403 /**
1404  * @tc.name: LockDataTest001
1405  * @tc.desc: Test status after lock
1406  * @tc.type: FUNC
1407  * @tc.require:
1408  * @tc.author: bty
1409  */
1410 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest001, TestSize.Level1)
1411 {
1412     /**
1413      * @tc.steps:step1. init data and lock, hashKey has no matching data
1414      * @tc.expected: step1. return NOT_FOUND.
1415      */
1416     const std::string tableName = "sync_data";
1417     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1418     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1419     EXPECT_NE(db, nullptr);
1420     int count = 10;
1421     InitDataStatus(tableName, count, db);
1422     std::vector<std::vector<uint8_t>> hashKey;
1423     hashKey.push_back({'1'});
1424     EXPECT_EQ(Lock(tableName, hashKey, db), NOT_FOUND);
1425 
1426     /**
1427      * @tc.steps:step2. init data and lock, hashKey has matching data
1428      * @tc.expected: step2. return OK.
1429      */
1430     hashKey.clear();
1431     CloudDBSyncUtilsTest::GetHashKey(tableName, " 1=1 ", db, hashKey);
1432     EXPECT_EQ(Lock(tableName, hashKey, db), OK);
1433 
1434     /**
1435      * @tc.steps:step3. check status
1436      * @tc.expected: step3. return OK.
1437      */
1438     CheckDataStatus(tableName, " status = 2 and data_key <= 10 ", db, count);
1439     CheckDataStatus(tableName, " status = 3 and data_key <= 20 ", db, count);
1440     CheckDataStatus(tableName, " status = 2 ", db, count + count);
1441     CheckDataStatus(tableName, " status = 3 ", db, count + count);
1442     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1443 }
1444 
1445 /**
1446  * @tc.name: LockDataTest002
1447  * @tc.desc: Test status after unLock
1448  * @tc.type: FUNC
1449  * @tc.require:
1450  * @tc.author: bty
1451  */
1452 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest002, TestSize.Level1)
1453 {
1454     /**
1455      * @tc.steps:step1. init data and unLock, there is data to be compensated for
1456      * @tc.expected: step1. return WAIT_COMPENSATED_SYNC.
1457      */
1458     const std::string tableName = "sync_data";
1459     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1460     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1461     EXPECT_NE(db, nullptr);
1462     int count = 10;
1463     InitDataStatus(tableName, count, db);
1464     std::vector<std::vector<uint8_t>> hashKey;
1465     CloudDBSyncUtilsTest::GetHashKey(tableName, " 1=1 ", db, hashKey);
1466     EXPECT_EQ(UnLock(tableName, hashKey, db), WAIT_COMPENSATED_SYNC);
1467 
1468     /**
1469      * @tc.steps:step2. check status
1470      * @tc.expected: step2. return OK.
1471      */
1472     CheckDataStatus(tableName, " status = 0 and data_key <= 10 ", db, count);
1473     CheckDataStatus(tableName, " status = 1 and data_key <= 20 ", db, count);
1474     CheckDataStatus(tableName, " status = 0 ", db, count + count);
1475     CheckDataStatus(tableName, " status = 1 ", db, count + count);
1476 
1477     /**
1478      * @tc.steps:step3. unLock again, there is data to be compensated for
1479      * @tc.expected: step3. return WAIT_COMPENSATED_SYNC.
1480      */
1481     EXPECT_EQ(UnLock(tableName, hashKey, db), WAIT_COMPENSATED_SYNC);
1482 
1483     /**
1484      * @tc.steps:step4. unLock again, there is no data to be compensated for
1485      * @tc.expected: step4. return OK.
1486      */
1487     std::string sql = "update " + DBCommon::GetLogTableName(tableName) + " SET status=0";
1488     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1489     EXPECT_EQ(UnLock(tableName, hashKey, db), OK);
1490 
1491     /**
1492      * @tc.steps:step5. unLock again, hashKey has matching data
1493      * @tc.expected: step5. return NOT_FOUND.
1494      */
1495     hashKey.clear();
1496     hashKey.push_back({'1'});
1497     EXPECT_EQ(UnLock(tableName, hashKey, db), NOT_FOUND);
1498     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1499 }
1500 
1501 /**
1502  * @tc.name: LockDataTest003
1503  * @tc.desc: Test status after local change
1504  * @tc.type: FUNC
1505  * @tc.require:
1506  * @tc.author: bty
1507  */
1508 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest003, TestSize.Level0)
1509 {
1510     /**
1511      * @tc.steps:step1. update data and check
1512      * @tc.expected: step1. return E_OK.
1513      */
1514     const std::string tableName = "sync_data";
1515     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1516     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1517     EXPECT_NE(db, nullptr);
1518     int count = 10;
1519     InitDataStatus(tableName, count, db);
1520     std::string sql = "update " + tableName + " SET name='1' where id in (1,11,21,31)";
1521     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1522     CheckDataStatus(tableName, " status = 3 and data_key in (1,11,21,31) ", db, 2); // 2 is changed count
1523 
1524     /**
1525      * @tc.steps:step1. delete data and check
1526      * @tc.expected: step1. return E_OK.
1527      */
1528     sql = "delete from " + tableName + " where id in (2,12,22,32)";
1529     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1530     CheckDataStatus(tableName, " status = 1 and data_key = -1 ", db, 3); // 3 is changed count
1531     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1532 }
1533 
1534 DistributedDB::StoreObserver::StoreChangedInfo g_changedData;
1535 
1536 class MockStoreObserver : public StoreObserver {
1537 public:
~MockStoreObserver()1538     virtual ~MockStoreObserver() {};
OnChange(StoreChangedInfo && data)1539     void OnChange(StoreChangedInfo &&data) override
1540     {
1541         g_changedData = data;
1542         std::unique_lock<std::mutex> lock(g_mutex);
1543         g_cv.notify_one();
1544         g_alreadyNotify = true;
1545     };
1546 };
1547 
CreateTableForStoreObserver(sqlite3 * db,const std::string tableName)1548 void CreateTableForStoreObserver(sqlite3 *db, const std::string tableName)
1549 {
1550     std::string sql = "create table " + tableName + "(id INTEGER primary key, name TEXT);";
1551     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1552     sql = "create table no_" + tableName + "(id INTEGER, name TEXT);";
1553     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1554     sql = "create table mult_" + tableName + "(id INTEGER, name TEXT, age int, ";
1555     sql += "PRIMARY KEY (id, name));";
1556     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1557 }
1558 
PrepareDataForStoreObserver(sqlite3 * db,const std::string & tableName,int begin,int dataCounts)1559 void PrepareDataForStoreObserver(sqlite3 *db, const std::string &tableName, int begin, int dataCounts)
1560 {
1561     std::string sql = "begin;";
1562     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1563     for (int i = begin; i < begin + dataCounts; i++) {
1564         sql = "insert into " + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan" +
1565             std::to_string(i + 1) + "');";
1566         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1567         sql = "insert into no_" + tableName +" VALUES(" + std::to_string(i + 1) + ", 'zhangsan" +
1568             std::to_string(i + 1) + "');";
1569         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1570         sql = "insert into mult_" + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan";
1571         sql += std::to_string(i + 1) + "', 18);";
1572         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1573     }
1574     for (int i = begin; i < dataCounts / 2 + begin; i++) { // 2 is half
1575         sql = "update " + tableName + " set name = 'lisi' where id = " + std::to_string(i + 1) + ";";
1576         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1577         sql = "update no_" + tableName + " set name = 'lisi' where _rowid_ = " + std::to_string(i + 1) + ";";
1578         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1579         sql = "update mult_" + tableName + " set age = 20 where id = " + std::to_string(i + 1);
1580         sql += " and name = 'zhangsan" + std::to_string(i + 1) + "';";
1581         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1582     }
1583     for (int i = dataCounts / 2 + begin; i < dataCounts + begin; i++) { // 2 is half
1584         sql = "delete from " + tableName + " where id = " + std::to_string(i + 1) + ";";
1585         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1586         sql = "delete from no_" + tableName + " where _rowid_ = " + std::to_string(i + 1) + ";";
1587         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1588         sql = "delete from mult_" + tableName + " where id = " + std::to_string(i + 1);
1589         sql += " and name = 'zhangsan" + std::to_string(i + 1) + "';";
1590         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1591     }
1592     sql = "commit;";
1593     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1594 }
1595 
CheckChangedData(int num,int times=0,int offset=0)1596 void CheckChangedData(int num, int times = 0, int offset = 0)
1597 {
1598     if (num == 1) {
1599         for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_INSERT].size(); i++) {
1600             EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_INSERT][i - 1][0]),
1601                 static_cast<int64_t>(i + offset - times * 5)); // 5 is rowid times
1602         }
1603         for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_DELETE].size(); i++) {
1604             EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_DELETE][i - 1][0]),
1605                 static_cast<int64_t>(i + offset + 5)); // 5 is offset
1606         }
1607         return;
1608     }
1609     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_INSERT].size(); i++) {
1610         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_INSERT][i - 1][0]),
1611             static_cast<int64_t>(i + offset));
1612     }
1613     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_UPDATE].size(); i++) {
1614         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_UPDATE][i - 1][0]),
1615             static_cast<int64_t>(i + offset));
1616     }
1617     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_DELETE].size(); i++) {
1618         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_DELETE][i - 1][0]),
1619             static_cast<int64_t>(i + offset + 5)); // 5 is offset
1620     }
1621 }
1622 
1623 /**
1624  * @tc.name: RegisterStoreObserverTest001
1625  * @tc.desc: Test commit for three table then trigger store observer
1626  * @tc.type: FUNC
1627  * @tc.require:
1628  * @tc.author: chenchaohao
1629  */
1630 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest001, TestSize.Level1)
1631 {
1632     /**
1633      * @tc.steps:step1. prepare db and create table.
1634      * @tc.expected: step1. return ok.
1635      */
1636     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1637     EXPECT_NE(db, nullptr);
1638     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1639     std::string tableName = "primary_test";
1640     CreateTableForStoreObserver(db, tableName);
1641 
1642     /**
1643     * @tc.steps:step2. register store observer and check onchange.
1644     * @tc.expected: step2. return ok.
1645     */
1646     auto storeObserver = std::make_shared<MockStoreObserver>();
1647     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1648     RegisterDbHook(db);
1649     EXPECT_TRUE(g_changedData.empty());
1650     int dataCounts = 10; // 10 is count of insert options.
1651     int begin = 0;
1652     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1653     {
1654         std::unique_lock<std::mutex> lock(g_mutex);
__anonf66911751702() 1655         g_cv.wait(lock, []() {
1656             return g_alreadyNotify;
1657         });
1658         g_alreadyNotify = false;
1659     }
1660     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1661     CheckChangedData(0);
1662     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1663     CheckChangedData(1);
1664     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1665     CheckChangedData(2); // 2 is mult primary table
1666     g_changedData.clear();
1667 
1668     /**
1669     * @tc.steps:step3. unregister store observer and update data check onchange.
1670     * @tc.expected: step3. return ok.
1671     */
1672     EXPECT_EQ(UnregisterStoreObserver(db), OK);
1673     begin = 10; // 10 is begin id
1674     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1675     EXPECT_TRUE(g_changedData.empty());
1676     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1677 }
1678 
1679 /**
1680  * @tc.name: RegisterStoreObserverTest002
1681  * @tc.desc: Test commit for three table then trigger client observer when register then create table
1682  * @tc.type: FUNC
1683  * @tc.require:
1684  * @tc.author: chenchaohao
1685  */
1686 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest002, TestSize.Level1)
1687 {
1688     /**
1689      * @tc.steps:step1. prepare db and register store observer then create table.
1690      * @tc.expected: step1. return ok.
1691      */
1692     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1693     EXPECT_NE(db, nullptr);
1694     auto storeObserver = std::make_shared<MockStoreObserver>();
1695     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1696     RegisterDbHook(db);
1697     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1698     std::string tableName = "primary_test";
1699     CreateTableForStoreObserver(db, tableName);
1700 
1701     /**
1702     * @tc.steps:step2. update data and check onchange.
1703     * @tc.expected: step2. return ok.
1704     */
1705     EXPECT_TRUE(g_changedData.empty());
1706     int dataCounts = 10; // 10 is count of insert options.
1707     int begin = 0;
1708     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1709     WaitAndResetNotify();
1710     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1711     CheckChangedData(0);
1712     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1713     CheckChangedData(1);
1714     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1715     CheckChangedData(2); // 2 is mult primary table
1716     g_changedData.clear();
1717 
1718     /**
1719     * @tc.steps:step3. unregister store observer and update data check onchange.
1720     * @tc.expected: step3. return ok.
1721     */
1722     EXPECT_EQ(UnregisterStoreObserver(db), OK);
1723     begin = 10; // 11 is begin id
1724     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1725     EXPECT_TRUE(g_changedData.empty());
1726     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1727 }
1728 
1729 /**
1730  * @tc.name: RegisterStoreObserverTest003
1731  * @tc.desc: Test commit for three table then trigger client observer when register two observer
1732  * @tc.type: FUNC
1733  * @tc.require:
1734  * @tc.author: chenchaohao
1735  */
1736 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest003, TestSize.Level1)
1737 {
1738     /**
1739      * @tc.steps:step1. prepare db and register store observer then create table.
1740      * @tc.expected: step1. return ok.
1741      */
1742     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1743     EXPECT_NE(db, nullptr);
1744     auto storeObserver1 = std::make_shared<MockStoreObserver>();
1745     auto storeObserver2 = std::make_shared<MockStoreObserver>();
1746     EXPECT_EQ(RegisterStoreObserver(db, storeObserver1), OK);
1747     EXPECT_EQ(RegisterStoreObserver(db, storeObserver2), OK);
1748     RegisterDbHook(db);
1749     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1750     std::string tableName = "primary_test";
1751     CreateTableForStoreObserver(db, tableName);
1752 
1753     /**
1754     * @tc.steps:step2. update data and check onchange.
1755     * @tc.expected: step2. return ok.
1756     */
1757     EXPECT_TRUE(g_changedData.empty());
1758     int dataCounts = 10; // 10 is count of insert options.
1759     int begin = 0;
1760     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1761     WaitAndResetNotify();
1762     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1763     CheckChangedData(0);
1764     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1765     CheckChangedData(1);
1766     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1767     CheckChangedData(2); // 2 is mult primary table
1768     g_changedData.clear();
1769 
1770     /**
1771     * @tc.steps:step3. unregister store observer and update data check onchange.
1772     * @tc.expected: step3. return ok.
1773     */
1774     EXPECT_EQ(UnregisterStoreObserver(db, storeObserver1), OK);
1775     begin = 10; // 11 is begin id
1776     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1777     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1778     CheckChangedData(0, 1, dataCounts);
1779     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1780     CheckChangedData(1, 1, dataCounts);
1781     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1782     CheckChangedData(2, 1, dataCounts); // 2 is mult primary table
1783     g_changedData.clear();
1784 
1785     EXPECT_EQ(UnregisterStoreObserver(db, storeObserver2), OK);
1786     begin = 20; // 21 is begin id
1787     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1788     EXPECT_TRUE(g_changedData.empty());
1789     UnregisterDbHook(db);
1790     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1791 }
1792 
1793 /**
1794  * @tc.name: RegisterStoreObserverTest004
1795  * @tc.desc: Test register two same observer
1796  * @tc.type: FUNC
1797  * @tc.require:
1798  * @tc.author: chenchaohao
1799  */
1800 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest004, TestSize.Level1)
1801 {
1802     /**
1803      * @tc.steps:step1. prepare db and register store observer then create table.
1804      * @tc.expected: step1. return ok.
1805      */
1806     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1807     EXPECT_NE(db, nullptr);
1808     auto storeObserver = std::make_shared<MockStoreObserver>();
1809     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1810     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1811     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1812 }
1813 
1814 /**
1815  * @tc.name: AbnormalDelegateImplTest001
1816  * @tc.desc: Test delegateImpl interface after delegate is closed
1817  * @tc.type: FUNC
1818  * @tc.require:
1819  * @tc.author: suyue
1820  */
1821 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateImplTest001, TestSize.Level0)
1822 {
1823     /**
1824      * @tc.steps: step1. create db and open store.
1825      * @tc.expected: step1. return ok.
1826      */
1827     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1828     ASSERT_NE(db, nullptr);
1829     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1830     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1831     RelationalStoreDelegate *delegate = nullptr;
1832     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1833     EXPECT_EQ(status, OK);
1834     ASSERT_NE(delegate, nullptr);
1835 
1836     /**
1837      * @tc.steps: step2. close delegate.
1838      * @tc.expected: step2. return ok.
1839      */
1840     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1841     status = delegateImpl->Close();
1842     EXPECT_EQ(status, OK);
1843 
1844     /**
1845      * @tc.steps: step3. test DelegateImpl interface after delegate is closed.
1846      * @tc.expected: step3. return DB_ERROR.
1847      */
1848     const RemoteCondition condition;
1849     std::shared_ptr<ResultSet> result = nullptr;
1850     DBStatus ret = delegateImpl->RemoteQuery("", condition, 0, result);
1851     EXPECT_EQ(ret, DB_ERROR);
1852     EXPECT_EQ(delegateImpl->RemoveDeviceData(), DB_ERROR);
1853 
1854     StoreObserver observer;
1855     EXPECT_EQ(delegateImpl->RegisterObserver(&observer), DB_ERROR);
1856     EXPECT_EQ(delegateImpl->UnRegisterObserver(&observer), DB_ERROR);
1857     DistributedDB::SqlCondition sqlCondition;
1858     std::vector<VBucket> records = {};
1859     EXPECT_EQ(delegateImpl->ExecuteSql(sqlCondition, records), DB_ERROR);
1860     EXPECT_EQ(delegateImpl->UpsertData("", records, RecordStatus::WAIT_COMPENSATED_SYNC), DB_ERROR);
1861     const CloudSyncConfig config;
1862     EXPECT_EQ(delegateImpl->SetCloudSyncConfig(config), DB_ERROR);
1863 
1864     /**
1865      * @tc.steps: step4. close store.
1866      * @tc.expected: step4. return ok.
1867      */
1868     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1869     delegate = nullptr;
1870 }
1871 
1872 /**
1873  * @tc.name: AbnormalDelegateImplTest002
1874  * @tc.desc: Test delegate interface after delegate is closed
1875  * @tc.type: FUNC
1876  * @tc.require:
1877  * @tc.author: suyue
1878  */
1879 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateImplTest002, TestSize.Level0)
1880 {
1881     /**
1882      * @tc.steps: step1. create db and open store.
1883      * @tc.expected: step1. return ok.
1884      */
1885     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1886     ASSERT_NE(db, nullptr);
1887     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1888     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1889     RelationalStoreDelegate *delegate = nullptr;
1890     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1891     EXPECT_EQ(status, OK);
1892     ASSERT_NE(delegate, nullptr);
1893 
1894     /**
1895      * @tc.steps: step2. test DelegateImpl interface when para is err.
1896      * @tc.expected: step2. return INVALID_ARGS or NOT_FOUND.
1897      */
1898     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1899     const CloudSyncConfig config;
1900     EXPECT_EQ(delegateImpl->SetCloudSyncConfig(config), OK);
1901     DistributedDB::SqlCondition sqlCondition;
1902     std::vector<VBucket> records = {};
1903     EXPECT_EQ(delegateImpl->ExecuteSql(sqlCondition, records), INVALID_ARGS);
1904     EXPECT_EQ(delegateImpl->UpsertData("", records, RecordStatus::WAIT_COMPENSATED_SYNC), INVALID_ARGS);
1905     EXPECT_EQ(delegateImpl->CleanTrackerData("", 0), INVALID_ARGS);
1906     TrackerSchema schema;
1907     EXPECT_EQ(delegateImpl->SetTrackerTable(schema), INVALID_ARGS);
1908     schema = {.tableName = "test", .extendColNames = {}, .trackerColNames = {}};
1909     EXPECT_EQ(delegateImpl->SetTrackerTable(schema), NOT_FOUND);
1910 
1911     /**
1912      * @tc.steps: step3. close store.
1913      * @tc.expected: step3. return ok.
1914      */
1915     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1916     delegate = nullptr;
1917 }
1918 
1919 /**
1920  * @tc.name: FuncExceptionTest001
1921  * @tc.desc: Test the interception expection of the interface
1922  * @tc.type: FUNC
1923  * @tc.require:
1924  * @tc.author: bty
1925  */
1926 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FuncExceptionTest001, TestSize.Level1)
1927 {
1928     std::shared_ptr<StoreObserver> iStoreObserver = nullptr;
1929     EXPECT_EQ(RegisterStoreObserver(nullptr, iStoreObserver), INVALID_ARGS);
1930     EXPECT_EQ(UnregisterStoreObserver(nullptr, iStoreObserver), INVALID_ARGS);
1931     iStoreObserver = std::make_shared<StoreObserver>();
1932     EXPECT_EQ(RegisterStoreObserver(nullptr, iStoreObserver), INVALID_ARGS);
1933     EXPECT_EQ(UnregisterStoreObserver(nullptr, iStoreObserver), INVALID_ARGS);
1934 
1935     EXPECT_EQ(RelationalStoreManager::CalcPrimaryKeyHash({}, {}).size(), 0u);
1936     std::map<std::string, Type> pkMap1 = {{"fielddInt", 0L}};
1937     std::map<std::string, CollateType> ctMap1 = {{"fielddInt", CollateType::COLLATE_BUTT}};
1938     std::vector<uint8_t> result = RelationalStoreManager::CalcPrimaryKeyHash(pkMap1, ctMap1);
1939     EXPECT_TRUE(result.empty());
1940 
1941     std::map<std::string, Type> pkMap2 = {{"FIELDINT", 0L}, {"FIELDSTR", std::string("FIELDSTR")}};
1942     std::map<std::string, CollateType> ctMap2;
1943     ctMap2.insert_or_assign("fieldint", CollateType::COLLATE_BUTT);
1944     ctMap2.insert_or_assign("fieldstr", CollateType::COLLATE_BUTT);
1945     result = RelationalStoreManager::CalcPrimaryKeyHash(pkMap2, ctMap2);
1946     EXPECT_TRUE(result.empty());
1947 
1948     ctMap2.insert_or_assign("fieldint", CollateType::COLLATE_NOCASE);
1949     ctMap2.insert_or_assign("fieldstr", CollateType::COLLATE_NOCASE);
1950     result = RelationalStoreManager::CalcPrimaryKeyHash(pkMap2, ctMap2);
1951     EXPECT_FALSE(result.empty());
1952 
1953     std::map<std::string, std::string> entries2;
1954     pkMap2.insert_or_assign("FIELDINT", entries2);
1955     result = RelationalStoreManager::CalcPrimaryKeyHash(pkMap2, ctMap2);
1956     EXPECT_TRUE(result.empty());
1957 }
1958 
1959 /**
1960  * @tc.name: CleanTest001
1961  * @tc.desc: Test calling the Clean interface twice
1962  * @tc.type: FUNC
1963  * @tc.require:
1964  * @tc.author: suyue
1965  */
1966 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CleanTest001, TestSize.Level0)
1967 {
1968     Logger *loggerInstance = Logger::GetInstance();
1969     ASSERT_NE(loggerInstance, nullptr);
1970     Clean(true);
1971     Clean(false);
1972     loggerInstance = nullptr;
1973     Logger *newLoggerInstance = Logger::GetInstance();
1974     ASSERT_NE(newLoggerInstance, nullptr);
1975 }
1976 
1977 /**
1978  * @tc.name: CreateTempTriggerTest001
1979  * @tc.desc: Test create data change temp trigger.
1980  * @tc.type: FUNC
1981  * @tc.require:
1982  * @tc.author: liaoyonghuang
1983  */
1984 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CreateTempTriggerTest001, TestSize.Level0)
1985 {
1986     /**
1987      * @tc.steps: step1. create db and fts table.
1988      * @tc.expected: step1. return ok.
1989      */
1990     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1991     EXPECT_NE(db, nullptr);
1992     std::string tableName = "table1";
1993     std::string sql = "CREATE VIRTUAL TABLE IF NOT EXISTS " + tableName + " USING fts4(content);";
1994     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
1995     /**
1996      * @tc.steps: step2. create temp trigger on table.
1997      * @tc.expected: step2. return ok.
1998      */
1999     EXPECT_EQ(CreateDataChangeTempTrigger(db), OK);
2000     Clean(false);
2001     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
2002 }
2003 
2004 /**
2005  * @tc.name: CreateTempTriggerTest002
2006  * @tc.desc: Test create data change temp trigger
2007  * @tc.type: FUNC
2008  * @tc.require:
2009  * @tc.author: liaoyonghuang
2010  */
2011 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CreateTempTriggerTest002, TestSize.Level0)
2012 {
2013     /**
2014      * @tc.steps: step1. create db and fts table.
2015      * @tc.expected: step1. return ok.
2016      */
2017     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
2018     EXPECT_NE(db, nullptr);
2019     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
2020     std::string tableName = "table1";
2021     std::string sql = "create virtual table if not exists " + tableName + " using fts4(content);";
2022     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
2023     /**
2024      * @tc.steps: step2. create temp trigger on table.
2025      * @tc.expected: step2. return ok.
2026      */
2027     auto storeObserver = std::make_shared<MockStoreObserver>();
2028     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
2029     RegisterDbHook(db);
2030     g_changedData.clear();
2031     /**
2032      * @tc.steps: step3. insert data and check changed data.
2033      * @tc.expected: step3. return ok.
2034      */
2035     sql = "insert into " + tableName + "_content values(1, '123456');";
2036     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
2037     ASSERT_EQ(g_changedData.size(), 1u);
2038     EXPECT_EQ(g_changedData.front().tableName, tableName + "_content");
2039     ASSERT_EQ(g_changedData.front().primaryData[OP_INSERT].size(), 1u);
2040     EXPECT_EQ(UnregisterStoreObserver(db, storeObserver), OK);
2041     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
2042 }
2043 
2044 /**
2045  * @tc.name: CreateTempTriggerTest003
2046  * @tc.desc: Test monitoring of virtual table data
2047  * @tc.type: FUNC
2048  * @tc.require:
2049  * @tc.author: liaoyonghuang
2050  */
2051 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CreateTempTriggerTest003, TestSize.Level0)
2052 {
2053     /**
2054      * @tc.steps: step1. create db and fts table.
2055      * @tc.expected: step1. return ok.
2056      */
2057     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
2058     EXPECT_NE(db, nullptr);
2059     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
2060     std::string tableName = "table1";
2061     std::string sql = "create virtual table if not exists " + tableName + " using fts4(content);";
2062     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
2063     /**
2064      * @tc.steps: step2. create temp trigger on table.
2065      * @tc.expected: step2. return ok.
2066      */
2067     auto storeObserver = std::make_shared<MockStoreObserver>();
2068     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
2069     RegisterDbHook(db);
2070     g_changedData.clear();
2071     /**
2072      * @tc.steps: step3. insert data and check changed data.
2073      * @tc.expected: step3. return ok.
2074      */
2075     sql = "insert into " + tableName + " values(12345);";
2076     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
2077     ASSERT_FALSE(g_changedData.empty());
2078     EXPECT_EQ(g_changedData.front().tableName, tableName + "_content");
2079     ASSERT_EQ(g_changedData.front().primaryData[OP_INSERT].size(), 1u);
2080     EXPECT_EQ(UnregisterStoreObserver(db, storeObserver), OK);
2081     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
2082 }
2083 }
2084