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, .extendColName = EXTEND_COL_NAME2, .trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2
86 };
87 TrackerSchema g_normalSchema2 = {
88 .tableName = TABLE_NAME2, .extendColName = EXTEND_COL_NAME3, .trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2
89 };
90 TrackerSchema g_normalSchema3 = {
91 .tableName = TABLE_NAME2, .extendColName = 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)142 void CheckExtendAndCursor(uint64_t num, int start)
143 {
144 int index = 0;
145 string querySql = "select extend_field, cursor from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
146 " where data_key <= " + std::to_string(num);
147 sqlite3_stmt *stmt = nullptr;
148 EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
149 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
150 std::string extendVal;
151 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
152 ASSERT_NE(num, 0u);
153 EXPECT_EQ(extendVal, "Local" + std::to_string(index % num));
154 std::string cursorVal;
155 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
156 EXPECT_EQ(cursorVal, std::to_string(num + (++index) + start));
157 }
158 int errCode;
159 SQLiteUtils::ResetStatement(stmt, true, errCode);
160 }
161
OpenStore()162 void OpenStore()
163 {
164 if (g_db == nullptr) {
165 g_db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
166 ASSERT_NE(g_db, nullptr);
167 }
168 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, g_delegate);
169 EXPECT_EQ(status, OK);
170 ASSERT_NE(g_delegate, nullptr);
171 }
172
CloseStore()173 void CloseStore()
174 {
175 if (g_db != nullptr) {
176 EXPECT_EQ(sqlite3_close_v2(g_db), SQLITE_OK);
177 g_db = nullptr;
178 }
179 if (g_delegate != nullptr) {
180 EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
181 g_delegate = nullptr;
182 }
183 }
184
CheckDropTableAndReopenDb(bool isDistributed)185 void CheckDropTableAndReopenDb(bool isDistributed)
186 {
187 /**
188 * @tc.steps:step1. SetTrackerTable, init data and drop table
189 * @tc.expected: step1. Return OK.
190 */
191 CreateMultiTable();
192 OpenStore();
193 if (isDistributed) {
194 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
195 }
196 TrackerSchema schema = g_normalSchema1;
197 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
198 uint64_t num = 10;
199 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
200 std::string sql = "drop table if exists " + TABLE_NAME2;
201 EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
202 CloseStore();
203
204 /**
205 * @tc.steps:step2. reopen db, check log table
206 * @tc.expected: step2. Return OK.
207 */
208 OpenStore();
209 sql = "select count(*) from sqlite_master where name = '" + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 +
210 "_log'";
211 EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
212 reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
213
214 /**
215 * @tc.steps:step3. check tracker schema
216 * @tc.expected: step3. Return OK.
217 */
218 const Key schemaKey(DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY.begin(),
219 DBConstant::RELATIONAL_TRACKER_SCHEMA_KEY.end());
220 sql = "SELECT value FROM " + DBConstant::RELATIONAL_PREFIX + "metadata WHERE key=?;";
221 sqlite3_stmt *stmt = nullptr;
222 EXPECT_EQ(SQLiteUtils::GetStatement(g_db, sql, stmt), E_OK);
223 EXPECT_EQ(SQLiteUtils::BindBlobToStatement(stmt, 1, schemaKey, false), E_OK);
224 Value schemaVal;
225 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
226 SQLiteUtils::GetColumnBlobValue(stmt, 0, schemaVal);
227 }
228 EXPECT_TRUE(schemaVal.size() != 0);
229 int errCode;
230 SQLiteUtils::ResetStatement(stmt, true, errCode);
231 std::string schemaStr;
232 DBCommon::VectorToString(schemaVal, schemaStr);
233 RelationalSchemaObject schemaObject;
234 EXPECT_EQ(schemaObject.ParseFromTrackerSchemaString(schemaStr), E_OK);
235 EXPECT_EQ(schemaObject.GetTrackerTable(TABLE_NAME2).IsEmpty(), true);
236 CloseStore();
237 }
238
239 class DistributedDBInterfacesRelationalTrackerTableTest : public testing::Test {
240 public:
241 static void SetUpTestCase(void);
242
243 static void TearDownTestCase(void);
244
245 void SetUp();
246
247 void TearDown();
248 };
249
SetUpTestCase(void)250 void DistributedDBInterfacesRelationalTrackerTableTest::SetUpTestCase(void)
251 {
252 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
253 LOGD("Test dir is %s", g_testDir.c_str());
254 g_dbDir = g_testDir + "/";
255 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
256 }
257
TearDownTestCase(void)258 void DistributedDBInterfacesRelationalTrackerTableTest::TearDownTestCase(void)
259 {
260 }
261
SetUp(void)262 void DistributedDBInterfacesRelationalTrackerTableTest::SetUp(void)
263 {
264 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
265 LOGE("rm test db files error.");
266 }
267 DistributedDBToolsUnitTest::PrintTestCaseInfo();
268 }
269
TearDown(void)270 void DistributedDBInterfacesRelationalTrackerTableTest::TearDown(void)
271 {
272 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
273 }
274
SetTrackerTableTest(const TrackerSchema & schema,DBStatus expect)275 void SetTrackerTableTest(const TrackerSchema &schema, DBStatus expect)
276 {
277 CreateMultiTable();
278 OpenStore();
279 EXPECT_EQ(g_delegate->SetTrackerTable(schema), expect);
280 CloseStore();
281 }
282
283 /**
284 * @tc.name: TrackerTableTest001
285 * @tc.desc: Test set tracker table with invalid table name
286 * @tc.type: FUNC
287 * @tc.require:
288 * @tc.author: bty
289 */
290 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest001, TestSize.Level0)
291 {
292 CreateMultiTable();
293 OpenStore();
294 /**
295 * @tc.steps:step1. table name is empty
296 * @tc.expected: step1. Return INVALID_ARGS.
297 */
298 TrackerSchema schema;
299 EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
300
301 /**
302 * @tc.steps:step2. table name is no exist
303 * @tc.expected: step2. Return NOT_FOUND.
304 */
305 schema.tableName = "xx";
306 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
307
308 /**
309 * @tc.steps:step3. table name is illegal table name
310 * @tc.expected: step3. Return INVALID_ARGS.
311 */
312 schema.tableName = DBConstant::SYSTEM_TABLE_PREFIX + "_1";
313 EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
314 CloseStore();
315 }
316
317 /**
318 * @tc.name: TrackerTableTest002
319 * @tc.desc: Test set tracker table with empty colNames
320 * @tc.type: FUNC
321 * @tc.require:
322 * @tc.author: bty
323 */
324 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest002, TestSize.Level0)
325 {
326 /**
327 * @tc.steps:step1. trackerColNames is empty
328 * @tc.expected: step1. Return OK.
329 */
330 TrackerSchema schema;
331 schema.tableName = TABLE_NAME1;
332 SetTrackerTableTest(schema, OK);
333
334 /**
335 * @tc.steps:step2. trackerColNames is empty but extendColName is no exist
336 * @tc.expected: step2. Return OK.
337 */
338 schema.extendColName = EXTEND_COL_NAME1;
339 SetTrackerTableTest(schema, OK);
340
341 /**
342 * @tc.steps:step1. param valid but extend name is empty
343 * @tc.expected: step1. Return OK.
344 */
345 schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
346 schema.extendColName = {};
347 SetTrackerTableTest(schema, OK);
348 }
349
350 /**
351 * @tc.name: TrackerTableTest003
352 * @tc.desc: Test set tracker table with invalid col name
353 * @tc.type: FUNC
354 * @tc.require:
355 * @tc.author: bty
356 */
357 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest003, TestSize.Level0)
358 {
359 /**
360 * @tc.steps:step1. tracker col name is no exist
361 * @tc.expected: step1. Return SCHEMA_MISMATCH.
362 */
363 TrackerSchema schema;
364 schema.tableName = TABLE_NAME1;
365 schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET1;
366 SetTrackerTableTest(schema, SCHEMA_MISMATCH);
367
368 /**
369 * @tc.steps:step2. tracker col names contains empty name
370 * @tc.expected: step2. Return INVALID_ARGS.
371 */
372 schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET5;
373 SetTrackerTableTest(schema, INVALID_ARGS);
374
375 /**
376 * @tc.steps:step3. extend name is no exist
377 * @tc.expected: step3. Return SCHEMA_MISMATCH.
378 */
379 schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
380 schema.extendColName = EXTEND_COL_NAME1;
381 SetTrackerTableTest(schema, SCHEMA_MISMATCH);
382 }
383
384 /**
385 * @tc.name: TrackerTableTest005
386 * @tc.desc: Test set tracker table in same delegate
387 * @tc.type: FUNC
388 * @tc.require:
389 * @tc.author: bty
390 */
391 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest005, TestSize.Level0)
392 {
393 /**
394 * @tc.steps:step1. SetTrackerTable twice in same delegate
395 * @tc.expected: step1. Return WITH_INVENTORY_DATA for the first time, return OK again
396 */
397 TrackerSchema schema = g_normalSchema1;
398 CreateMultiTable();
399 OpenStore();
400 uint64_t num = 10;
401 BatchInsertTableName2Data(num);
402 EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
403 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
404 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
405
406 /**
407 * @tc.steps:step2. SetTrackerTable again with different schema
408 * @tc.expected: step2. Return OK.
409 */
410 schema = g_normalSchema3;
411 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
412 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
413 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
414
415 /**
416 * @tc.steps:step3. SetTrackerTable again with different table
417 * @tc.expected: step3. Return OK.
418 */
419 schema.tableName = TABLE_NAME1;
420 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
421 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
422
423 /**
424 * @tc.steps:step4. unSetTrackerTable
425 * @tc.expected: step4. Return OK.
426 */
427 schema.tableName = TABLE_NAME2;
428 schema.trackerColNames = {};
429 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
430 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
431 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
432 CloseStore();
433 }
434
435 /**
436 * @tc.name: TrackerTableTest006
437 * @tc.desc: Test set tracker table in diff delegate
438 * @tc.type: FUNC
439 * @tc.require:
440 * @tc.author: bty
441 */
442 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest006, TestSize.Level0)
443 {
444 /**
445 * @tc.steps:step1. SetTrackerTable
446 * @tc.expected: step1. Return OK.
447 */
448 TrackerSchema schema = g_normalSchema1;
449 CreateMultiTable();
450 OpenStore();
451 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
452 uint64_t num = 10;
453 BatchInsertTableName2Data(num);
454 CloseStore();
455
456 /**
457 * @tc.steps:step2. reopen db and SetTrackerTable
458 * @tc.expected: step2. Return OK.
459 */
460 OpenStore();
461 schema = g_normalSchema2;
462 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
463 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
464 CloseStore();
465
466 /**
467 * @tc.steps:step3. reopen db and SetTrackerTable with diff table
468 * @tc.expected: step3. Return OK.
469 */
470 OpenStore();
471 schema.tableName = TABLE_NAME1;
472 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
473 CloseStore();
474
475 /**
476 * @tc.steps:step4. reopen db and unSetTrackerTable
477 * @tc.expected: step4. Return OK.
478 */
479 OpenStore();
480 schema.trackerColNames = {};
481 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
482 CloseStore();
483 }
484
485 /**
486 * @tc.name: TrackerTableTest007
487 * @tc.desc: Test set tracker table to upgrade inventory data
488 * @tc.type: FUNC
489 * @tc.require:
490 * @tc.author: bty
491 */
492 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest007, TestSize.Level0)
493 {
494 /**
495 * @tc.steps:step1. SetTrackerTable when the db exist data
496 * @tc.expected: step1. Return WITH_INVENTORY_DATA.
497 */
498 uint64_t num = 10;
499 CreateMultiTable();
500 BatchInsertTableName2Data(num);
501 OpenStore();
502 TrackerSchema schema = g_normalSchema3;
503 EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
504
505 /**
506 * @tc.steps:step2. SetTrackerTable again with diff tracker schema
507 * @tc.expected: step2. Return OK.
508 */
509 schema = g_normalSchema1;
510 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
511
512 /**
513 * @tc.steps:step3. check extend_field and cursor
514 * @tc.expected: step3. Return OK.
515 */
516 CheckExtendAndCursor(num, 0);
517
518 /**
519 * @tc.steps:step4. update extend field and check
520 * @tc.expected: step4. Return OK.
521 */
522 EXPECT_EQ(g_delegate->SetTrackerTable(g_normalSchema3), OK);
523 std::string sql = "UPDATE " + TABLE_NAME2 + " SET age='666'";
524 EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
525 sql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) +
526 " where extend_field=666;";
527 EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
528 reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
529 CloseStore();
530 }
531
532 /**
533 * @tc.name: TrackerTableTest008
534 * @tc.desc: Test set tracker table to check extend_field and cursor
535 * @tc.type: FUNC
536 * @tc.require:
537 * @tc.author: bty
538 */
539 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest008, TestSize.Level0)
540 {
541 /**
542 * @tc.steps:step1. SetTrackerTable on table2
543 * @tc.expected: step1. Return WITH_INVENTORY_DATA.
544 */
545 uint64_t num = 10;
546 CreateMultiTable();
547 BatchInsertTableName2Data(num);
548 OpenStore();
549 TrackerSchema schema = g_normalSchema1;
550 EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
551
552 /**
553 * @tc.steps:step2. Update non tracker columns,then check extend_field and cursor
554 * @tc.expected: step2. Return OK.
555 */
556 uint64_t updateNum = 2;
557 BatchUpdateTableName2Data(updateNum, LOCAL_TABLE_TRACKER_NAME_SET3);
558 int index = 0;
559 string querySql = "select extend_field, cursor from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
560 " where data_key <= " + std::to_string(updateNum);
561 sqlite3_stmt *stmt = nullptr;
562 EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
563 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
564 std::string extendVal;
565 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
566 EXPECT_EQ(extendVal, "Local" + std::to_string(index % num));
567 std::string cursorVal;
568 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
569 EXPECT_EQ(cursorVal, std::to_string(++index));
570 }
571 int errCode;
572 SQLiteUtils::ResetStatement(stmt, true, errCode);
573
574 /**
575 * @tc.steps:step3. Update tracker columns,then check extend_field and cursor
576 * @tc.expected: step3. Return OK.
577 */
578 BatchUpdateTableName2Data(updateNum, LOCAL_TABLE_TRACKER_NAME_SET2);
579 stmt = nullptr;
580 index = 0;
581 EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
582 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
583 std::string extendVal;
584 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
585 EXPECT_EQ(extendVal, "1");
586 std::string cursorVal;
587 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, cursorVal), E_OK);
588 EXPECT_EQ(cursorVal, std::to_string(num + (++index)));
589 }
590 SQLiteUtils::ResetStatement(stmt, true, errCode);
591 CloseStore();
592 }
593
594 /**
595 * @tc.name: TrackerTableTest009
596 * @tc.desc: Test set tracker table to check extend_field and cursor after delete
597 * @tc.type: FUNC
598 * @tc.require:
599 * @tc.author: bty
600 */
601 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest009, TestSize.Level0)
602 {
603 /**
604 * @tc.steps:step1. SetTrackerTable on table2
605 * @tc.expected: step1. Return WITH_INVENTORY_DATA.
606 */
607 uint64_t num = 10;
608 CreateMultiTable();
609 BatchInsertTableName2Data(num);
610 OpenStore();
611 TrackerSchema schema = g_normalSchema1;
612 EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
613
614 /**
615 * @tc.steps:step2. select extend_field and cursor after delete
616 * @tc.expected: step2. Return OK.
617 */
618 BatchDeleteTableName2Data(num);
619 CheckExtendAndCursor(num, 0);
620 CloseStore();
621 }
622
623 /**
624 * @tc.name: TrackerTableTest010
625 * @tc.desc: Test set tracker table after unSetTrackerTable
626 * @tc.type: FUNC
627 * @tc.require:
628 * @tc.author: bty
629 */
630 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest010, TestSize.Level0)
631 {
632 /**
633 * @tc.steps:step1. SetTrackerTable on table2
634 * @tc.expected: step1. Return OK.
635 */
636 CreateMultiTable();
637 OpenStore();
638 TrackerSchema schema = g_normalSchema1;
639 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
640
641 /**
642 * @tc.steps:step2. unSetTrackerTable
643 * @tc.expected: step2. Return OK.
644 */
645 schema.trackerColNames = {};
646 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
647
648 /**
649 * @tc.steps:step3. SetTrackerTable again
650 * @tc.expected: step3. Return OK.
651 */
652 schema.trackerColNames = LOCAL_TABLE_TRACKER_NAME_SET2;
653 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
654
655 /**
656 * @tc.steps:step4. operator data
657 * @tc.expected: step4. Return OK.
658 */
659 uint64_t num = 10;
660 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
661 CloseStore();
662 }
663
664 /**
665 * @tc.name: TrackerTableTest011
666 * @tc.desc: Test CreateDistributedTable after set tracker table
667 * @tc.type: FUNC
668 * @tc.require:
669 * @tc.author: bty
670 */
671 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest011, TestSize.Level0)
672 {
673 /**
674 * @tc.steps:step1. SetTrackerTable on table2
675 * @tc.expected: step1. Return OK.
676 */
677 CreateMultiTable();
678 OpenStore();
679 TrackerSchema schema = g_normalSchema1;
680 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
681
682 /**
683 * @tc.steps:step2. CreateDistributedTable on table2 and insert data
684 * @tc.expected: step2. Return OK.
685 */
686 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
687 uint64_t num = 10;
688 BatchInsertTableName2Data(num);
689
690 /**
691 * @tc.steps:step3. CreateDistributedTable on table2 again, but schema not change
692 * @tc.expected: step3. Return OK.
693 */
694 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
695 CheckExtendAndCursor(num, -num);
696
697 /**
698 * @tc.steps:step4. operator data on table2
699 * @tc.expected: step4. Return OK.
700 */
701 std::string sql = "ALTER TABLE " + TABLE_NAME2 + " ADD COLUMN xxx INT";
702 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(g_db, sql), E_OK);
703 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
704 CheckExtendAndCursor(num, 0);
705
706 /**
707 * @tc.steps:step5. unSetTrackerTable
708 * @tc.expected: step5. Return OK.
709 */
710 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
711 schema.trackerColNames = {};
712 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
713
714 /**
715 * @tc.steps:step6. operator data on table2
716 * @tc.expected: step6. Return OK.
717 */
718 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
719 CloseStore();
720 }
721
722 /**
723 * @tc.name: TrackerTableTest012
724 * @tc.desc: Test CreateDistributedTable after set tracker table
725 * @tc.type: FUNC
726 * @tc.require:
727 * @tc.author: bty
728 */
729 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest012, TestSize.Level0)
730 {
731 /**
732 * @tc.steps:step1. SetTrackerTable on table2
733 * @tc.expected: step1. Return OK.
734 */
735 CreateMultiTable();
736 OpenStore();
737 TrackerSchema schema = g_normalSchema1;
738 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
739
740 /**
741 * @tc.steps:step2. CreateDistributedTable on table2 without data
742 * @tc.expected: step2. Return OK.
743 */
744 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
745
746 /**
747 * @tc.steps:step3. CreateDistributedTable on table1
748 * @tc.expected: step3. Return OK.
749 */
750 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME1, CLOUD_COOPERATION), DBStatus::OK);
751
752 /**
753 * @tc.steps:step4. operator data on table2
754 * @tc.expected: step4. Return OK.
755 */
756 uint64_t num = 10;
757 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
758
759 /**
760 * @tc.steps:step5. unSetTrackerTable
761 * @tc.expected: step5. Return OK.
762 */
763 schema.trackerColNames = {};
764 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
765
766 /**
767 * @tc.steps:step6. operator data on table2
768 * @tc.expected: step6. Return OK.
769 */
770 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
771 CloseStore();
772 }
773
774 /**
775 * @tc.name: TrackerTableTest013
776 * @tc.desc: Test CreateDistributedTable after clean table data
777 * @tc.type: FUNC
778 * @tc.require:
779 * @tc.author: bty
780 */
781 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest013, TestSize.Level0)
782 {
783 /**
784 * @tc.steps:step1. init data and SetTrackerTable on table2
785 * @tc.expected: step1. Return WITH_INVENTORY_DATA.
786 */
787 uint64_t num = 10;
788 CreateMultiTable();
789 BatchInsertTableName2Data(num);
790 OpenStore();
791 TrackerSchema schema = g_normalSchema1;
792 EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
793
794 /**
795 * @tc.steps:step2. CreateDistributedTable on table2
796 * @tc.expected: step2. Return NOT_SUPPORT.
797 */
798 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
799
800 /**
801 * @tc.steps:step3. delete all data but keep the log , then CreateDistributedTable
802 * @tc.expected: step3. Return OK.
803 */
804 BatchDeleteTableName2Data(num);
805 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), OK);
806 BatchInsertTableName2Data(num);
807 CloseStore();
808 }
809
810 /**
811 * @tc.name: TrackerTableTest014
812 * @tc.desc: Test SetTrackerTable after CreateDistributedTable
813 * @tc.type: FUNC
814 * @tc.require:
815 * @tc.author: bty
816 */
817 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest014, TestSize.Level0)
818 {
819 /**
820 * @tc.steps:step1. CreateDistributedTable on table2
821 * @tc.expected: step1. Return OK.
822 */
823 CreateMultiTable();
824 OpenStore();
825 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
826
827 /**
828 * @tc.steps:step2. SetTrackerTable on table2
829 * @tc.expected: step2. Return OK.
830 */
831 TrackerSchema schema = g_normalSchema1;
832 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
833
834 /**
835 * @tc.steps:step3. operator data and check extend_filed and cursor
836 * @tc.expected: step3. Return OK.
837 */
838 uint64_t num = 10;
839 int begin = -10;
840 BatchInsertTableName2Data(num);
841 CheckExtendAndCursor(num, begin);
842 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
843
844 /**
845 * @tc.steps:step4. unSetTrackerTable
846 * @tc.expected: step4. Return OK.
847 */
848 schema.trackerColNames = {};
849 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
850 CloseStore();
851 }
852
853 /**
854 * @tc.name: TrackerTableTest015
855 * @tc.desc: Test operator data on Distributed tracker table
856 * @tc.type: FUNC
857 * @tc.require:
858 * @tc.author: bty
859 */
860 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest015, TestSize.Level0)
861 {
862 /**
863 * @tc.steps:step1. CreateDistributedTable on table2
864 * @tc.expected: step1. Return OK.
865 */
866 CreateMultiTable();
867 OpenStore();
868 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
869
870 /**
871 * @tc.steps:step2. operator data
872 * @tc.expected: step2. Return OK.
873 */
874 uint64_t num = 10;
875 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
876
877 /**
878 * @tc.steps:step3. SetTrackerTable on table2
879 * @tc.expected: step3. Return WITH_INVENTORY_DATA.
880 */
881 TrackerSchema schema = g_normalSchema1;
882 EXPECT_EQ(g_delegate->SetTrackerTable(schema), WITH_INVENTORY_DATA);
883 string querySql = "select extend_field from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
884 " where data_key = 15;";
885 sqlite3_stmt *stmt = nullptr;
886 EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
887 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
888 std::string extendVal;
889 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, extendVal), E_OK);
890 EXPECT_EQ(extendVal, "Local4");
891 }
892 int errCode;
893 SQLiteUtils::ResetStatement(stmt, true, errCode);
894
895 /**
896 * @tc.steps:step4. operator data
897 * @tc.expected: step4. Return OK.
898 */
899 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
900 CloseStore();
901 }
902
903 /**
904 * @tc.name: TrackerTableTest016
905 * @tc.desc: Test operator data on tracker Distributed table
906 * @tc.type: FUNC
907 * @tc.require:
908 * @tc.author: bty
909 */
910 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest016, TestSize.Level0)
911 {
912 /**
913 * @tc.steps:step1. SetTrackerTable on table2
914 * @tc.expected: step1. Return OK.
915 */
916 CreateMultiTable();
917 OpenStore();
918 TrackerSchema schema = g_normalSchema1;
919 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
920
921 /**
922 * @tc.steps:step2. reopen store and create distributed table
923 * @tc.expected: step2. Return OK.
924 */
925 CloseStore();
926 OpenStore();
927 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
928
929 /**
930 * @tc.steps:step3. operator data
931 * @tc.expected: step3. Return OK.
932 */
933 uint64_t num = 10;
934 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET2);
935 CloseStore();
936 }
937
938 /**
939 * @tc.name: TrackerTableTest017
940 * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
941 * @tc.type: FUNC
942 * @tc.require:
943 * @tc.author: bty
944 */
945 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest017, TestSize.Level0)
946 {
947 /**
948 * @tc.steps:step1. SetTrackerTable on table2
949 * @tc.expected: step1. Return OK.
950 */
951 CreateMultiTable();
952 OpenStore();
953 TrackerSchema schema = g_normalSchema1;
954 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
955
956 /**
957 * @tc.steps:step2. Create DEVICE_COOPERATION DistributedTable
958 * @tc.expected: step2. Return NOT_SUPPORT.
959 */
960 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::NOT_SUPPORT);
961
962 /**
963 * @tc.steps:step3. operator data on table2
964 * @tc.expected: step3. Return OK.
965 */
966 uint64_t num = 10;
967 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
968
969 /**
970 * @tc.steps:step4. unSetTrackerTable
971 * @tc.expected: step4. Return OK.
972 */
973 schema.trackerColNames = {};
974 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
975
976 /**
977 * @tc.steps:step5. There is still data in the table
978 * @tc.expected: step5. Return NOT_SUPPORT.
979 */
980 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), OK);
981
982 /**
983 * @tc.steps:step6. clear all data and create DEVICE_COOPERATION table
984 * @tc.expected: step6. Return OK.
985 */
986 BatchDeleteTableName2Data(num + num);
987 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), OK);
988
989 /**
990 * @tc.steps:step7. operator data on table2
991 * @tc.expected: step7. Return OK.
992 */
993 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
994 CloseStore();
995 }
996
997 /**
998 * @tc.name: TrackerTableTest018
999 * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
1000 * @tc.type: FUNC
1001 * @tc.require:
1002 * @tc.author: bty
1003 */
1004 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest018, TestSize.Level0)
1005 {
1006 /**
1007 * @tc.steps:step1. Create DEVICE_COOPERATION DistributedTable
1008 * @tc.expected: step1. Return OK.
1009 */
1010 CreateMultiTable();
1011 OpenStore();
1012 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, DEVICE_COOPERATION), DBStatus::OK);
1013
1014 /**
1015 * @tc.steps:step2. SetTrackerTable on table2
1016 * @tc.expected: step2. Return NOT_SUPPORT.
1017 */
1018 TrackerSchema schema = g_normalSchema1;
1019 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_SUPPORT);
1020
1021 /**
1022 * @tc.steps:step3. operator data on table2
1023 * @tc.expected: step3. Return OK.
1024 */
1025 uint64_t num = 10;
1026 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1027
1028 /**
1029 * @tc.steps:step4. unSetTrackerTable
1030 * @tc.expected: step4. Return NOT_SUPPORT.
1031 */
1032 schema.trackerColNames = {};
1033 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_SUPPORT);
1034
1035 /**
1036 * @tc.steps:step5. operator data on table2
1037 * @tc.expected: step5. Return OK.
1038 */
1039 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1040 CloseStore();
1041 }
1042
1043 /**
1044 * @tc.name: TrackerTableTest019
1045 * @tc.desc: Test set tracker table with DEVICE_COOPERATION mode
1046 * @tc.type: FUNC
1047 * @tc.require:
1048 * @tc.author: bty
1049 */
1050 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest019, TestSize.Level0)
1051 {
1052 /**
1053 * @tc.steps:step1. SetTrackerTable
1054 * @tc.expected: step1. Return OK.
1055 */
1056 CreateMultiTable();
1057 OpenStore();
1058 TrackerSchema schema = g_normalSchema1;
1059 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1060
1061 /**
1062 * @tc.steps:step2. CleanTrackerData with table name no exist
1063 * @tc.expected: step2. Return DB_ERROR.
1064 */
1065 uint64_t num = 10;
1066 BatchInsertTableName2Data(num);
1067 BatchDeleteTableName2Data(num / HALF);
1068 EXPECT_EQ(g_delegate->CleanTrackerData("xx", num), DB_ERROR);
1069
1070 /**
1071 * @tc.steps:step3. CleanTrackerData with empty table name
1072 * @tc.expected: step3. Return INVALID_ARGS.
1073 */
1074 EXPECT_EQ(g_delegate->CleanTrackerData("", num), INVALID_ARGS);
1075
1076 /**
1077 * @tc.steps:step4. CleanTrackerData
1078 * @tc.expected: step4. Return OK.
1079 */
1080 EXPECT_EQ(g_delegate->CleanTrackerData(TABLE_NAME2, num + (num / HALF)), OK);
1081 std::string sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
1082 " where extend_field is NULL;";
1083 EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1084 reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1085 CloseStore();
1086 }
1087
1088 /**
1089 * @tc.name: TrackerTableTest020
1090 * @tc.desc: Test drop and rebuild table in same delegate
1091 * @tc.type: FUNC
1092 * @tc.require:
1093 * @tc.author: bty
1094 */
1095 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest020, TestSize.Level0)
1096 {
1097 /**
1098 * @tc.steps:step1. SetTrackerTable and init data
1099 * @tc.expected: step1. Return OK.
1100 */
1101 CreateMultiTable();
1102 OpenStore();
1103 TrackerSchema schema = g_normalSchema1;
1104 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1105 uint64_t num = 10;
1106 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1107
1108 /**
1109 * @tc.steps:step2. drop and rebuild table, then SetTrackerTable
1110 * @tc.expected: step2. Return OK.
1111 */
1112 std::string sql = "drop table if exists " + TABLE_NAME2;
1113 EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1114 EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
1115 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1116
1117 /**
1118 * @tc.steps:step3. check the extend_field and cursor is null
1119 * @tc.expected: step3. Return OK.
1120 */
1121 sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log where extend_field is NULL " +
1122 " AND cursor is NULL";
1123 EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1124 reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1125
1126 /**
1127 * @tc.steps:step4. set diff schema, check the extend_field and cursor is null
1128 * @tc.expected: step4. Return OK.
1129 */
1130 schema.extendColName = EXTEND_COL_NAME3;
1131 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1132 sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log where extend_field is NULL " +
1133 " AND cursor is NULL";
1134 EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1135 reinterpret_cast<void *>(0), nullptr), SQLITE_OK);
1136 CloseStore();
1137 }
1138
1139 /**
1140 * @tc.name: TrackerTableTest021
1141 * @tc.desc: Test non distributed table delete table and reopen db
1142 * @tc.type: FUNC
1143 * @tc.require:
1144 * @tc.author: bty
1145 */
1146 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest021, TestSize.Level0)
1147 {
1148 CheckDropTableAndReopenDb(false);
1149 }
1150
1151 /**
1152 * @tc.name: TrackerTableTest022
1153 * @tc.desc: Test distributed table delete table and reopen db
1154 * @tc.type: FUNC
1155 * @tc.require:
1156 * @tc.author: bty
1157 */
1158 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest022, TestSize.Level0)
1159 {
1160 CheckDropTableAndReopenDb(true);
1161 }
1162
1163 /**
1164 * @tc.name: TrackerTableTest023
1165 * @tc.desc: Test drop and rebuild table,then insert data and set tracker table
1166 * @tc.type: FUNC
1167 * @tc.require:
1168 * @tc.author: bty
1169 */
1170 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest023, TestSize.Level0)
1171 {
1172 /**
1173 * @tc.steps:step1. SetTrackerTable and init data
1174 * @tc.expected: step1. Return OK.
1175 */
1176 CreateMultiTable();
1177 OpenStore();
1178 TrackerSchema schema = g_normalSchema1;
1179 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1180 uint64_t num = 10;
1181 BatchInsertTableName2Data(num);
1182 BatchDeleteTableName2Data(num);
1183
1184 /**
1185 * @tc.steps:step2. drop and rebuild table,then insert data and set tracker table
1186 * @tc.expected: step2. Return OK.
1187 */
1188 std::string sql = "drop table if exists " + TABLE_NAME2;
1189 EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1190 EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, CREATE_LOCAL_PK_TABLE_SQL), SQLITE_OK);
1191 BatchInsertTableName2Data(num);
1192 schema = g_normalSchema2;
1193 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1194
1195 /**
1196 * @tc.steps:step3. query cursor
1197 * @tc.expected: step3. Return OK.
1198 */
1199 string querySql = "select cursor from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log";
1200 sqlite3_stmt *stmt = nullptr;
1201 int index = 20;
1202 EXPECT_EQ(SQLiteUtils::GetStatement(g_db, querySql, stmt), E_OK);
1203 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1204 std::string cursorVal;
1205 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 0, cursorVal), E_OK);
1206 EXPECT_EQ(cursorVal, std::to_string(++index));
1207 }
1208 int errCode;
1209 SQLiteUtils::ResetStatement(stmt, true, errCode);
1210 CloseStore();
1211 }
1212
1213 /**
1214 * @tc.name: TrackerTableTest024
1215 * @tc.desc: Test set tracker table and set extend col as the asset type
1216 * @tc.type: FUNC
1217 * @tc.require:
1218 * @tc.author: bty
1219 */
1220 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest024, TestSize.Level0)
1221 {
1222 CreateMultiTable();
1223 OpenStore();
1224 TrackerSchema schema;
1225 schema.tableName = TABLE_NAME3;
1226 schema.extendColName = EXTEND_COL_NAME3;
1227 schema.trackerColNames = { EXTEND_COL_NAME3 };
1228 EXPECT_EQ(g_delegate->SetTrackerTable(schema), INVALID_ARGS);
1229 CloseStore();
1230 }
1231
1232 /**
1233 * @tc.name: ExecuteSql001
1234 * @tc.desc: Test ExecuteSql with invalid param
1235 * @tc.type: FUNC
1236 * @tc.require:
1237 * @tc.author: bty
1238 */
1239 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql001, TestSize.Level0)
1240 {
1241 /**
1242 * @tc.steps:step1. init db data
1243 * @tc.expected: step1. Return OK.
1244 */
1245 uint64_t num = 10;
1246 CreateMultiTable();
1247 BatchInsertTableName2Data(num);
1248 OpenStore();
1249
1250 /**
1251 * @tc.steps:step2. sql is empty
1252 * @tc.expected: step2. Return INVALID_ARGS.
1253 */
1254 SqlCondition condition;
1255 std::vector<VBucket> records;
1256 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1257
1258 /**
1259 * @tc.steps:step3. SQL does not have placeholders but there are bind args present
1260 * @tc.expected: step3. Return INVALID_ARGS.
1261 */
1262 std::string querySql = "select * from " + TABLE_NAME2 + " where id = 1;";
1263 condition.sql = querySql;
1264 condition.bindArgs = {"1"};
1265 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1266
1267 /**
1268 * @tc.steps:step4. More SQL binding parameters than SQL placeholders
1269 * @tc.expected: step4. Return INVALID_ARGS.
1270 */
1271 querySql = "select * from " + TABLE_NAME2 + " where id > ?;";
1272 condition.sql = querySql;
1273 condition.bindArgs = {};
1274 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1275
1276 /**
1277 * @tc.steps:step5. More SQL placeholders than SQL binding parameters
1278 * @tc.expected: step5. Return INVALID_ARGS.
1279 */
1280 condition.bindArgs = {"1", "2"};
1281 condition.sql = querySql;
1282 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1283 CloseStore();
1284 }
1285
1286 /**
1287 * @tc.name: ExecuteSql002
1288 * @tc.desc: Test ExecuteSql and check query result
1289 * @tc.type: FUNC
1290 * @tc.require:
1291 * @tc.author: bty
1292 */
1293 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql002, TestSize.Level0)
1294 {
1295 /**
1296 * @tc.steps:step1. init db data
1297 * @tc.expected: step1. Return OK.
1298 */
1299 uint64_t num = 10;
1300 CreateMultiTable();
1301 BatchInsertTableName2Data(num);
1302 OpenStore();
1303
1304 /**
1305 * @tc.steps:step2. execute query sql and check result
1306 * @tc.expected: step2. Return OK.
1307 */
1308 int64_t beginId = 1;
1309 SqlCondition condition;
1310 std::vector<VBucket> records;
1311 std::string querySql = "select * from " + TABLE_NAME2 + " where id > ?;";
1312 condition.sql = querySql;
1313 condition.bindArgs = {beginId};
1314 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1315 EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1316 for (const VBucket &item: records) {
1317 auto iter = item.find("id");
1318 ASSERT_NE(iter, item.end());
1319 ASSERT_TRUE(iter->second.index() == TYPE_INDEX<int64_t>);
1320 EXPECT_EQ(std::get<int64_t>(iter->second), beginId + 1);
1321
1322 iter = item.find("name");
1323 ASSERT_NE(iter, item.end());
1324 ASSERT_TRUE(iter->second.index() == TYPE_INDEX<std::string>);
1325 EXPECT_EQ(std::get<std::string>(iter->second), "Local" + std::to_string(beginId));
1326
1327 iter = item.find("height");
1328 ASSERT_NE(iter, item.end());
1329 ASSERT_TRUE(iter->second.index() == TYPE_INDEX<double>);
1330 EXPECT_EQ(std::get<double>(iter->second), 175.8);
1331
1332 iter = item.find("photo");
1333 ASSERT_NE(iter, item.end());
1334 ASSERT_TRUE(iter->second.index() == TYPE_INDEX<double>);
1335 EXPECT_EQ(std::get<double>(iter->second), 175.88888888888);
1336
1337 iter = item.find("asserts");
1338 ASSERT_NE(iter, item.end());
1339 ASSERT_TRUE(iter->second.index() == TYPE_INDEX<std::string>);
1340 EXPECT_EQ(std::get<std::string>(iter->second), "x");
1341 beginId++;
1342 }
1343 CloseStore();
1344 }
1345
1346 /**
1347 * @tc.name: ExecuteSql003
1348 * @tc.desc: Test ExecuteSql and check update and delete result
1349 * @tc.type: FUNC
1350 * @tc.require:
1351 * @tc.author: bty
1352 */
1353 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql003, TestSize.Level0)
1354 {
1355 /**
1356 * @tc.steps:step1. init db data
1357 * @tc.expected: step1. Return OK.
1358 */
1359 uint64_t num = 10;
1360 CreateMultiTable();
1361 BatchInsertTableName2Data(num);
1362 OpenStore();
1363
1364 /**
1365 * @tc.steps:step2. update sql
1366 * @tc.expected: step2. Return OK.
1367 */
1368 int64_t beginId = 1;
1369 SqlCondition condition;
1370 std::vector<VBucket> records;
1371 std::string updateSql = "update " + TABLE_NAME2 + " set age = 3 where id = ?;";
1372 condition.sql = updateSql;
1373 condition.bindArgs = {beginId};
1374 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1375 EXPECT_EQ(records.size(), 0u);
1376
1377 std::string delSql = "delete from " + TABLE_NAME2 + " where id = ?;";
1378 condition.sql = delSql;
1379 condition.bindArgs = {beginId + 1};
1380 std::vector<VBucket> records2;
1381 EXPECT_EQ(g_delegate->ExecuteSql(condition, records2), OK);
1382 EXPECT_EQ(records2.size(), 0u);
1383
1384 string insSql = "INSERT INTO " + TABLE_NAME2 +
1385 " (name, height, photo, asserts, age) VALUES ('Local" + std::to_string(num + 1) +
1386 "', '175.8', '0', 'x', ?);";
1387 condition.sql = insSql;
1388 condition.bindArgs = {beginId};
1389 std::vector<VBucket> records3;
1390 EXPECT_EQ(g_delegate->ExecuteSql(condition, records3), OK);
1391 EXPECT_EQ(records3.size(), 0u);
1392 CloseStore();
1393 }
1394
1395 /**
1396 * @tc.name: ExecuteSql004
1397 * @tc.desc: Test ExecuteSql after SetTrackerTable
1398 * @tc.type: FUNC
1399 * @tc.require:
1400 * @tc.author: bty
1401 */
1402 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql004, TestSize.Level0)
1403 {
1404 /**
1405 * @tc.steps:step1. SetTrackerTable
1406 * @tc.expected: step1. Return OK.
1407 */
1408 CreateMultiTable();
1409 OpenStore();
1410 TrackerSchema schema = g_normalSchema1;
1411 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1412
1413 /**
1414 * @tc.steps:step2. batch insert
1415 * @tc.expected: step2. Return OK.
1416 */
1417 uint64_t num = 10;
1418 BatchInsertTableName2Data(num);
1419
1420 /**
1421 * @tc.steps:step3. execute query sql and check result
1422 * @tc.expected: step3. Return OK.
1423 */
1424 int64_t begin = 0;
1425 SqlCondition condition;
1426 std::vector<VBucket> records;
1427 std::string querySql = "select " + TABLE_NAME2 + ".* from " + TABLE_NAME2 + " join ";
1428 querySql += DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" + " as a on " + TABLE_NAME2 + "._rowid_ = ";
1429 querySql += "a.data_key where a.cursor > ?;";
1430 condition.sql = querySql;
1431 condition.bindArgs = {begin};
1432 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1433 EXPECT_EQ(records.size(), num);
1434
1435 /**
1436 * @tc.steps:step4. update
1437 * @tc.expected: step4. Return OK.
1438 */
1439 std::string updateSql = "update " + TABLE_NAME2 + " set name = '3' where _rowid_ <= 5;";
1440 condition.sql = updateSql;
1441 condition.bindArgs = {};
1442 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1443
1444 /**
1445 * @tc.steps:step5. query after updating
1446 * @tc.expected: step5. Return OK.
1447 */
1448 records.clear();
1449 begin = 10;
1450 condition.sql = querySql;
1451 condition.bindArgs = {begin};
1452 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1453 EXPECT_EQ(records.size(), 5u); // 5 is the num of update
1454 CloseStore();
1455 }
1456
1457 /**
1458 * @tc.name: ExecuteSql005
1459 * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1460 * @tc.type: FUNC
1461 * @tc.require:
1462 * @tc.author: bty
1463 */
1464 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql005, TestSize.Level0)
1465 {
1466 /**
1467 * @tc.steps:step1. init db data
1468 * @tc.expected: step1. Return OK.
1469 */
1470 uint64_t num = 10;
1471 CreateMultiTable();
1472 BatchInsertTableName2Data(num);
1473 OpenStore();
1474
1475 /**
1476 * @tc.steps:step2. execute query sql but the table is no exist
1477 * @tc.expected: step2. Return DB_ERROR.
1478 */
1479 int64_t beginId = 1;
1480 SqlCondition condition;
1481 std::vector<VBucket> records;
1482 std::string querySql = "select * from " + TABLE_NAME2 + " where id > 1;";
1483 querySql += "select _rowid_ from " + TABLE_NAME2 + " where id = 1;";
1484 condition.sql = querySql;
1485 condition.bindArgs = {};
1486 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1487 EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1488
1489 /**
1490 * @tc.steps:step3. execute multi query sql and the num of bindArgs is greater than the first sql
1491 * @tc.expected: step3. Return INVALID_ARGS.
1492 */
1493 records = {};
1494 std::string querySql2 = "select * from " + TABLE_NAME2 + " where id > ?;";
1495 querySql2 += "select _rowid_ from " + TABLE_NAME2 + " where id = ?;";
1496 condition.sql = querySql2;
1497 condition.bindArgs = {beginId, beginId};
1498 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), INVALID_ARGS);
1499 EXPECT_EQ(records.size(), 0u);
1500
1501 /**
1502 * @tc.steps:step4. execute multi query sql and the num of bindArgs is equal to the first sql
1503 * @tc.expected: step4. Return OK.
1504 */
1505 records = {};
1506 condition.bindArgs = {beginId};
1507 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1508 EXPECT_EQ(records.size(), static_cast<size_t>(num - beginId));
1509 CloseStore();
1510 }
1511
1512 /**
1513 * @tc.name: ExecuteSql006
1514 * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1515 * @tc.type: FUNC
1516 * @tc.require:
1517 * @tc.author: bty
1518 */
1519 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql006, TestSize.Level0)
1520 {
1521 /**
1522 * @tc.steps:step1. init db data
1523 * @tc.expected: step1. Return OK.
1524 */
1525 uint64_t num = 10;
1526 CreateMultiTable();
1527 BatchInsertTableName2Data(num);
1528 OpenStore();
1529
1530 /**
1531 * @tc.steps:step2. execute multi update sql
1532 * @tc.expected: step2. Return OK.
1533 */
1534 SqlCondition condition;
1535 std::vector<VBucket> records;
1536 std::string updateSql = "update " + TABLE_NAME2 + " SET age = 100; ";
1537 updateSql += "update " + TABLE_NAME2 + " SET age = 50;";
1538 condition.sql = updateSql;
1539 condition.bindArgs = {};
1540 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1541
1542 /**
1543 * @tc.steps:step3. execute query sql where age is 100
1544 * @tc.expected: step3. Return OK.
1545 */
1546 records = {};
1547 std::string querySql = "select * from " + TABLE_NAME2 + " where age = 100;";
1548 condition.sql = querySql;
1549 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1550 EXPECT_EQ(records.size(), num);
1551
1552 /**
1553 * @tc.steps:step4. execute update sql and query sql
1554 * @tc.expected: step4. Return OK.
1555 */
1556 updateSql = "update " + TABLE_NAME2 + " SET age = 88; ";
1557 updateSql += "select * from " + TABLE_NAME2;
1558 condition.sql = updateSql;
1559 condition.bindArgs = {};
1560 records = {};
1561 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1562 EXPECT_EQ(records.size(), 0u);
1563
1564 /**
1565 * @tc.steps:step5. execute multi delete sql
1566 * @tc.expected: step5. Return OK.
1567 */
1568 records = {};
1569 std::string delSql = "DELETE FROM " + TABLE_NAME2 + " WHERE age = 100; ";
1570 delSql += "DELETE FROM " + TABLE_NAME2 + " WHERE age = 88;";
1571 condition.sql = delSql;
1572 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1573
1574 /**
1575 * @tc.steps:step6. execute query sql where age is 100
1576 * @tc.expected: step6. Return OK.
1577 */
1578 records = {};
1579 condition.sql = "select * from " + TABLE_NAME2 + " where age = 88;";
1580 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1581 EXPECT_EQ(records.size(), num);
1582 CloseStore();
1583 }
1584
1585 /**
1586 * @tc.name: ExecuteSql006
1587 * @tc.desc: Test ExecuteSql interface only takes effect on the first SQL
1588 * @tc.type: FUNC
1589 * @tc.require:
1590 * @tc.author: bty
1591 */
1592 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql007, TestSize.Level0)
1593 {
1594 /**
1595 * @tc.steps:step1. init db data
1596 * @tc.expected: step1. Return OK.
1597 */
1598 uint64_t num = 10;
1599 CreateMultiTable();
1600 BatchInsertTableName2Data(num);
1601 OpenStore();
1602
1603 /**
1604 * @tc.steps:step2. ExecuteSql with transaction
1605 * @tc.expected: step2. Return OK.
1606 */
1607 SqlCondition condition;
1608 std::vector<VBucket> records;
1609 condition.sql = "BEGIN";
1610 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1611 condition.sql = "COMMIT;";
1612 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1613 condition.sql = "BEGIN";
1614 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1615 condition.sql = "ROLLBACK;";
1616 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1617 condition.sql = "BEGIN TRANSACTION;";
1618 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1619 condition.sql = "END TRANSACTION;";
1620 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1621 condition.sql = "BEGIN IMMEDIATE TRANSACTION;";
1622 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1623 condition.sql = "COMMIT;";
1624 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1625
1626 /**
1627 * @tc.steps:step3. ExecuteSql with attach and detach
1628 * @tc.expected: step3. Return OK.
1629 */
1630 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID2 + DB_SUFFIX);
1631 EXPECT_NE(db, nullptr);
1632 condition.sql = "ATTACH DATABASE '" + g_dbDir + STORE_ID2 + DB_SUFFIX + "' AS TEST";
1633 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1634 condition.sql = "DETACH DATABASE TEST";
1635 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1636 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1637 db = nullptr;
1638 CloseStore();
1639 }
1640
1641 /**
1642 * @tc.name: ExecuteSql008
1643 * @tc.desc: Test the ExecSql interface for bool type results
1644 * @tc.type: FUNC
1645 * @tc.require:
1646 * @tc.author: bty
1647 */
1648 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql008, TestSize.Level0)
1649 {
1650 /**
1651 * @tc.steps:step1. init db data
1652 * @tc.expected: step1. Return OK.
1653 */
1654 CreateMultiTable();
1655 OpenStore();
1656 uint64_t num = 10;
1657 for (size_t i = 0; i < num; i++) {
1658 string sql = "INSERT OR REPLACE INTO " + TABLE_NAME1 +
1659 " (name, height, married, photo, assert, age) VALUES ('Tom" + std::to_string(i) +
1660 "', '175.8', '0', '', '' , '18');";
1661 EXPECT_EQ(RelationalTestUtils::ExecSql(g_db, sql), SQLITE_OK);
1662 }
1663
1664 /**
1665 * @tc.steps:step2. check if the result is of bool type
1666 * @tc.expected: step2. Return OK.
1667 */
1668 SqlCondition condition;
1669 condition.sql = "select * from " + TABLE_NAME1;
1670 std::vector<VBucket> records;
1671 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1672 EXPECT_EQ(records.size(), num);
1673 EXPECT_NE(records[0].find("married"), records[0].end());
1674 if (records[0].find("married") != records[0].end()) {
1675 Type married = records[0].find("married")->second;
1676 EXPECT_TRUE(married.index() == TYPE_INDEX<bool>);
1677 }
1678 CloseStore();
1679 }
1680
1681 /**
1682 * @tc.name: ExecuteSql010
1683 * @tc.desc: Test ExecuteSql with temp table
1684 * @tc.type: FUNC
1685 * @tc.require:
1686 * @tc.author: bty
1687 */
1688 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, ExecuteSql010, TestSize.Level0)
1689 {
1690 /**
1691 * @tc.steps:step1. init db data
1692 * @tc.expected: step1. Return OK.
1693 */
1694 uint64_t num = 10;
1695 CreateMultiTable();
1696 OpenStore();
1697 SqlCondition condition;
1698 Bytes photo = { 1, 2, 3, 4 };
1699 std::vector<VBucket> records;
1700 for (size_t i = 0; i < num; i++) {
1701 condition.sql = "INSERT INTO " + TABLE_NAME2
1702 + " (name, height, photo, asserts, age) VALUES ('Local" + std::to_string(i) +
1703 "', '175.8', ?, 'x', '18');";
1704 condition.bindArgs = {photo};
1705 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1706 }
1707
1708 /**
1709 * @tc.steps:step2. ExecuteSql with transaction
1710 * @tc.expected: step2. Return OK.
1711 */
1712 condition.sql = "create temp table AA as select * from " + TABLE_NAME2;
1713 condition.bindArgs = {};
1714 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1715 condition.sql = "select * from " + TABLE_NAME2;
1716 condition.readOnly = true;
1717 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1718 EXPECT_EQ(records.size(), num);
1719 CloseStore();
1720 }
1721
1722 /**
1723 * @tc.name: TrackerTableTest026
1724 * @tc.desc: Test tracker table with case sensitive table name
1725 * @tc.type: FUNC
1726 * @tc.require:
1727 * @tc.author: bty
1728 */
1729 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest026, TestSize.Level0)
1730 {
1731 /**
1732 * @tc.steps:step1. SetTrackerTable on table2
1733 * @tc.expected: step1. Return OK.
1734 */
1735 CreateMultiTable();
1736 OpenStore();
1737 TrackerSchema schema = g_normalSchema1;
1738 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1739
1740 /**
1741 * @tc.steps:step2. SetTrackerTable on table2 with case different
1742 * @tc.expected: step2. Return NOT_FOUND.
1743 */
1744 schema.tableName = "worker2";
1745 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1746 uint64_t num = 10;
1747 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1748 schema.tableName = "workeR2";
1749 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1750 schema.trackerColNames = {};
1751 schema.tableName = "WorkeR2";
1752 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1753 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1754
1755 schema = g_normalSchema1;
1756 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1757 CloseStore();
1758 }
1759
1760 /**
1761 * @tc.name: TrackerTableTest027
1762 * @tc.desc: Test tracker table with case sensitive distributed table name
1763 * @tc.type: FUNC
1764 * @tc.require:
1765 * @tc.author: bty
1766 */
1767 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest027, TestSize.Level0)
1768 {
1769 /**
1770 * @tc.steps:step1. create distributed table on table2 with case different
1771 * @tc.expected: step1. Return OK.
1772 */
1773 CreateMultiTable();
1774 OpenStore();
1775 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
1776 TrackerSchema schema = g_normalSchema1;
1777 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1778 EXPECT_EQ(g_delegate->CreateDistributedTable("worker2", CLOUD_COOPERATION), DBStatus::OK);
1779
1780 /**
1781 * @tc.steps:step2. SetTrackerTable on table2 with case different
1782 * @tc.expected: step2. Return NOT_FOUND.
1783 */
1784 schema.tableName = "Worker2";
1785 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1786 uint64_t num = 10;
1787 BatchOperatorTableName2Data(num, LOCAL_TABLE_TRACKER_NAME_SET3);
1788 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1789 schema.tableName = "WOrker2";
1790 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1791 schema.trackerColNames = {};
1792 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1793 schema.tableName = "Worker2";
1794 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1795
1796 /**
1797 * @tc.steps:step3. SetTrackerTable with "worKer2"
1798 * @tc.expected: step3. Return NOT_FOUND.
1799 */
1800 schema.tableName = g_normalSchema1.tableName;
1801 EXPECT_EQ(g_delegate->SetTrackerTable(schema), NOT_FOUND);
1802
1803 /**
1804 * @tc.steps:step4. SetTrackerTable with "worKer2" after reopening db
1805 * @tc.expected: step4. Return OK.
1806 */
1807 CloseStore();
1808 OpenStore();
1809 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1810 schema.trackerColNames = {};
1811 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1812 CloseStore();
1813 }
1814
1815 /**
1816 * @tc.name: TrackerTableTest030
1817 * @tc.desc: Test clean trackTable when table is distributedTable
1818 * @tc.type: FUNC
1819 * @tc.require:
1820 * @tc.author: wangxiangdong
1821 */
1822 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest030, TestSize.Level0)
1823 {
1824 /**
1825 * @tc.steps:step1. SetTrackerTable
1826 * @tc.expected: step1. Return OK.
1827 */
1828 CreateMultiTable();
1829
1830 OpenStore();
1831 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2), OK);
1832
1833 /**
1834 * @tc.steps:step2. Insert data to table2
1835 * @tc.expected: step2. Return E_OK.
1836 */
1837 uint64_t num = 10;
1838 BatchInsertTableName2Data(num);
1839 BatchDeleteTableName2Data(num / HALF);
1840
1841 /**
1842 * @tc.steps:step3. CleanTrackerData
1843 * @tc.expected: step3. Return OK.
1844 */
1845 EXPECT_EQ(g_delegate->CleanTrackerData(TABLE_NAME2, num + (num / HALF)), OK);
1846 std::string sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + TABLE_NAME2 + "_log" +
1847 " where extend_field is NULL;";
1848 EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback,
1849 reinterpret_cast<void *>(num), nullptr), SQLITE_OK);
1850 CloseStore();
1851 }
1852
1853 /**
1854 * @tc.name: SchemaStrTest001
1855 * @tc.desc: Test open reOpen stroe when schemaStr is empty
1856 * @tc.type: FUNC
1857 * @tc.require:
1858 * @tc.author: bty
1859 */
1860 HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, SchemaStrTest001, TestSize.Level0)
1861 {
1862 /**
1863 * @tc.steps:step1. set empty for relational schema str, reopen store
1864 * @tc.expected: step1. Return OK.
1865 */
1866 std::string updMetaSql = "UPDATE naturalbase_rdb_aux_metadata SET value=? where key=?;";
1867 CreateMultiTable();
1868 OpenStore();
1869 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
1870 SqlCondition condition;
1871 std::vector<VBucket> records;
1872 condition.sql = updMetaSql;
1873 Key relationKey;
1874 DBCommon::StringToVector(DBConstant::RELATIONAL_SCHEMA_KEY, relationKey);
1875 condition.bindArgs = { std::string(""), relationKey };
1876 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1877 CloseStore();
1878 OpenStore();
1879
1880 /**
1881 * @tc.steps:step2. set empty for relational schema str, reopen store to upgrade
1882 * @tc.expected: step2. Return OK.
1883 */
1884 Value verVal;
1885 DBCommon::StringToVector("5.0", verVal);
1886 Key verKey;
1887 DBCommon::StringToVector("log_table_version", verKey);
1888 condition.bindArgs = { verVal, verKey };
1889 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1890 condition.bindArgs = { std::string(""), relationKey };
1891 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1892 CloseStore();
1893 OpenStore();
1894
1895 /**
1896 * @tc.steps:step3. set empty for tracker schema str, reopen store to upgrade
1897 * @tc.expected: step3. Return OK.
1898 */
1899 TrackerSchema schema = g_normalSchema1;
1900 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1901 condition.bindArgs = { verVal, verKey };
1902 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1903 condition.bindArgs = { std::string(""), relationKey };
1904 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1905 Key trackerKey;
1906 DBCommon::StringToVector("relational_tracker_schema", trackerKey);
1907 condition.bindArgs = { std::string(""), trackerKey };
1908 EXPECT_EQ(g_delegate->ExecuteSql(condition, records), OK);
1909 CloseStore();
1910 OpenStore();
1911
1912 /**
1913 * @tc.steps:step4. try to create distributed table and set tracker table again
1914 * @tc.expected: step4. Return OK.
1915 */
1916 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME2, CLOUD_COOPERATION), DBStatus::OK);
1917 EXPECT_EQ(g_delegate->CreateDistributedTable(TABLE_NAME1, CLOUD_COOPERATION), DBStatus::OK);
1918 EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK);
1919 CloseStore();
1920 }
1921 }