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