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