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