1 /*
2 * Copyright (c) 2021 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 #ifdef RELATIONAL_STORE
16 #include <gtest/gtest.h>
17
18 #include "data_transformer.h"
19 #include "db_common.h"
20 #include "db_constant.h"
21 #include "db_errno.h"
22 #include "db_types.h"
23 #include "distributeddb_data_generate_unit_test.h"
24 #include "distributeddb_tools_unit_test.h"
25 #include "generic_single_ver_kv_entry.h"
26 #include "kvdb_properties.h"
27 #include "log_print.h"
28 #include "relational_schema_object.h"
29 #include "relational_store_delegate.h"
30 #include "relational_store_instance.h"
31 #include "relational_store_manager.h"
32 #include "relational_store_sqlite_ext.h"
33 #include "relational_sync_able_storage.h"
34 #include "sqlite_relational_store.h"
35 #include "sqlite_utils.h"
36 #include "virtual_communicator_aggregator.h"
37
38 using namespace testing::ext;
39 using namespace DistributedDB;
40 using namespace DistributedDBUnitTest;
41 using namespace std;
42
43 namespace {
44 string g_testDir;
45 string g_storePath;
46 string g_storeID = "dftStoreID";
47 string g_tableName { "data" };
48 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
49 RelationalStoreDelegate *g_delegate = nullptr;
50 IRelationalStore *g_store = nullptr;
51
CreateDBAndTable()52 void CreateDBAndTable()
53 {
54 sqlite3 *db = nullptr;
55 int errCode = sqlite3_open(g_storePath.c_str(), &db);
56 if (errCode != SQLITE_OK) {
57 LOGE("open db failed:%d", errCode);
58 sqlite3_close(db);
59 return;
60 }
61
62 const string sql =
63 "PRAGMA journal_mode=WAL;"
64 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
65 char *zErrMsg = nullptr;
66 errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &zErrMsg);
67 if (errCode != SQLITE_OK) {
68 LOGE("sql error:%s", zErrMsg);
69 sqlite3_free(zErrMsg);
70 }
71 sqlite3_close(db);
72 }
73
AddOrUpdateRecord(int64_t key,int64_t value)74 int AddOrUpdateRecord(int64_t key, int64_t value)
75 {
76 sqlite3 *db = nullptr;
77 int errCode = sqlite3_open(g_storePath.c_str(), &db);
78 if (errCode == SQLITE_OK) {
79 const string sql =
80 "INSERT OR REPLACE INTO " + g_tableName + " VALUES(" + to_string(key) + "," + to_string(value) + ");";
81 errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
82 }
83 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
84 sqlite3_close(db);
85 return errCode;
86 }
87
GetLogData(int key,uint64_t & flag,Timestamp & timestamp,const DeviceID & device="")88 int GetLogData(int key, uint64_t &flag, Timestamp ×tamp, const DeviceID &device = "")
89 {
90 if (!device.empty()) {
91 }
92 const string sql = "SELECT timestamp, flag \
93 FROM " + g_tableName + " as a, " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log as b \
94 WHERE a.key=? AND a.rowid=b.data_key;";
95
96 sqlite3 *db = nullptr;
97 sqlite3_stmt *statement = nullptr;
98 int errCode = sqlite3_open(g_storePath.c_str(), &db);
99 if (errCode != SQLITE_OK) {
100 LOGE("open db failed:%d", errCode);
101 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
102 goto END;
103 }
104 errCode = SQLiteUtils::GetStatement(db, sql, statement);
105 if (errCode != E_OK) {
106 goto END;
107 }
108 errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, key); // 1 means key's index
109 if (errCode != E_OK) {
110 goto END;
111 }
112 errCode = SQLiteUtils::StepWithRetry(statement, false);
113 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
114 timestamp = static_cast<Timestamp>(sqlite3_column_int64(statement, 0));
115 flag = static_cast<Timestamp>(sqlite3_column_int64(statement, 1));
116 errCode = E_OK;
117 } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
118 errCode = -E_NOT_FOUND;
119 }
120
121 END:
122 SQLiteUtils::ResetStatement(statement, true, errCode);
123 sqlite3_close(db);
124 return errCode;
125 }
126
InitStoreProp(const std::string & storePath,const std::string & appId,const std::string & userId,RelationalDBProperties & properties)127 void InitStoreProp(const std::string &storePath, const std::string &appId, const std::string &userId,
128 RelationalDBProperties &properties)
129 {
130 properties.SetStringProp(RelationalDBProperties::DATA_DIR, storePath);
131 properties.SetStringProp(RelationalDBProperties::APP_ID, appId);
132 properties.SetStringProp(RelationalDBProperties::USER_ID, userId);
133 properties.SetStringProp(RelationalDBProperties::STORE_ID, g_storeID);
134 std::string identifier = userId + "-" + appId + "-" + g_storeID;
135 std::string hashIdentifier = DBCommon::TransferHashString(identifier);
136 properties.SetStringProp(RelationalDBProperties::IDENTIFIER_DATA, hashIdentifier);
137 }
138
GetRelationalStore()139 const RelationalSyncAbleStorage *GetRelationalStore()
140 {
141 RelationalDBProperties properties;
142 InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
143 int errCode = E_OK;
144 g_store = RelationalStoreInstance::GetDataBase(properties, errCode);
145 if (g_store == nullptr) {
146 LOGE("Get db failed:%d", errCode);
147 return nullptr;
148 }
149 return static_cast<SQLiteRelationalStore *>(g_store)->GetStorageEngine();
150 }
151
GetCount(sqlite3 * db,const string & sql,size_t & count)152 int GetCount(sqlite3 *db, const string &sql, size_t &count)
153 {
154 sqlite3_stmt *stmt = nullptr;
155 int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
156 if (errCode != E_OK) {
157 return errCode;
158 }
159 errCode = SQLiteUtils::StepWithRetry(stmt, false);
160 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
161 count = static_cast<size_t>(sqlite3_column_int64(stmt, 0));
162 errCode = E_OK;
163 }
164 SQLiteUtils::ResetStatement(stmt, true, errCode);
165 return errCode;
166 }
167
ExpectCount(sqlite3 * db,const string & sql,size_t expectCount)168 void ExpectCount(sqlite3 *db, const string &sql, size_t expectCount)
169 {
170 size_t count = 0;
171 ASSERT_EQ(GetCount(db, sql, count), E_OK);
172 EXPECT_EQ(count, expectCount);
173 }
174
GetOneText(sqlite3 * db,const string & sql)175 std::string GetOneText(sqlite3 *db, const string &sql)
176 {
177 std::string result;
178 sqlite3_stmt *stmt = nullptr;
179 int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
180 if (errCode != E_OK) {
181 return result;
182 }
183 errCode = SQLiteUtils::StepWithRetry(stmt, false);
184 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
185 SQLiteUtils::GetColumnTextValue(stmt, 0, result);
186 }
187 SQLiteUtils::ResetStatement(stmt, true, errCode);
188 return result;
189 }
190
PutBatchData(uint32_t totalCount,uint32_t valueSize)191 int PutBatchData(uint32_t totalCount, uint32_t valueSize)
192 {
193 sqlite3 *db = nullptr;
194 sqlite3_stmt *stmt = nullptr;
195 const string sql = "INSERT INTO " + g_tableName + " VALUES(?,?);";
196 int errCode = sqlite3_open(g_storePath.c_str(), &db);
197 if (errCode != SQLITE_OK) {
198 goto ERROR;
199 }
200 EXPECT_EQ(sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", nullptr, nullptr, nullptr), SQLITE_OK);
201 errCode = SQLiteUtils::GetStatement(db, sql, stmt);
202 if (errCode != E_OK) {
203 goto ERROR;
204 }
205 for (uint32_t i = 0; i < totalCount; i++) {
206 errCode = SQLiteUtils::BindBlobToStatement(stmt, 2, Value(valueSize, 'a'), false); // 2 means value index
207 if (errCode != E_OK) {
208 break;
209 }
210 errCode = SQLiteUtils::StepWithRetry(stmt);
211 if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
212 break;
213 }
214 errCode = E_OK;
215 SQLiteUtils::ResetStatement(stmt, false, errCode);
216 }
217
218 ERROR:
219 if (errCode == E_OK) {
220 EXPECT_EQ(sqlite3_exec(db, "COMMIT TRANSACTION", nullptr, nullptr, nullptr), SQLITE_OK);
221 } else {
222 EXPECT_EQ(sqlite3_exec(db, "ROLLBACK TRANSACTION", nullptr, nullptr, nullptr), SQLITE_OK);
223 }
224 SQLiteUtils::ResetStatement(stmt, true, errCode);
225 errCode = SQLiteUtils::MapSQLiteErrno(errCode);
226 sqlite3_close(db);
227 return errCode;
228 }
229
ExecSqlAndAssertOK(sqlite3 * db,const std::string & sql)230 void ExecSqlAndAssertOK(sqlite3 *db, const std::string &sql)
231 {
232 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
233 }
234
ExecSqlAndAssertOK(sqlite3 * db,const initializer_list<std::string> & sqlList)235 void ExecSqlAndAssertOK(sqlite3 *db, const initializer_list<std::string> &sqlList)
236 {
237 for (const auto &sql : sqlList) {
238 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
239 }
240 }
241
ExpectMissQueryCnt(const std::vector<SingleVerKvEntry * > & entries,size_t expectCount)242 void ExpectMissQueryCnt(const std::vector<SingleVerKvEntry *> &entries, size_t expectCount)
243 {
244 size_t count = 0;
245 for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
246 if (((*iter)->GetFlag() & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) == 0) {
247 count++;
248 }
249 auto nextOne = std::next(iter, 1);
250 if (nextOne != entries.end()) {
251 EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
252 }
253 }
254 EXPECT_EQ(count, expectCount);
255 };
256 }
257
258 class DistributedDBRelationalGetDataTest : public testing::Test {
259 public:
260 static void SetUpTestCase(void);
261 static void TearDownTestCase(void);
262 void SetUp();
263 void TearDown();
264 };
265
SetUpTestCase(void)266 void DistributedDBRelationalGetDataTest::SetUpTestCase(void)
267 {
268 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
269 g_storePath = g_testDir + "/getDataTest.db";
270 LOGI("The test db is:%s", g_testDir.c_str());
271
272 auto communicator = new (std::nothrow) VirtualCommunicatorAggregator();
273 ASSERT_TRUE(communicator != nullptr);
274 RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicator);
275 }
276
TearDownTestCase(void)277 void DistributedDBRelationalGetDataTest::TearDownTestCase(void)
278 {}
279
SetUp(void)280 void DistributedDBRelationalGetDataTest::SetUp(void)
281 {
282 g_tableName = "data";
283 DistributedDBToolsUnitTest::PrintTestCaseInfo();
284 CreateDBAndTable();
285 }
286
TearDown(void)287 void DistributedDBRelationalGetDataTest::TearDown(void)
288 {
289 if (g_delegate != nullptr) {
290 EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
291 g_delegate = nullptr;
292 }
293 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
294 LOGE("rm test db files error.");
295 }
296 return;
297 }
298
299 /**
300 * @tc.name: LogTbl1
301 * @tc.desc: When put sync data to relational store, trigger generate log.
302 * @tc.type: FUNC
303 * @tc.require: AR000GK58G
304 * @tc.author: lidongwei
305 */
306 HWTEST_F(DistributedDBRelationalGetDataTest, LogTbl1, TestSize.Level1)
307 {
308 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
309 ASSERT_NE(g_delegate, nullptr);
310 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
311
312 /**
313 * @tc.steps: step1. Put data.
314 * @tc.expected: Succeed, return OK.
315 */
316 int insertKey = 1;
317 int insertValue = 1;
318 EXPECT_EQ(AddOrUpdateRecord(insertKey, insertValue), E_OK);
319
320 /**
321 * @tc.steps: step2. Check log record.
322 * @tc.expected: Record exists.
323 */
324 uint64_t flag = 0;
325 Timestamp timestamp1 = 0;
326 EXPECT_EQ(GetLogData(insertKey, flag, timestamp1), E_OK);
327 EXPECT_EQ(flag, DataItem::LOCAL_FLAG);
328 EXPECT_NE(timestamp1, 0ULL);
329 }
330
331 /**
332 * @tc.name: GetSyncData1
333 * @tc.desc: GetSyncData interface
334 * @tc.type: FUNC
335 * @tc.require: AR000GK58H
336 * @tc.author: lidongwei
337 */
338 HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData1, TestSize.Level1)
339 {
340 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
341 ASSERT_NE(g_delegate, nullptr);
342 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
343
344 /**
345 * @tc.steps: step1. Put 500 records.
346 * @tc.expected: Succeed, return OK.
347 */
348 const size_t RECORD_COUNT = 500;
349 for (size_t i = 0; i < RECORD_COUNT; ++i) {
350 EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
351 }
352
353 /**
354 * @tc.steps: step2. Get all data.
355 * @tc.expected: Succeed and the count is right.
356 */
357 auto store = GetRelationalStore();
358 ASSERT_NE(store, nullptr);
359 ContinueToken token = nullptr;
360 QueryObject query(Query::Select(g_tableName));
361 std::vector<SingleVerKvEntry *> entries;
362 DataSizeSpecInfo sizeInfo {MTU_SIZE, 50};
363
364 int errCode = store->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries);
365 auto count = entries.size();
366 SingleVerKvEntry::Release(entries);
367 EXPECT_EQ(errCode, -E_UNFINISHED);
368 while (token != nullptr) {
369 errCode = store->GetSyncDataNext(entries, token, sizeInfo);
370 count += entries.size();
371 SingleVerKvEntry::Release(entries);
372 EXPECT_TRUE(errCode == E_OK || errCode == -E_UNFINISHED);
373 }
374 EXPECT_EQ(count, RECORD_COUNT);
375 RefObject::DecObjRef(g_store);
376 }
377
378 /**
379 * @tc.name: GetSyncData2
380 * @tc.desc: GetSyncData interface. For overlarge data(over 4M), ignore it.
381 * @tc.type: FUNC
382 * @tc.require: AR000GK58H
383 * @tc.author: lidongwei
384 */
385 HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData2, TestSize.Level1)
386 {
387 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
388 ASSERT_NE(g_delegate, nullptr);
389 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
390
391 /**
392 * @tc.steps: step1. Put 10 records.(1M + 2M + 3M + 4M + 5M) * 2.
393 * @tc.expected: Succeed, return OK.
394 */
395 for (int i = 1; i <= 5; ++i) {
396 EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK); // 1024*1024 equals 1M.
397 }
398 for (int i = 1; i <= 5; ++i) {
399 EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK); // 1024*1024 equals 1M.
400 }
401
402 /**
403 * @tc.steps: step2. Get all data.
404 * @tc.expected: Succeed and the count is 6.
405 */
406 auto store = GetRelationalStore();
407 ASSERT_NE(store, nullptr);
408 ContinueToken token = nullptr;
409 QueryObject query(Query::Select(g_tableName));
410 std::vector<SingleVerKvEntry *> entries;
411
412 const size_t EXPECT_COUNT = 6; // expect 6 records.
413 DataSizeSpecInfo sizeInfo;
414 sizeInfo.blockSize = 100 * 1024 * 1024; // permit 100M.
415 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries), E_OK);
416 EXPECT_EQ(entries.size(), EXPECT_COUNT);
417 SingleVerKvEntry::Release(entries);
418 RefObject::DecObjRef(g_store);
419 }
420
421 /**
422 * @tc.name: GetSyncData3
423 * @tc.desc: GetSyncData interface. For deleted data.
424 * @tc.type: FUNC
425 * @tc.require: AR000GK58H
426 * @tc.author: lidongwei
427 */
428 HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData3, TestSize.Level1)
429 {
430 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
431 ASSERT_NE(g_delegate, nullptr);
432 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
433
434 /**
435 * @tc.steps: step1. Create distributed table "dataPlus".
436 * @tc.expected: Succeed, return OK.
437 */
438 const string tableName = g_tableName + "Plus";
439 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
440 sqlite3 *db = nullptr;
441 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
442 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
443 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
444
445 /**
446 * @tc.steps: step2. Put 5 records with different type into "dataPlus" table. Put 5 records into "data" table.
447 * @tc.expected: Succeed, return OK.
448 */
449 const size_t RECORD_COUNT = 5; // 5 records
450 ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
451 "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
452 "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
453 "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
454 "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');"});
455
456 /**
457 * @tc.steps: step3. Get all data from "dataPlus" table.
458 * @tc.expected: Succeed and the count is right.
459 */
460 auto store = GetRelationalStore();
461 ASSERT_NE(store, nullptr);
462 ContinueToken token = nullptr;
463 QueryObject query(Query::Select(tableName));
464 std::vector<SingleVerKvEntry *> entries;
465 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
466 EXPECT_EQ(entries.size(), RECORD_COUNT);
467
468 /**
469 * @tc.steps: step4. Put data into "data" table from deviceA and deviceB
470 * @tc.expected: Succeed, return OK.
471 */
472 QueryObject gQuery(Query::Select(g_tableName));
473 DeviceID deviceA = "deviceA";
474 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
475 DBCommon::GetDistributedTableName(deviceA, g_tableName)));
476 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(gQuery, entries, deviceA), E_OK);
477
478 DeviceID deviceB = "deviceB";
479 auto rEntries = std::vector<SingleVerKvEntry *>(entries.rbegin(), entries.rend());
480 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
481 DBCommon::GetDistributedTableName(deviceB, g_tableName)));
482 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(gQuery, rEntries, deviceB), E_OK);
483 rEntries.clear();
484 SingleVerKvEntry::Release(entries);
485
486 /**
487 * @tc.steps: step5. Delete 2 "dataPlus" data from deviceA.
488 * @tc.expected: Succeed.
489 */
490 ExecSqlAndAssertOK(db, "DELETE FROM " + tableName + " WHERE rowid<=2;");
491 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
492 EXPECT_EQ(entries.size(), RECORD_COUNT);
493 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(gQuery, entries, deviceA), E_OK);
494 SingleVerKvEntry::Release(entries);
495
496 /**
497 * @tc.steps: step6. Check data.
498 * @tc.expected: 2 data in the from deviceA are deleted and all data from deviceB are not deleted.
499 */
500 ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName +
501 "_log WHERE flag&0x01=0x01;", 2U); // 2 deleted log
502 ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
503 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceA)) + ";", 3U); // 3 records in A
504 ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
505 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceB)) + ";", RECORD_COUNT); // 5 records in B
506
507 sqlite3_close(db);
508 RefObject::DecObjRef(g_store);
509 }
510
511 /**
512 * @tc.name: GetQuerySyncData1
513 * @tc.desc: GetSyncData interface.
514 * @tc.type: FUNC
515 * @tc.require: AR000GK58H
516 * @tc.author: lidongwei
517 */
518 HWTEST_F(DistributedDBRelationalGetDataTest, GetQuerySyncData1, TestSize.Level1)
519 {
520 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
521 ASSERT_NE(g_delegate, nullptr);
522 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
523
524 /**
525 * @tc.steps: step1. Put 100 records.
526 * @tc.expected: Succeed, return OK.
527 */
528 const size_t RECORD_COUNT = 100; // 100 records.
529 for (size_t i = 0; i < RECORD_COUNT; ++i) {
530 EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
531 }
532
533 /**
534 * @tc.steps: step2. Get data limit 80, offset 30.
535 * @tc.expected: Get 70 records.
536 */
537 auto store = GetRelationalStore();
538 ASSERT_NE(store, nullptr);
539 ContinueToken token = nullptr;
540 const unsigned int LIMIT = 80; // limit as 80.
541 const unsigned int OFFSET = 30; // offset as 30.
542 const unsigned int EXPECT_COUNT = RECORD_COUNT - OFFSET; // expect 70 records.
543 QueryObject query(Query::Select(g_tableName).Limit(LIMIT, OFFSET));
544 std::vector<SingleVerKvEntry *> entries;
545
546 int errCode = store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries);
547 EXPECT_EQ(entries.size(), EXPECT_COUNT);
548 EXPECT_EQ(errCode, E_OK);
549 EXPECT_EQ(token, nullptr);
550 SingleVerKvEntry::Release(entries);
551 RefObject::DecObjRef(g_store);
552 }
553
554 /**
555 * @tc.name: GetQuerySyncData2
556 * @tc.desc: GetSyncData interface.
557 * @tc.type: FUNC
558 * @tc.require: AR000GK58H
559 * @tc.author: lidongwei
560 */
561 HWTEST_F(DistributedDBRelationalGetDataTest, GetQuerySyncData2, TestSize.Level1)
562 {
563 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
564 ASSERT_NE(g_delegate, nullptr);
565 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
566
567 /**
568 * @tc.steps: step1. Put 100 records.
569 * @tc.expected: Succeed, return OK.
570 */
571 const size_t RECORD_COUNT = 100; // 100 records.
572 for (size_t i = 0; i < RECORD_COUNT; ++i) {
573 EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
574 }
575
576 /**
577 * @tc.steps: step2. Get record whose key is not equal to 10 and value is not equal to 20, order by key desc.
578 * @tc.expected: Succeed, Get 98 records.
579 */
580 auto store = GetRelationalStore();
581 ASSERT_NE(store, nullptr);
582 ContinueToken token = nullptr;
583
584 Query query = Query::Select(g_tableName).NotEqualTo("key", 10).And().NotEqualTo("value", 20).OrderBy("key", false);
585 QueryObject queryObj(query);
586 queryObj.SetSchema(store->GetSchemaInfo());
587
588 std::vector<SingleVerKvEntry *> entries;
589 EXPECT_EQ(store->GetSyncData(queryObj, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
590 EXPECT_EQ(token, nullptr);
591 size_t expectCount = 98; // expect 98 records.
592 EXPECT_EQ(entries.size(), expectCount);
593 for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
594 auto nextOne = std::next(iter, 1);
595 if (nextOne != entries.end()) {
596 EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
597 }
598 }
599 SingleVerKvEntry::Release(entries);
600
601 /**
602 * @tc.steps: step3. Get record whose key is equal to 10 or value is equal to 20, order by key asc.
603 * @tc.expected: Succeed, Get 98 records.
604 */
605 query = Query::Select(g_tableName).EqualTo("key", 10).Or().EqualTo("value", 20).OrderBy("key", true);
606 queryObj = QueryObject(query);
607 queryObj.SetSchema(store->GetSchemaInfo());
608
609 EXPECT_EQ(store->GetSyncData(queryObj, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
610 EXPECT_EQ(token, nullptr);
611 expectCount = 2; // expect 2 records.
612 EXPECT_EQ(entries.size(), expectCount);
613 for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
614 auto nextOne = std::next(iter, 1);
615 if (nextOne != entries.end()) {
616 EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
617 }
618 }
619 SingleVerKvEntry::Release(entries);
620 RefObject::DecObjRef(g_store);
621 }
622
623 /**
624 * @tc.name: GetIncorrectTypeData1
625 * @tc.desc: GetSyncData and PutSyncDataWithQuery interface.
626 * @tc.type: FUNC
627 * @tc.require: AR000GK58H
628 * @tc.author: lidongwei
629 */
630 HWTEST_F(DistributedDBRelationalGetDataTest, GetIncorrectTypeData1, TestSize.Level1)
631 {
632 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
633 ASSERT_NE(g_delegate, nullptr);
634 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
635
636 /**
637 * @tc.steps: step1. Create 2 index for table "data".
638 * @tc.expected: Succeed, return OK.
639 */
640 sqlite3 *db = nullptr;
641 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
642
643 ExecSqlAndAssertOK(db, {"CREATE INDEX index1 ON " + g_tableName + "(value);",
644 "CREATE UNIQUE INDEX index2 ON " + g_tableName + "(value,key);"});
645
646 /**
647 * @tc.steps: step2. Create distributed table "dataPlus".
648 * @tc.expected: Succeed, return OK.
649 */
650 const string tableName = g_tableName + "Plus";
651 string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
652 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
653 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
654
655 /**
656 * @tc.steps: step3. Put 5 records with different type into "dataPlus" table.
657 * @tc.expected: Succeed, return OK.
658 */
659 const size_t RECORD_COUNT = 5; // 5 sqls
660 ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
661 "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
662 "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
663 "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
664 "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');"});
665
666 /**
667 * @tc.steps: step4. Get all data from "dataPlus" table.
668 * @tc.expected: Succeed and the count is right.
669 */
670 auto store = GetRelationalStore();
671 ASSERT_NE(store, nullptr);
672 ContinueToken token = nullptr;
673 QueryObject query(Query::Select(tableName));
674 std::vector<SingleVerKvEntry *> entries;
675 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
676 EXPECT_EQ(entries.size(), RECORD_COUNT);
677
678 /**
679 * @tc.steps: step5. Put data into "data" table from deviceA.
680 * @tc.expected: Succeed, return OK.
681 */
682 QueryObject queryPlus(Query::Select(g_tableName));
683 const DeviceID deviceID = "deviceA";
684 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
685 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
686 ASSERT_EQ(E_OK, SQLiteUtils::CloneIndexes(db, g_tableName,
687 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
688 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
689 SingleVerKvEntry::Release(entries);
690
691 /**
692 * @tc.steps: step6. Check data.
693 * @tc.expected: All data in the two tables are same.
694 */
695 ExpectCount(db, "SELECT count(*) FROM " + tableName + " as a, " + DBConstant::RELATIONAL_PREFIX + g_tableName +
696 "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b "
697 "WHERE a.key=b.key AND (a.value=b.value OR (a.value is NULL AND b.value is NULL));", RECORD_COUNT);
698
699 /**
700 * @tc.steps: step7. Check index.
701 * @tc.expected: 2 index for deviceA's data table exists.
702 */
703 ExpectCount(db,
704 "SELECT count(*) FROM sqlite_master WHERE type='index' AND tbl_name='" + DBConstant::RELATIONAL_PREFIX +
705 g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "'", 2U); // 2 index
706 sqlite3_close(db);
707 RefObject::DecObjRef(g_store);
708 }
709
710 /**
711 * @tc.name: UpdateData1
712 * @tc.desc: UpdateData succeed when the table has primary key.
713 * @tc.type: FUNC
714 * @tc.require: AR000GK58H
715 * @tc.author: lidongwei
716 */
717 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateData1, TestSize.Level1)
718 {
719 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
720 ASSERT_NE(g_delegate, nullptr);
721 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
722
723 /**
724 * @tc.steps: step1. Create distributed table "dataPlus".
725 * @tc.expected: Succeed, return OK.
726 */
727 const string tableName = g_tableName + "Plus";
728 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
729 sqlite3 *db = nullptr;
730 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
731 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
732 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
733
734 /**
735 * @tc.steps: step2. Put 5 records with different type into "dataPlus" table.
736 * @tc.expected: Succeed, return OK.
737 */
738 vector<string> sqls = {
739 "INSERT INTO " + tableName + " VALUES(NULL, 1);",
740 "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
741 "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
742 "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
743 "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');",
744 };
745 const size_t RECORD_COUNT = sqls.size();
746 for (const auto &item : sqls) {
747 ASSERT_EQ(sqlite3_exec(db, item.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
748 }
749
750 /**
751 * @tc.steps: step3. Get all data from "dataPlus" table.
752 * @tc.expected: Succeed and the count is right.
753 */
754 auto store = GetRelationalStore();
755 ASSERT_NE(store, nullptr);
756 ContinueToken token = nullptr;
757 QueryObject query(Query::Select(tableName));
758 std::vector<SingleVerKvEntry *> entries;
759 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
760 EXPECT_EQ(entries.size(), RECORD_COUNT);
761
762 /**
763 * @tc.steps: step4. Put data into "data" table from deviceA for 10 times.
764 * @tc.expected: Succeed, return OK.
765 */
766 query = QueryObject(Query::Select(g_tableName));
767 const DeviceID deviceID = "deviceA";
768 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
769 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
770 for (uint32_t i = 0; i < 10; ++i) { // 10 for test.
771 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
772 }
773 SingleVerKvEntry::Release(entries);
774
775 /**
776 * @tc.steps: step5. Check data.
777 * @tc.expected: There is 5 data in table.
778 */
779 sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
780 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
781 size_t count = 0;
782 EXPECT_EQ(GetCount(db, sql, count), E_OK);
783 EXPECT_EQ(count, RECORD_COUNT);
784
785 sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;";
786 count = 0;
787 EXPECT_EQ(GetCount(db, sql, count), E_OK);
788 EXPECT_EQ(count, RECORD_COUNT);
789
790 sqlite3_close(db);
791 RefObject::DecObjRef(g_store);
792 }
793
794 /**
795 * @tc.name: UpdateDataWithMulDevData1
796 * @tc.desc: UpdateData succeed when there is multiple devices data exists.
797 * @tc.type: FUNC
798 * @tc.require: AR000GK58H
799 * @tc.author: lidongwei
800 */
801 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateDataWithMulDevData1, TestSize.Level1)
802 {
803 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
804 ASSERT_NE(g_delegate, nullptr);
805 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
806 /**
807 * @tc.steps: step1. Create distributed table "dataPlus".
808 * @tc.expected: Succeed, return OK.
809 */
810 const string tableName = g_tableName + "Plus";
811 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
812 sqlite3 *db = nullptr;
813 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
814 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
815 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
816 /**
817 * @tc.steps: step2. Put k1v1 into "dataPlus" table.
818 * @tc.expected: Succeed, return OK.
819 */
820 sql = "INSERT INTO " + tableName + " VALUES(1, 1);"; // k1v1
821 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
822 /**
823 * @tc.steps: step3. Get k1v1 from "dataPlus" table.
824 * @tc.expected: Succeed and the count is right.
825 */
826 auto store = GetRelationalStore();
827 ASSERT_NE(store, nullptr);
828 ContinueToken token = nullptr;
829 QueryObject query(Query::Select(tableName));
830 std::vector<SingleVerKvEntry *> entries;
831 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
832 /**
833 * @tc.steps: step4. Put k1v1 into "data" table from deviceA.
834 * @tc.expected: Succeed, return OK.
835 */
836 query = QueryObject(Query::Select(g_tableName));
837 const DeviceID deviceID = "deviceA";
838 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
839 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
840 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
841 SingleVerKvEntry::Release(entries);
842 /**
843 * @tc.steps: step4. Put k1v1 into "data" table.
844 * @tc.expected: Succeed, return OK.
845 */
846 EXPECT_EQ(AddOrUpdateRecord(1, 1), E_OK); // k1v1
847 /**
848 * @tc.steps: step5. Change k1v1 to k1v2
849 * @tc.expected: Succeed, return OK.
850 */
851 sql = "UPDATE " + g_tableName + " SET value=2 WHERE key=1;"; // k1v1
852 EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); // change k1v1 to k1v2
853
854 sqlite3_close(db);
855 RefObject::DecObjRef(g_store);
856 }
857
858 /**
859 * @tc.name: MissQuery1
860 * @tc.desc: Check REMOTE_DEVICE_DATA_MISS_QUERY flag succeed.
861 * @tc.type: FUNC
862 * @tc.require: AR000GK58H
863 * @tc.author: lidongwei
864 */
865 HWTEST_F(DistributedDBRelationalGetDataTest, MissQuery1, TestSize.Level1)
866 {
867 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
868 ASSERT_NE(g_delegate, nullptr);
869 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
870 /**
871 * @tc.steps: step1. Create distributed table "dataPlus".
872 * @tc.expected: Succeed, return OK.
873 */
874 const string tableName = g_tableName + "Plus";
875 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
876 sqlite3 *db = nullptr;
877 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
878 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
879 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
880
881 /**
882 * @tc.steps: step2. Put 5 records with different type into "dataPlus" table.
883 * @tc.expected: Succeed, return OK.
884 */
885 ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
886 "INSERT INTO " + tableName + " VALUES(NULL, 2);", "INSERT INTO " + tableName + " VALUES(NULL, 3);",
887 "INSERT INTO " + tableName + " VALUES(NULL, 4);", "INSERT INTO " + tableName + " VALUES(NULL, 5);"});
888
889 /**
890 * @tc.steps: step3. Get all data from "dataPlus" table.
891 * @tc.expected: Succeed and the count is right.
892 */
893 auto store = GetRelationalStore();
894 ASSERT_NE(store, nullptr);
895 ContinueToken token = nullptr;
896 SyncTimeRange timeRange;
897 QueryObject query(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4));
898 std::vector<SingleVerKvEntry *> entries;
899 EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK);
900 timeRange.lastQueryTime = (*(entries.rbegin()))->GetTimestamp();
901 EXPECT_EQ(entries.size(), 3U); // 3 for test
902
903 /**
904 * @tc.steps: step4. Put data into "data" table from deviceA for 10 times.
905 * @tc.expected: Succeed, return OK.
906 */
907 query = QueryObject(Query::Select(g_tableName));
908 const DeviceID deviceID = "deviceA";
909 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
910 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
911 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
912 SingleVerKvEntry::Release(entries);
913
914 /**
915 * @tc.steps: step5. Check data.
916 * @tc.expected: There is 3 data in table.
917 */
918 std::string getDataSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
919 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
920 ExpectCount(db, getDataSql, 3); // 2,3,4
921
922 std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;";
923 ExpectCount(db, getLogSql, 3); // 2,3,4
924
925 /**
926 * @tc.steps: step6. Update data. k2v2 to k2v102, k3v3 to k3v103, k4v4 to k4v104.
927 * @tc.expected: Update succeed.
928 */
929 ExecSqlAndAssertOK(db, {"INSERT OR REPLACE INTO " + tableName + " VALUES(2, 102);",
930 "UPDATE " + tableName + " SET value=103 WHERE value=3;",
931 "DELETE FROM " + tableName + " WHERE key=4;",
932 "INSERT INTO " + tableName + " VALUES(4, 104);"});
933
934 /**
935 * @tc.steps: step7. Get all data from "dataPlus" table.
936 * @tc.expected: Succeed and the count is right.
937 */
938 query = QueryObject(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4));
939 EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK);
940 EXPECT_EQ(entries.size(), 3U); // 3 miss query data.
941
942 /**
943 * @tc.steps: step8. Put data into "data" table from deviceA for 10 times.
944 * @tc.expected: Succeed, return OK.
945 */
946 query = QueryObject(Query::Select(g_tableName));
947 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
948 SingleVerKvEntry::Release(entries);
949
950 /**
951 * @tc.steps: step9. Check data.
952 * @tc.expected: There is 0 data in table.
953 */
954 ExpectCount(db, getDataSql, 0U); // 0 data exists
955 ExpectCount(db, getLogSql, 0U); // 0 data exists
956
957 sqlite3_close(db);
958 RefObject::DecObjRef(g_store);
959 }
960
961 /**
962 * @tc.name: CompatibleData1
963 * @tc.desc: Check compatibility.
964 * @tc.type: FUNC
965 * @tc.require: AR000GK58H
966 * @tc.author: lidongwei
967 */
968 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData1, TestSize.Level1)
969 {
970 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
971 ASSERT_NE(g_delegate, nullptr);
972 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
973 /**
974 * @tc.steps: step1. Create distributed table "dataPlus".
975 * @tc.expected: Succeed, return OK.
976 */
977 const string tableName = g_tableName + "Plus";
978 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
979 extra_field TEXT NOT NULL DEFAULT 'default_value');";
980 sqlite3 *db = nullptr;
981 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
982 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
983 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
984 /**
985 * @tc.steps: step2. Put 1 record into data and dataPlus table.
986 * @tc.expected: Succeed, return OK.
987 */
988 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
989 sql = "INSERT INTO " + tableName + " VALUES(2, 102, 'f3');"; // k2v102
990 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
991 /**
992 * @tc.steps: step3. Get all data from "data" table.
993 * @tc.expected: Succeed and the count is right.
994 */
995 auto store = GetRelationalStore();
996 ASSERT_NE(store, nullptr);
997 ContinueToken token = nullptr;
998 QueryObject query(Query::Select(g_tableName));
999 std::vector<SingleVerKvEntry *> entries;
1000 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1001 EXPECT_EQ(entries.size(), 1UL);
1002 /**
1003 * @tc.steps: step4. Put data into "data_plus" table from deviceA.
1004 * @tc.expected: Succeed, return OK.
1005 */
1006 QueryObject queryPlus(Query::Select(tableName));
1007 const DeviceID deviceID = "deviceA";
1008 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName),
1009 DBCommon::GetDistributedTableName(deviceID, tableName)));
1010 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1011 SingleVerKvEntry::Release(entries);
1012 /**
1013 * @tc.steps: step4. Get all data from "dataPlus" table.
1014 * @tc.expected: Succeed and the count is right.
1015 */
1016 EXPECT_EQ(store->GetSyncData(queryPlus, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1017 EXPECT_EQ(entries.size(), 1UL);
1018 /**
1019 * @tc.steps: step5. Put data into "data" table from deviceA.
1020 * @tc.expected: Succeed, return OK.
1021 */
1022 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
1023 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
1024 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
1025 SingleVerKvEntry::Release(entries);
1026 /**
1027 * @tc.steps: step6. Check data.
1028 * @tc.expected: All data in the two tables are same.
1029 */
1030 sql = "SELECT count(*) FROM " + g_tableName + " as a," + DBConstant::RELATIONAL_PREFIX + tableName + "_" +
1031 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " +
1032 "WHERE a.key=b.key AND a.value=b.value;";
1033 size_t count = 0;
1034 EXPECT_EQ(GetCount(db, sql, count), E_OK);
1035 EXPECT_EQ(count, 1UL);
1036 sql = "SELECT count(*) FROM " + tableName + " as a," + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
1037 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " +
1038 "WHERE a.key=b.key AND a.value=b.value;";
1039 count = 0;
1040 EXPECT_EQ(GetCount(db, sql, count), E_OK);
1041 EXPECT_EQ(count, 1UL);
1042 sqlite3_close(db);
1043 RefObject::DecObjRef(g_store);
1044 }
1045
1046 /**
1047 * @tc.name: GetDataSortByTime1
1048 * @tc.desc: All query get data sort by time asc.
1049 * @tc.type: FUNC
1050 * @tc.require: AR000GK58H
1051 * @tc.author: lidongwei
1052 */
1053 HWTEST_F(DistributedDBRelationalGetDataTest, GetDataSortByTime1, TestSize.Level1)
1054 {
1055 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1056 ASSERT_NE(g_delegate, nullptr);
1057 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1058 /**
1059 * @tc.steps: step2. Add 3 record into data. k1v105, k2v104, k3v103, timestamp desc.
1060 * @tc.expected: Succeed, return OK.
1061 */
1062 sqlite3 *db = nullptr;
1063 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1064 std::string sql = "INSERT INTO " + g_tableName + " VALUES(1, 101);"; // k1v101
1065 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1066 sql = "INSERT INTO " + g_tableName + " VALUES(2, 102);"; // k2v102
1067 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1068 sql = "INSERT INTO " + g_tableName + " VALUES(3, 103);"; // k3v103
1069 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1070 sql = "UPDATE " + g_tableName + " SET value=104 WHERE key=2;"; // k2v104
1071 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1072 sql = "UPDATE " + g_tableName + " SET value=105 WHERE key=1;"; // k1v105
1073 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1074 /**
1075 * @tc.steps: step3. Get all data from "data" table by all query.
1076 * @tc.expected: Succeed and the count is right.
1077 */
1078 auto store = GetRelationalStore();
1079 ASSERT_NE(store, nullptr);
1080 ContinueToken token = nullptr;
1081 QueryObject query(Query::Select(g_tableName));
1082 std::vector<SingleVerKvEntry *> entries;
1083 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1084 ExpectMissQueryCnt(entries, 3UL); // 3 data
1085 SingleVerKvEntry::Release(entries);
1086
1087 query = QueryObject(Query::Select(g_tableName).EqualTo("key", 1).Or().EqualTo("key", 3));
1088 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1089 ExpectMissQueryCnt(entries, 2UL); // 2 data
1090 SingleVerKvEntry::Release(entries);
1091
1092 query = QueryObject(Query::Select(g_tableName).OrderBy("key", false));
1093 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1094 ExpectMissQueryCnt(entries, 3UL); // 3 data
1095 SingleVerKvEntry::Release(entries);
1096
1097 query = QueryObject(Query::Select(g_tableName).OrderBy("value", false));
1098 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1099 ExpectMissQueryCnt(entries, 3UL); // 3 data
1100 SingleVerKvEntry::Release(entries);
1101
1102 query = QueryObject(Query::Select(g_tableName).Limit(2));
1103 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1104 ExpectMissQueryCnt(entries, 2UL); // 2 data
1105 SingleVerKvEntry::Release(entries);
1106
1107 sqlite3_close(db);
1108 RefObject::DecObjRef(g_store);
1109 }
1110
1111 /**
1112 * @tc.name: SameFieldWithLogTable1
1113 * @tc.desc: Get query data OK when the table has same field with log table.
1114 * @tc.type: FUNC
1115 * @tc.require: AR000GK58H
1116 * @tc.author: lidongwei
1117 */
1118 HWTEST_F(DistributedDBRelationalGetDataTest, SameFieldWithLogTable1, TestSize.Level1)
1119 {
1120 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1121 ASSERT_NE(g_delegate, nullptr);
1122 /**
1123 * @tc.steps: step1. Create distributed table "dataPlus".
1124 * @tc.expected: Succeed, return OK.
1125 */
1126 const string tableName = g_tableName + "Plus";
1127 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, flag INTEGER NOT NULL, \
1128 device TEXT NOT NULL DEFAULT 'default_value');";
1129 sqlite3 *db = nullptr;
1130 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1131 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1132 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1133 /**
1134 * @tc.steps: step2. Put 1 record into dataPlus table.
1135 * @tc.expected: Succeed, return OK.
1136 */
1137 sql = "INSERT INTO " + tableName + " VALUES(1, 101, 'f3');"; // k1v101
1138 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1139 /**
1140 * @tc.steps: step3. Get all data from dataPlus table.
1141 * @tc.expected: Succeed and the count is right.
1142 */
1143 auto store = GetRelationalStore();
1144 ASSERT_NE(store, nullptr);
1145 ContinueToken token = nullptr;
1146 QueryObject query(Query::Select(tableName).EqualTo("flag", 101).OrderBy("device", false));
1147 std::vector<SingleVerKvEntry *> entries;
1148 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1149 EXPECT_EQ(entries.size(), 1UL);
1150 SingleVerKvEntry::Release(entries);
1151 sqlite3_close(db);
1152 RefObject::DecObjRef(g_store);
1153 }
1154
1155 /**
1156 * @tc.name: CompatibleData2
1157 * @tc.desc: Check compatibility.
1158 * @tc.type: FUNC
1159 * @tc.require: AR000GK58H
1160 * @tc.author: lidongwei
1161 */
1162 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData2, TestSize.Level1)
1163 {
1164 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1165 ASSERT_NE(g_delegate, nullptr);
1166 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1167
1168 sqlite3 *db = nullptr;
1169 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1170
1171 auto store = GetRelationalStore();
1172 ASSERT_NE(store, nullptr);
1173
1174 /**
1175 * @tc.steps: step1. Create distributed table from deviceA.
1176 * @tc.expected: Succeed, return OK.
1177 */
1178 const DeviceID deviceID = "deviceA";
1179 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
1180 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
1181
1182 /**
1183 * @tc.steps: step2. Alter "data" table and create distributed table again.
1184 * @tc.expected: Succeed.
1185 */
1186 std::string sql = "ALTER TABLE " + g_tableName + " ADD COLUMN integer_type INTEGER DEFAULT 123 not null;"
1187 "ALTER TABLE " + g_tableName + " ADD COLUMN text_type TEXT DEFAULT 'high_version' not null;"
1188 "ALTER TABLE " + g_tableName + " ADD COLUMN real_type REAL DEFAULT 123.123456 not null;"
1189 "ALTER TABLE " + g_tableName + " ADD COLUMN blob_type BLOB DEFAULT 123 not null;";
1190 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1191 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1192
1193 /**
1194 * @tc.steps: step3. Check deviceA's distributed table.
1195 * @tc.expected: The create sql is correct.
1196 */
1197 std::string expectSql = "CREATE TABLE naturalbase_rdb_aux_data_"
1198 "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f(key integer NOT NULL,"
1199 "value integer, integer_type integer NOT NULL DEFAULT 123, text_type text NOT NULL DEFAULT 'high_version', "
1200 "real_type real NOT NULL DEFAULT 123.123456, blob_type blob NOT NULL DEFAULT 123, PRIMARY KEY (key))";
1201 sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
1202 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';";
1203 EXPECT_EQ(GetOneText(db, sql), expectSql);
1204
1205 sqlite3_close(db);
1206 RefObject::DecObjRef(g_store);
1207 }
1208
1209 /**
1210 * @tc.name: PutSyncDataConflictDataTest001
1211 * @tc.desc: Check put with conflict sync data.
1212 * @tc.type: FUNC
1213 * @tc.require: AR000GK58H
1214 * @tc.author: lianhuix
1215 */
1216 HWTEST_F(DistributedDBRelationalGetDataTest, PutSyncDataConflictDataTest001, TestSize.Level1)
1217 {
1218 const DeviceID deviceID_A = "deviceA";
1219 const DeviceID deviceID_B = "deviceB";
1220 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath);
1221 RelationalTestUtils::CreateDeviceTable(db, g_tableName, deviceID_B);
1222
1223 DBStatus status = g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate);
1224 EXPECT_EQ(status, DBStatus::OK);
1225 ASSERT_NE(g_delegate, nullptr);
1226 EXPECT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1227
1228 auto store = const_cast<RelationalSyncAbleStorage *>(GetRelationalStore());
1229 ASSERT_NE(store, nullptr);
1230
1231 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1001,'VAL_1');");
1232 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1002,'VAL_2');");
1233 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1003,'VAL_3');");
1234
1235 DataSizeSpecInfo sizeInfo {MTU_SIZE, 50};
1236 ContinueToken token = nullptr;
1237 QueryObject query(Query::Select(g_tableName));
1238 std::vector<SingleVerKvEntry *> entries;
1239 int errCode = store->GetSyncData(query, {}, sizeInfo, token, entries);
1240 EXPECT_EQ(errCode, E_OK);
1241
1242 errCode = store->PutSyncDataWithQuery(query, entries, deviceID_B);
1243 EXPECT_EQ(errCode, E_OK);
1244 GenericSingleVerKvEntry::Release(entries);
1245
1246 QueryObject query2(Query::Select(g_tableName).EqualTo("key", 1001));
1247 std::vector<SingleVerKvEntry *> entries2;
1248 store->GetSyncData(query2, {}, sizeInfo, token, entries2);
1249
1250 errCode = store->PutSyncDataWithQuery(query, entries2, deviceID_B);
1251 EXPECT_EQ(errCode, E_OK);
1252 GenericSingleVerKvEntry::Release(entries2);
1253
1254 RefObject::DecObjRef(g_store);
1255
1256 std::string deviceTable = DBCommon::GetDistributedTableName(deviceID_B, g_tableName);
1257 EXPECT_EQ(RelationalTestUtils::CheckTableRecords(db, deviceTable), 3);
1258 sqlite3_close_v2(db);
1259 }
1260
1261 /**
1262 * @tc.name: SaveNonexistDevdata1
1263 * @tc.desc: Save non-exist device data and check errCode.
1264 * @tc.type: FUNC
1265 * @tc.require: AR000GK58H
1266 * @tc.author: lidongwei
1267 */
1268 HWTEST_F(DistributedDBRelationalGetDataTest, SaveNonexistDevdata1, TestSize.Level1)
1269 {
1270 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1271 ASSERT_NE(g_delegate, nullptr);
1272 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1273 /**
1274 * @tc.steps: step1. Create distributed table "dataPlus".
1275 * @tc.expected: Succeed, return OK.
1276 */
1277 const string tableName = g_tableName + "Plus";
1278 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1279 extra_field TEXT NOT NULL DEFAULT 'default_value');";
1280 sqlite3 *db = nullptr;
1281 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1282 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1283 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1284 /**
1285 * @tc.steps: step2. Put 1 record into data table.
1286 * @tc.expected: Succeed, return OK.
1287 */
1288 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1289
1290 /**
1291 * @tc.steps: step3. Get all data from "data" table.
1292 * @tc.expected: Succeed and the count is right.
1293 */
1294 auto store = GetRelationalStore();
1295 ASSERT_NE(store, nullptr);
1296 ContinueToken token = nullptr;
1297 QueryObject query(Query::Select(g_tableName));
1298 std::vector<SingleVerKvEntry *> entries;
1299 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1300 EXPECT_EQ(entries.size(), 1UL);
1301
1302 /**
1303 * @tc.steps: step4. Put data into "data_plus" table from deviceA and deviceA does not exist.
1304 * @tc.expected: Succeed, return OK.
1305 */
1306 query = QueryObject(Query::Select(tableName));
1307 const DeviceID deviceID = "deviceA";
1308 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID),
1309 -1); // -1 means error
1310 SingleVerKvEntry::Release(entries);
1311
1312 sqlite3_close(db);
1313 RefObject::DecObjRef(g_store);
1314 }
1315
1316 /**
1317 * @tc.name: GetMaxTimestamp1
1318 * @tc.desc: Get max timestamp.
1319 * @tc.type: FUNC
1320 * @tc.require: AR000GK58H
1321 * @tc.author: lidongwei
1322 */
1323 HWTEST_F(DistributedDBRelationalGetDataTest, GetMaxTimestamp1, TestSize.Level1)
1324 {
1325 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1326 ASSERT_NE(g_delegate, nullptr);
1327 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1328 /**
1329 * @tc.steps: step1. Create distributed table "dataPlus".
1330 * @tc.expected: Succeed, return OK.
1331 */
1332 sqlite3 *db = nullptr;
1333 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1334 const string tableName = g_tableName + "Plus";
1335 ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1336 extra_field TEXT NOT NULL DEFAULT 'default_value');");
1337 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1338
1339 /**
1340 * @tc.steps: step2. Get max timestamp when no data exists.
1341 * @tc.expected: Succeed and the time is 0;
1342 */
1343 auto store = GetRelationalStore();
1344 ASSERT_NE(store, nullptr);
1345
1346 Timestamp time1 = 0;
1347 store->GetMaxTimestamp(time1);
1348 EXPECT_EQ(time1, 0ull);
1349
1350 /**
1351 * @tc.steps: step3. Put 1 record into data table and get max timestamp.
1352 * @tc.expected: Succeed and the time is updated.
1353 */
1354 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1355 Timestamp time2 = 0;
1356 store->GetMaxTimestamp(time2);
1357 EXPECT_GT(time2, time1);
1358
1359 /**
1360 * @tc.steps: step4. Put 1 record into data table and get max timestamp.
1361 * @tc.expected: Succeed and the time is updated.
1362 */
1363 ASSERT_EQ(AddOrUpdateRecord(2, 102), E_OK);
1364 Timestamp time3 = 0;
1365 store->GetMaxTimestamp(time3);
1366 EXPECT_GT(time3, time2);
1367
1368 /**
1369 * @tc.steps: step5. Put 1 record into data table and get the max timestamp of data table.
1370 * @tc.expected: Succeed and the time is equals to max timestamp in DB.
1371 */
1372 Timestamp time4 = 0;
1373 store->GetMaxTimestamp(g_tableName, time4);
1374 EXPECT_EQ(time4, time3);
1375
1376 /**
1377 * @tc.steps: step6. Put 1 record into data table and get the max timestamp of dataPlus table.
1378 * @tc.expected: Succeed and the time is 0.
1379 */
1380 Timestamp time5 = 0;
1381 store->GetMaxTimestamp(tableName, time5);
1382 EXPECT_EQ(time5, 0ull);
1383
1384 sqlite3_close(db);
1385 RefObject::DecObjRef(g_store);
1386 }
1387
1388 /**
1389 * @tc.name: NoPkData1
1390 * @tc.desc: For no pk data.
1391 * @tc.type: FUNC
1392 * @tc.require: AR000GK58H
1393 * @tc.author: lidongwei
1394 */
1395 HWTEST_F(DistributedDBRelationalGetDataTest, NoPkData1, TestSize.Level1)
1396 {
1397 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1398 ASSERT_NE(g_delegate, nullptr);
1399
1400 sqlite3 *db = nullptr;
1401 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1402 ExecSqlAndAssertOK(db, "DROP TABLE IF EXISTS " + g_tableName + "; \
1403 CREATE TABLE " + g_tableName + "(key INTEGER NOT NULL, value INTEGER);");
1404 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1405
1406 /**
1407 * @tc.steps: step1. Create distributed table "dataPlus".
1408 * @tc.expected: Succeed, return OK.
1409 */
1410 const string tableName = g_tableName + "Plus";
1411 ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER NOT NULL, value INTEGER);");
1412 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1413
1414 /**
1415 * @tc.steps: step2. Put 2 data into "data" table.
1416 * @tc.expected: Succeed.
1417 */
1418 ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK);
1419 ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK);
1420
1421 /**
1422 * @tc.steps: step3. Get data from "data" table.
1423 * @tc.expected: Succeed.
1424 */
1425 auto store = GetRelationalStore();
1426 ASSERT_NE(store, nullptr);
1427
1428 ContinueToken token = nullptr;
1429 QueryObject query(Query::Select(g_tableName));
1430 std::vector<SingleVerKvEntry *> entries;
1431 EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK);
1432 EXPECT_EQ(entries.size(), 2U); // expect 2 data.
1433
1434 /**
1435 * @tc.steps: step4. Put data into "data" table from deviceA.
1436 * @tc.expected: Succeed, return OK.
1437 */
1438 QueryObject queryPlus(Query::Select(tableName));
1439 const DeviceID deviceID = "deviceA";
1440 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName),
1441 DBCommon::GetDistributedTableName(deviceID, tableName)));
1442 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1443 SingleVerKvEntry::Release(entries);
1444
1445 /**
1446 * @tc.steps: step5. Changet data in "data" table.
1447 * @tc.expected: Succeed.
1448 */
1449 ExecSqlAndAssertOK(db, {"UPDATE " + g_tableName + " SET value=101 WHERE key=1;",
1450 "DELETE FROM " + g_tableName + " WHERE key=2;",
1451 "INSERT INTO " + g_tableName + " VALUES(2, 102);"});
1452
1453 /**
1454 * @tc.steps: step6. Get data from "data" table.
1455 * @tc.expected: Succeed.
1456 */
1457 EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK);
1458 EXPECT_EQ(entries.size(), 2U); // expect 2 data.
1459
1460 /**
1461 * @tc.steps: step7. Put data into "data" table from deviceA.
1462 * @tc.expected: Succeed, return OK.
1463 */
1464 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1465 SingleVerKvEntry::Release(entries);
1466
1467 /**
1468 * @tc.steps: step8. Check data.
1469 * @tc.expected: There is 2 data.
1470 */
1471 std::string sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_" +
1472 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
1473 size_t count = 0;
1474 EXPECT_EQ(GetCount(db, sql, count), E_OK);
1475 EXPECT_EQ(count, 2U); // expect 2 data.
1476
1477 sqlite3_close(db);
1478 RefObject::DecObjRef(g_store);
1479 }
1480
1481 /**
1482 * @tc.name: GetAfterDropTable1
1483 * @tc.desc: Get data after drop table.
1484 * @tc.type: FUNC
1485 * @tc.require: AR000H2QPN
1486 * @tc.author: lidongwei
1487 */
1488 HWTEST_F(DistributedDBRelationalGetDataTest, GetAfterDropTable1, TestSize.Level1)
1489 {
1490 /**
1491 * @tc.steps: step1. Create distributed table.
1492 * @tc.expected: Succeed, return OK.
1493 */
1494 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1495 ASSERT_NE(g_delegate, nullptr);
1496 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1497
1498 /**
1499 * @tc.steps: step2. Insert several data.
1500 * @tc.expected: Succeed, return OK.
1501 */
1502 ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK);
1503 ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK);
1504 ASSERT_EQ(AddOrUpdateRecord(3, 3), E_OK);
1505
1506 /**
1507 * @tc.steps: step3. Check data in distributed log table.
1508 * @tc.expected: The data in log table is in expect. All the flag in log table is 1.
1509 */
1510 sqlite3 *db = nullptr;
1511 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1512
1513 std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log "
1514 "WHERE flag&0x01<>0;";
1515 ExpectCount(db, getLogSql, 0u); // 0 means no deleted data.
1516
1517 /**
1518 * @tc.steps: step4. Drop the table in another connection.
1519 * @tc.expected: Succeed.
1520 */
__anon0dd17ad30202null1521 std::thread t1([] {
1522 sqlite3 *db = nullptr;
1523 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1524 ExecSqlAndAssertOK(db, "DROP TABLE " + g_tableName);
1525 sqlite3_close(db);
1526 });
1527 t1.join();
1528 std::this_thread::sleep_for(std::chrono::seconds(1));
1529 /**
1530 * @tc.steps: step5. Check data in distributed log table.
1531 * @tc.expected: The data in log table is in expect. All the flag in log table is 3.
1532 */
1533 ExpectCount(db, getLogSql, 3u); // 3 means all deleted data.
1534 sqlite3_close(db);
1535 }
1536
1537 /**
1538 * @tc.name: SetSchema1
1539 * @tc.desc: Test invalid parameters of query_object.cpp
1540 * @tc.type: FUNC
1541 * @tc.require:
1542 * @tc.author: bty
1543 */
1544 HWTEST_F(DistributedDBRelationalGetDataTest, SetSchema1, TestSize.Level1)
1545 {
1546 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1547 ASSERT_NE(g_delegate, nullptr);
1548 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1549 auto store = GetRelationalStore();
1550 ASSERT_NE(store, nullptr);
1551 Query query = Query::Select().OrderBy("errDevice", false);
1552 QueryObject queryObj1(query);
1553 int errorNo = E_OK;
1554 errorNo = queryObj1.SetSchema(store->GetSchemaInfo());
1555 EXPECT_EQ(errorNo, -E_INVALID_ARGS);
1556 EXPECT_FALSE(queryObj1.IsQueryForRelationalDB());
1557 errorNo = queryObj1.Init();
1558 EXPECT_EQ(errorNo, -E_NOT_SUPPORT);
1559 QueryObject queryObj2(query);
1560 queryObj2.SetTableName(g_tableName);
1561 errorNo = queryObj2.SetSchema(store->GetSchemaInfo());
1562 EXPECT_EQ(errorNo, E_OK);
1563 errorNo = queryObj2.Init();
1564 EXPECT_EQ(errorNo, -E_INVALID_QUERY_FIELD);
1565 RefObject::DecObjRef(g_store);
1566 }
1567
1568 /**
1569 * @tc.name: SetNextBeginTime001
1570 * @tc.desc: Test invalid parameters of query_object.cpp
1571 * @tc.type: FUNC
1572 * @tc.require:
1573 * @tc.author: bty
1574 */
1575 HWTEST_F(DistributedDBRelationalGetDataTest, SetNextBeginTime001, TestSize.Level1)
1576 {
1577 QueryObject query(Query::Select(g_tableName));
1578 std::unique_ptr<SQLiteSingleVerRelationalContinueToken> token =
1579 std::make_unique<SQLiteSingleVerRelationalContinueToken>(SyncTimeRange {}, query);
1580 ASSERT_TRUE(token != nullptr);
1581
1582 DataItem dataItem;
1583 dataItem.timestamp = INT64_MAX;
1584 token->SetNextBeginTime(dataItem);
1585
1586 dataItem.flag = DataItem::DELETE_FLAG;
1587 token->FinishGetData();
1588 token->SetNextBeginTime(dataItem);
1589 }
1590 #endif
1591