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, " + 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 RefObject::DecObjRef(g_store);
400 }
401
402 /**
403 * @tc.name: GetSyncData2
404 * @tc.desc: GetSyncData interface. For overlarge data(over 4M), ignore it.
405 * @tc.type: FUNC
406 * @tc.require: AR000GK58H
407 * @tc.author: lidongwei
408 */
409 HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData2, TestSize.Level1)
410 {
411 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
412 ASSERT_NE(g_delegate, nullptr);
413 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
414
415 /**
416 * @tc.steps: step1. Put 10 records.(1M + 2M + 3M + 4M + 5M) * 2.
417 * @tc.expected: Succeed, return OK.
418 */
419 for (int i = 1; i <= 5; ++i) {
420 EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK); // 1024*1024 equals 1M.
421 }
422 for (int i = 1; i <= 5; ++i) {
423 EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK); // 1024*1024 equals 1M.
424 }
425
426 /**
427 * @tc.steps: step2. Get all data.
428 * @tc.expected: Succeed and the count is 6.
429 */
430 auto store = GetRelationalStore();
431 ASSERT_NE(store, nullptr);
432 ContinueToken token = nullptr;
433 QueryObject query(Query::Select(g_tableName));
434 std::vector<SingleVerKvEntry *> entries;
435
436 const size_t EXPECT_COUNT = 6; // expect 6 records.
437 DataSizeSpecInfo sizeInfo;
438 sizeInfo.blockSize = 100 * 1024 * 1024; // permit 100M.
439 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries), E_OK);
440 EXPECT_EQ(entries.size(), EXPECT_COUNT);
441 SingleVerKvEntry::Release(entries);
442 RefObject::DecObjRef(g_store);
443 }
444
445 /**
446 * @tc.name: GetSyncData3
447 * @tc.desc: GetSyncData interface. For deleted data.
448 * @tc.type: FUNC
449 * @tc.require: AR000GK58H
450 * @tc.author: lidongwei
451 */
452 HWTEST_F(DistributedDBRelationalGetDataTest, GetSyncData3, TestSize.Level1)
453 {
454 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
455 ASSERT_NE(g_delegate, nullptr);
456 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
457
458 /**
459 * @tc.steps: step1. Create distributed table "dataPlus".
460 * @tc.expected: Succeed, return OK.
461 */
462 const string tableName = g_tableName + "Plus";
463 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
464 sqlite3 *db = nullptr;
465 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
466 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
467 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
468
469 /**
470 * @tc.steps: step2. Put 5 records with different type into "dataPlus" table. Put 5 records into "data" table.
471 * @tc.expected: Succeed, return OK.
472 */
473 const size_t RECORD_COUNT = 5; // 5 records
474 ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
475 "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
476 "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
477 "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
478 "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');"});
479
480 /**
481 * @tc.steps: step3. Get all data from "dataPlus" table.
482 * @tc.expected: Succeed and the count is right.
483 */
484 auto store = GetRelationalStore();
485 ASSERT_NE(store, nullptr);
486 ContinueToken token = nullptr;
487 QueryObject query(Query::Select(tableName));
488 std::vector<SingleVerKvEntry *> entries;
489 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
490 EXPECT_EQ(entries.size(), RECORD_COUNT);
491
492 /**
493 * @tc.steps: step4. Put data into "data" table from deviceA and deviceB
494 * @tc.expected: Succeed, return OK.
495 */
496 QueryObject gQuery(Query::Select(g_tableName));
497 DeviceID deviceA = "deviceA";
498 DeviceID deviceB = "deviceB";
499 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
500 DBCommon::GetDistributedTableName(deviceA, g_tableName)));
501 SetRemoteSchema(store, deviceA);
502 SetRemoteSchema(store, deviceB);
503 auto rEntries = std::vector<SingleVerKvEntry *>(entries.rbegin(), entries.rend());
504 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
505 DBCommon::GetDistributedTableName(deviceB, g_tableName)));
506 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(gQuery, rEntries, deviceB), E_OK);
507 rEntries.clear();
508 SingleVerKvEntry::Release(entries);
509
510 /**
511 * @tc.steps: step5. Delete 2 "dataPlus" data from deviceA.
512 * @tc.expected: Succeed.
513 */
514 ExecSqlAndAssertOK(db, "DELETE FROM " + tableName + " WHERE rowid<=2;");
515 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
516 EXPECT_EQ(entries.size(), RECORD_COUNT);
517 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(gQuery, entries, deviceA), E_OK);
518 SingleVerKvEntry::Release(entries);
519
520 /**
521 * @tc.steps: step6. Check data.
522 * @tc.expected: 2 data in the from deviceA are deleted and all data from deviceB are not deleted.
523 */
524 ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName +
525 "_log WHERE flag&0x01=0x01;", 2U); // 2 deleted log
526 ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
527 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceA)) + ";", 3U); // 3 records in A
528 ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
529 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceB)) + ";", RECORD_COUNT); // 5 records in B
530
531 sqlite3_close(db);
532 RefObject::DecObjRef(g_store);
533 }
534
535 /**
536 * @tc.name: GetQuerySyncData1
537 * @tc.desc: GetSyncData interface.
538 * @tc.type: FUNC
539 * @tc.require: AR000GK58H
540 * @tc.author: lidongwei
541 */
542 HWTEST_F(DistributedDBRelationalGetDataTest, GetQuerySyncData1, TestSize.Level1)
543 {
544 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
545 ASSERT_NE(g_delegate, nullptr);
546 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
547
548 /**
549 * @tc.steps: step1. Put 100 records.
550 * @tc.expected: Succeed, return OK.
551 */
552 const size_t RECORD_COUNT = 100; // 100 records.
553 for (size_t i = 0; i < RECORD_COUNT; ++i) {
554 EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
555 }
556
557 /**
558 * @tc.steps: step2. Get data limit 80, offset 30.
559 * @tc.expected: Get 70 records.
560 */
561 auto store = GetRelationalStore();
562 ASSERT_NE(store, nullptr);
563 ContinueToken token = nullptr;
564 const unsigned int LIMIT = 80; // limit as 80.
565 const unsigned int OFFSET = 30; // offset as 30.
566 const unsigned int EXPECT_COUNT = RECORD_COUNT - OFFSET; // expect 70 records.
567 QueryObject query(Query::Select(g_tableName).Limit(LIMIT, OFFSET));
568 std::vector<SingleVerKvEntry *> entries;
569
570 int errCode = store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries);
571 EXPECT_EQ(entries.size(), EXPECT_COUNT);
572 EXPECT_EQ(errCode, E_OK);
573 EXPECT_EQ(token, nullptr);
574 SingleVerKvEntry::Release(entries);
575 RefObject::DecObjRef(g_store);
576 }
577
578 /**
579 * @tc.name: GetQuerySyncData2
580 * @tc.desc: GetSyncData interface.
581 * @tc.type: FUNC
582 * @tc.require: AR000GK58H
583 * @tc.author: lidongwei
584 */
585 HWTEST_F(DistributedDBRelationalGetDataTest, GetQuerySyncData2, TestSize.Level1)
586 {
587 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
588 ASSERT_NE(g_delegate, nullptr);
589 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
590
591 /**
592 * @tc.steps: step1. Put 100 records.
593 * @tc.expected: Succeed, return OK.
594 */
595 const size_t RECORD_COUNT = 100; // 100 records.
596 for (size_t i = 0; i < RECORD_COUNT; ++i) {
597 EXPECT_EQ(AddOrUpdateRecord(i, i), E_OK);
598 }
599
600 /**
601 * @tc.steps: step2. Get record whose key is not equal to 10 and value is not equal to 20, order by key desc.
602 * @tc.expected: Succeed, Get 98 records.
603 */
604 auto store = GetRelationalStore();
605 ASSERT_NE(store, nullptr);
606 ContinueToken token = nullptr;
607
608 Query query = Query::Select(g_tableName).NotEqualTo("key", 10).And().NotEqualTo("value", 20).OrderBy("key", false);
609 QueryObject queryObj(query);
610 queryObj.SetSchema(store->GetSchemaInfo());
611
612 std::vector<SingleVerKvEntry *> entries;
613 EXPECT_EQ(store->GetSyncData(queryObj, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
614 EXPECT_EQ(token, nullptr);
615 size_t expectCount = 98; // expect 98 records.
616 EXPECT_EQ(entries.size(), expectCount);
617 for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
618 auto nextOne = std::next(iter, 1);
619 if (nextOne != entries.end()) {
620 EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
621 }
622 }
623 SingleVerKvEntry::Release(entries);
624
625 /**
626 * @tc.steps: step3. Get record whose key is equal to 10 or value is equal to 20, order by key asc.
627 * @tc.expected: Succeed, Get 98 records.
628 */
629 query = Query::Select(g_tableName).EqualTo("key", 10).Or().EqualTo("value", 20).OrderBy("key", true);
630 queryObj = QueryObject(query);
631 queryObj.SetSchema(store->GetSchemaInfo());
632
633 EXPECT_EQ(store->GetSyncData(queryObj, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
634 EXPECT_EQ(token, nullptr);
635 expectCount = 2; // expect 2 records.
636 EXPECT_EQ(entries.size(), expectCount);
637 for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
638 auto nextOne = std::next(iter, 1);
639 if (nextOne != entries.end()) {
640 EXPECT_LT((*iter)->GetTimestamp(), (*nextOne)->GetTimestamp());
641 }
642 }
643 SingleVerKvEntry::Release(entries);
644 RefObject::DecObjRef(g_store);
645 }
646
647 /**
648 * @tc.name: GetIncorrectTypeData1
649 * @tc.desc: GetSyncData and PutSyncDataWithQuery interface.
650 * @tc.type: FUNC
651 * @tc.require: AR000GK58H
652 * @tc.author: lidongwei
653 */
654 HWTEST_F(DistributedDBRelationalGetDataTest, GetIncorrectTypeData1, TestSize.Level1)
655 {
656 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
657 ASSERT_NE(g_delegate, nullptr);
658 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
659
660 /**
661 * @tc.steps: step1. Create 2 index for table "data".
662 * @tc.expected: Succeed, return OK.
663 */
664 sqlite3 *db = nullptr;
665 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
666
667 ExecSqlAndAssertOK(db, {"CREATE INDEX index1 ON " + g_tableName + "(value);",
668 "CREATE UNIQUE INDEX index2 ON " + g_tableName + "(value,key);"});
669
670 /**
671 * @tc.steps: step2. Create distributed table "dataPlus".
672 * @tc.expected: Succeed, return OK.
673 */
674 const string tableName = g_tableName + "Plus";
675 string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
676 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
677 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
678
679 /**
680 * @tc.steps: step3. Put 5 records with different type into "dataPlus" table.
681 * @tc.expected: Succeed, return OK.
682 */
683 const size_t RECORD_COUNT = 5; // 5 sqls
684 ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
685 "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
686 "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
687 "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
688 "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');"});
689
690 /**
691 * @tc.steps: step4. Get all data from "dataPlus" table.
692 * @tc.expected: Succeed and the count is right.
693 */
694 auto store = GetRelationalStore();
695 ASSERT_NE(store, nullptr);
696 ContinueToken token = nullptr;
697 QueryObject query(Query::Select(tableName));
698 std::vector<SingleVerKvEntry *> entries;
699 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
700 EXPECT_EQ(entries.size(), RECORD_COUNT);
701
702 /**
703 * @tc.steps: step5. Put data into "data" table from deviceA.
704 * @tc.expected: Succeed, return OK.
705 */
706 QueryObject queryPlus(Query::Select(g_tableName));
707 const DeviceID deviceID = "deviceA";
708 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
709 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
710 ASSERT_EQ(E_OK, SQLiteUtils::CloneIndexes(db, g_tableName,
711 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
712
713 SetRemoteSchema(store, deviceID);
714 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
715 SingleVerKvEntry::Release(entries);
716
717 /**
718 * @tc.steps: step6. Check data.
719 * @tc.expected: All data in the two tables are same.
720 */
721 ExpectCount(db, "SELECT count(*) FROM " + tableName + " as a, " + DBConstant::RELATIONAL_PREFIX + g_tableName +
722 "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b "
723 "WHERE a.key=b.key AND (a.value=b.value OR (a.value is NULL AND b.value is NULL));", RECORD_COUNT);
724
725 /**
726 * @tc.steps: step7. Check index.
727 * @tc.expected: 2 index for deviceA's data table exists.
728 */
729 ExpectCount(db,
730 "SELECT count(*) FROM sqlite_master WHERE type='index' AND tbl_name='" + DBConstant::RELATIONAL_PREFIX +
731 g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "'", 2U); // 2 index
732 sqlite3_close(db);
733 RefObject::DecObjRef(g_store);
734 }
735
736 /**
737 * @tc.name: UpdateData1
738 * @tc.desc: UpdateData succeed when the table has primary key.
739 * @tc.type: FUNC
740 * @tc.require: AR000GK58H
741 * @tc.author: lidongwei
742 */
743 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateData1, TestSize.Level1)
744 {
745 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
746 ASSERT_NE(g_delegate, nullptr);
747 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
748
749 /**
750 * @tc.steps: step1. Create distributed table "dataPlus".
751 * @tc.expected: Succeed, return OK.
752 */
753 const string tableName = g_tableName + "Plus";
754 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
755 sqlite3 *db = nullptr;
756 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
757 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
758 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
759
760 /**
761 * @tc.steps: step2. Put 5 records with different type into "dataPlus" table.
762 * @tc.expected: Succeed, return OK.
763 */
764 vector<string> sqls = {
765 "INSERT INTO " + tableName + " VALUES(NULL, 1);",
766 "INSERT INTO " + tableName + " VALUES(NULL, 0.01);",
767 "INSERT INTO " + tableName + " VALUES(NULL, NULL);",
768 "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');",
769 "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');",
770 };
771 const size_t RECORD_COUNT = sqls.size();
772 for (const auto &item : sqls) {
773 ASSERT_EQ(sqlite3_exec(db, item.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
774 }
775
776 /**
777 * @tc.steps: step3. Get all data from "dataPlus" table.
778 * @tc.expected: Succeed and the count is right.
779 */
780 auto store = GetRelationalStore();
781 ASSERT_NE(store, nullptr);
782 ContinueToken token = nullptr;
783 QueryObject query(Query::Select(tableName));
784 std::vector<SingleVerKvEntry *> entries;
785 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
786 EXPECT_EQ(entries.size(), RECORD_COUNT);
787
788 /**
789 * @tc.steps: step4. Put data into "data" table from deviceA for 10 times.
790 * @tc.expected: Succeed, return OK.
791 */
792 query = QueryObject(Query::Select(g_tableName));
793 const DeviceID deviceID = "deviceA";
794 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
795 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
796
797 SetRemoteSchema(store, deviceID);
798 for (uint32_t i = 0; i < 10; ++i) { // 10 for test.
799 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
800 }
801 SingleVerKvEntry::Release(entries);
802
803 /**
804 * @tc.steps: step5. Check data.
805 * @tc.expected: There is 5 data in table.
806 */
807 sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
808 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
809 size_t count = 0;
810 EXPECT_EQ(GetCount(db, sql, count), E_OK);
811 EXPECT_EQ(count, RECORD_COUNT);
812
813 sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;";
814 count = 0;
815 EXPECT_EQ(GetCount(db, sql, count), E_OK);
816 EXPECT_EQ(count, RECORD_COUNT);
817
818 sqlite3_close(db);
819 RefObject::DecObjRef(g_store);
820 }
821
822 /**
823 * @tc.name: UpdateDataWithMulDevData1
824 * @tc.desc: UpdateData succeed when there is multiple devices data exists.
825 * @tc.type: FUNC
826 * @tc.require: AR000GK58H
827 * @tc.author: lidongwei
828 */
829 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateDataWithMulDevData1, TestSize.Level1)
830 {
831 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
832 ASSERT_NE(g_delegate, nullptr);
833 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
834 /**
835 * @tc.steps: step1. Create distributed table "dataPlus".
836 * @tc.expected: Succeed, return OK.
837 */
838 const string tableName = g_tableName + "Plus";
839 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
840 sqlite3 *db = nullptr;
841 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
842 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
843 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
844 /**
845 * @tc.steps: step2. Put k1v1 into "dataPlus" table.
846 * @tc.expected: Succeed, return OK.
847 */
848 sql = "INSERT INTO " + tableName + " VALUES(1, 1);"; // k1v1
849 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
850 /**
851 * @tc.steps: step3. Get k1v1 from "dataPlus" table.
852 * @tc.expected: Succeed and the count is right.
853 */
854 auto store = GetRelationalStore();
855 ASSERT_NE(store, nullptr);
856 ContinueToken token = nullptr;
857 QueryObject query(Query::Select(tableName));
858 std::vector<SingleVerKvEntry *> entries;
859 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
860 /**
861 * @tc.steps: step4. Put k1v1 into "data" table from deviceA.
862 * @tc.expected: Succeed, return OK.
863 */
864 query = QueryObject(Query::Select(g_tableName));
865 const DeviceID deviceID = "deviceA";
866 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
867 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
868
869 SetRemoteSchema(store, deviceID);
870 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
871 SingleVerKvEntry::Release(entries);
872 /**
873 * @tc.steps: step4. Put k1v1 into "data" table.
874 * @tc.expected: Succeed, return OK.
875 */
876 EXPECT_EQ(AddOrUpdateRecord(1, 1), E_OK); // k1v1
877 /**
878 * @tc.steps: step5. Change k1v1 to k1v2
879 * @tc.expected: Succeed, return OK.
880 */
881 sql = "UPDATE " + g_tableName + " SET value=2 WHERE key=1;"; // k1v1
882 EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); // change k1v1 to k1v2
883
884 sqlite3_close(db);
885 RefObject::DecObjRef(g_store);
886 }
887
888 /**
889 * @tc.name: MissQuery1
890 * @tc.desc: Check REMOTE_DEVICE_DATA_MISS_QUERY flag succeed.
891 * @tc.type: FUNC
892 * @tc.require: AR000GK58H
893 * @tc.author: lidongwei
894 */
895 HWTEST_F(DistributedDBRelationalGetDataTest, MissQuery1, TestSize.Level1)
896 {
897 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
898 ASSERT_NE(g_delegate, nullptr);
899 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
900 /**
901 * @tc.steps: step1. Create distributed table "dataPlus".
902 * @tc.expected: Succeed, return OK.
903 */
904 const string tableName = g_tableName + "Plus";
905 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
906 sqlite3 *db = nullptr;
907 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
908 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
909 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
910
911 /**
912 * @tc.steps: step2. Put 5 records with different type into "dataPlus" table.
913 * @tc.expected: Succeed, return OK.
914 */
915 ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);",
916 "INSERT INTO " + tableName + " VALUES(NULL, 2);", "INSERT INTO " + tableName + " VALUES(NULL, 3);",
917 "INSERT INTO " + tableName + " VALUES(NULL, 4);", "INSERT INTO " + tableName + " VALUES(NULL, 5);"});
918
919 /**
920 * @tc.steps: step3. Get all data from "dataPlus" table.
921 * @tc.expected: Succeed and the count is right.
922 */
923 auto store = GetRelationalStore();
924 ASSERT_NE(store, nullptr);
925 ContinueToken token = nullptr;
926 SyncTimeRange timeRange;
927 QueryObject query(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4));
928 std::vector<SingleVerKvEntry *> entries;
929 EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK);
930 timeRange.lastQueryTime = (*(entries.rbegin()))->GetTimestamp();
931 EXPECT_EQ(entries.size(), 3U); // 3 for test
932
933 /**
934 * @tc.steps: step4. Put data into "data" table from deviceA for 10 times.
935 * @tc.expected: Succeed, return OK.
936 */
937 query = QueryObject(Query::Select(g_tableName));
938 const DeviceID deviceID = "deviceA";
939 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
940 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
941
942 SetRemoteSchema(store, deviceID);
943 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
944 SingleVerKvEntry::Release(entries);
945
946 /**
947 * @tc.steps: step5. Check data.
948 * @tc.expected: There is 3 data in table.
949 */
950 std::string getDataSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
951 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
952 ExpectCount(db, getDataSql, 3); // 2,3,4
953
954 std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;";
955 ExpectCount(db, getLogSql, 3); // 2,3,4
956
957 /**
958 * @tc.steps: step6. Update data. k2v2 to k2v102, k3v3 to k3v103, k4v4 to k4v104.
959 * @tc.expected: Update succeed.
960 */
961 ExecSqlAndAssertOK(db, {"INSERT OR REPLACE INTO " + tableName + " VALUES(2, 102);",
962 "UPDATE " + tableName + " SET value=103 WHERE value=3;",
963 "DELETE FROM " + tableName + " WHERE key=4;",
964 "INSERT INTO " + tableName + " VALUES(4, 104);"});
965
966 /**
967 * @tc.steps: step7. Get all data from "dataPlus" table.
968 * @tc.expected: Succeed and the count is right.
969 */
970 query = QueryObject(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4));
971 EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK);
972 EXPECT_EQ(entries.size(), 3U); // 3 miss query data.
973
974 /**
975 * @tc.steps: step8. Put data into "data" table from deviceA for 10 times.
976 * @tc.expected: Succeed, return OK.
977 */
978 SetRemoteSchema(store, deviceID);
979 query = QueryObject(Query::Select(g_tableName));
980 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
981 SingleVerKvEntry::Release(entries);
982
983 /**
984 * @tc.steps: step9. Check data.
985 * @tc.expected: There is 0 data in table.
986 */
987 ExpectCount(db, getDataSql, 0U); // 0 data exists
988 ExpectCount(db, getLogSql, 0U); // 0 data exists
989
990 sqlite3_close(db);
991 RefObject::DecObjRef(g_store);
992 }
993
994 /**
995 * @tc.name: CompatibleData1
996 * @tc.desc: Check compatibility.
997 * @tc.type: FUNC
998 * @tc.require: AR000GK58H
999 * @tc.author: lidongwei
1000 */
1001 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData1, TestSize.Level1)
1002 {
1003 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1004 ASSERT_NE(g_delegate, nullptr);
1005 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1006 /**
1007 * @tc.steps: step1. Create distributed table "dataPlus".
1008 * @tc.expected: Succeed, return OK.
1009 */
1010 const string tableName = g_tableName + "Plus";
1011 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1012 extra_field TEXT NOT NULL DEFAULT 'default_value');";
1013 sqlite3 *db = nullptr;
1014 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1015 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1016 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1017 /**
1018 * @tc.steps: step2. Put 1 record into data and dataPlus table.
1019 * @tc.expected: Succeed, return OK.
1020 */
1021 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1022 sql = "INSERT INTO " + tableName + " VALUES(2, 102, 'f3');"; // k2v102
1023 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1024 /**
1025 * @tc.steps: step3. Get all data from "data" table.
1026 * @tc.expected: Succeed and the count is right.
1027 */
1028 auto store = GetRelationalStore();
1029 ASSERT_NE(store, nullptr);
1030 ContinueToken token = nullptr;
1031 QueryObject query(Query::Select(g_tableName));
1032 std::vector<SingleVerKvEntry *> entries;
1033 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1034 EXPECT_EQ(entries.size(), 1UL);
1035 /**
1036 * @tc.steps: step4. Put data into "data_plus" table from deviceA.
1037 * @tc.expected: Succeed, return OK.
1038 */
1039 QueryObject queryPlus(Query::Select(tableName));
1040 const DeviceID deviceID = "deviceA";
1041 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName),
1042 DBCommon::GetDistributedTableName(deviceID, tableName)));
1043
1044 SetRemoteSchema(store, deviceID);
1045 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1046 SingleVerKvEntry::Release(entries);
1047 /**
1048 * @tc.steps: step4. Get all data from "dataPlus" table.
1049 * @tc.expected: Succeed and the count is right.
1050 */
1051 EXPECT_EQ(store->GetSyncData(queryPlus, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1052 EXPECT_EQ(entries.size(), 1UL);
1053 /**
1054 * @tc.steps: step5. Put data into "data" table from deviceA.
1055 * @tc.expected: Succeed, return OK.
1056 */
1057 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
1058 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
1059 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK);
1060 SingleVerKvEntry::Release(entries);
1061 /**
1062 * @tc.steps: step6. Check data.
1063 * @tc.expected: All data in the two tables are same.
1064 */
1065 sql = "SELECT count(*) FROM " + g_tableName + " as a," + DBConstant::RELATIONAL_PREFIX + tableName + "_" +
1066 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " +
1067 "WHERE a.key=b.key AND a.value=b.value;";
1068 size_t count = 0;
1069 EXPECT_EQ(GetCount(db, sql, count), E_OK);
1070 EXPECT_EQ(count, 1UL);
1071 sql = "SELECT count(*) FROM " + tableName + " as a," + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
1072 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " +
1073 "WHERE a.key=b.key AND a.value=b.value;";
1074 count = 0;
1075 EXPECT_EQ(GetCount(db, sql, count), E_OK);
1076 EXPECT_EQ(count, 1UL);
1077 sqlite3_close(db);
1078 RefObject::DecObjRef(g_store);
1079 }
1080
1081 /**
1082 * @tc.name: GetDataSortByTime1
1083 * @tc.desc: All query get data sort by time asc.
1084 * @tc.type: FUNC
1085 * @tc.require: AR000GK58H
1086 * @tc.author: lidongwei
1087 */
1088 HWTEST_F(DistributedDBRelationalGetDataTest, GetDataSortByTime1, TestSize.Level1)
1089 {
1090 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1091 ASSERT_NE(g_delegate, nullptr);
1092 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1093 /**
1094 * @tc.steps: step2. Add 3 record into data. k1v105, k2v104, k3v103, timestamp desc.
1095 * @tc.expected: Succeed, return OK.
1096 */
1097 sqlite3 *db = nullptr;
1098 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1099 std::string sql = "INSERT INTO " + g_tableName + " VALUES(1, 101);"; // k1v101
1100 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1101 sql = "INSERT INTO " + g_tableName + " VALUES(2, 102);"; // k2v102
1102 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1103 sql = "INSERT INTO " + g_tableName + " VALUES(3, 103);"; // k3v103
1104 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1105 sql = "UPDATE " + g_tableName + " SET value=104 WHERE key=2;"; // k2v104
1106 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1107 sql = "UPDATE " + g_tableName + " SET value=105 WHERE key=1;"; // k1v105
1108 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1109 /**
1110 * @tc.steps: step3. Get all data from "data" table by all query.
1111 * @tc.expected: Succeed and the count is right.
1112 */
1113 auto store = GetRelationalStore();
1114 ASSERT_NE(store, nullptr);
1115 ContinueToken token = nullptr;
1116 QueryObject query(Query::Select(g_tableName));
1117 std::vector<SingleVerKvEntry *> entries;
1118 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1119 ExpectMissQueryCnt(entries, 3UL); // 3 data
1120 SingleVerKvEntry::Release(entries);
1121
1122 query = QueryObject(Query::Select(g_tableName).EqualTo("key", 1).Or().EqualTo("key", 3));
1123 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1124 ExpectMissQueryCnt(entries, 2UL); // 2 data
1125 SingleVerKvEntry::Release(entries);
1126
1127 query = QueryObject(Query::Select(g_tableName).OrderBy("key", false));
1128 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1129 ExpectMissQueryCnt(entries, 3UL); // 3 data
1130 SingleVerKvEntry::Release(entries);
1131
1132 query = QueryObject(Query::Select(g_tableName).OrderBy("value", false));
1133 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1134 ExpectMissQueryCnt(entries, 3UL); // 3 data
1135 SingleVerKvEntry::Release(entries);
1136
1137 query = QueryObject(Query::Select(g_tableName).Limit(2));
1138 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1139 ExpectMissQueryCnt(entries, 2UL); // 2 data
1140 SingleVerKvEntry::Release(entries);
1141
1142 sqlite3_close(db);
1143 RefObject::DecObjRef(g_store);
1144 }
1145
1146 /**
1147 * @tc.name: SameFieldWithLogTable1
1148 * @tc.desc: Get query data OK when the table has same field with log table.
1149 * @tc.type: FUNC
1150 * @tc.require: AR000GK58H
1151 * @tc.author: lidongwei
1152 */
1153 HWTEST_F(DistributedDBRelationalGetDataTest, SameFieldWithLogTable1, TestSize.Level1)
1154 {
1155 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1156 ASSERT_NE(g_delegate, nullptr);
1157 /**
1158 * @tc.steps: step1. Create distributed table "dataPlus".
1159 * @tc.expected: Succeed, return OK.
1160 */
1161 const string tableName = g_tableName + "Plus";
1162 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, flag INTEGER NOT NULL, \
1163 device TEXT NOT NULL DEFAULT 'default_value');";
1164 sqlite3 *db = nullptr;
1165 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1166 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1167 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1168 /**
1169 * @tc.steps: step2. Put 1 record into dataPlus table.
1170 * @tc.expected: Succeed, return OK.
1171 */
1172 sql = "INSERT INTO " + tableName + " VALUES(1, 101, 'f3');"; // k1v101
1173 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1174 /**
1175 * @tc.steps: step3. Get all data from dataPlus table.
1176 * @tc.expected: Succeed and the count is right.
1177 */
1178 auto store = GetRelationalStore();
1179 ASSERT_NE(store, nullptr);
1180 ContinueToken token = nullptr;
1181 QueryObject query(Query::Select(tableName).EqualTo("flag", 101).OrderBy("device", false));
1182 std::vector<SingleVerKvEntry *> entries;
1183 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1184 EXPECT_EQ(entries.size(), 1UL);
1185 SingleVerKvEntry::Release(entries);
1186 sqlite3_close(db);
1187 RefObject::DecObjRef(g_store);
1188 }
1189
1190 /**
1191 * @tc.name: CompatibleData2
1192 * @tc.desc: Check compatibility.
1193 * @tc.type: FUNC
1194 * @tc.require: AR000GK58H
1195 * @tc.author: lidongwei
1196 */
1197 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData2, TestSize.Level1)
1198 {
1199 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1200 ASSERT_NE(g_delegate, nullptr);
1201 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1202
1203 sqlite3 *db = nullptr;
1204 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1205
1206 auto store = GetRelationalStore();
1207 ASSERT_NE(store, nullptr);
1208
1209 /**
1210 * @tc.steps: step1. Create distributed table from deviceA.
1211 * @tc.expected: Succeed, return OK.
1212 */
1213 const DeviceID deviceID = "deviceA";
1214 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName),
1215 DBCommon::GetDistributedTableName(deviceID, g_tableName)));
1216
1217 /**
1218 * @tc.steps: step2. Alter "data" table and create distributed table again.
1219 * @tc.expected: Succeed.
1220 */
1221 std::string sql = "ALTER TABLE " + g_tableName + " ADD COLUMN integer_type INTEGER DEFAULT 123 not null;"
1222 "ALTER TABLE " + g_tableName + " ADD COLUMN text_type TEXT DEFAULT 'high_version' not null;"
1223 "ALTER TABLE " + g_tableName + " ADD COLUMN real_type REAL DEFAULT 123.123456 not null;"
1224 "ALTER TABLE " + g_tableName + " ADD COLUMN blob_type BLOB DEFAULT 123 not null;";
1225 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1226 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1227
1228 /**
1229 * @tc.steps: step3. Check deviceA's distributed table.
1230 * @tc.expected: The create sql is correct.
1231 */
1232 std::string expectSql = "CREATE TABLE 'naturalbase_rdb_aux_data_"
1233 "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f' ('key' 'integer' NOT NULL,'value' 'integer',"
1234 " 'integer_type' 'integer' NOT NULL DEFAULT 123, 'text_type' 'text' NOT NULL DEFAULT 'high_version', "
1235 "'real_type' 'real' NOT NULL DEFAULT 123.123456, 'blob_type' 'blob' NOT NULL DEFAULT 123, PRIMARY KEY ('key'))";
1236 sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" +
1237 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';";
1238 EXPECT_EQ(GetOneText(db, sql), expectSql);
1239
1240 sqlite3_close(db);
1241 RefObject::DecObjRef(g_store);
1242 }
1243
1244 /**
1245 * @tc.name: PutSyncDataConflictDataTest001
1246 * @tc.desc: Check put with conflict sync data.
1247 * @tc.type: FUNC
1248 * @tc.require: AR000GK58H
1249 * @tc.author: lianhuix
1250 */
1251 HWTEST_F(DistributedDBRelationalGetDataTest, PutSyncDataConflictDataTest001, TestSize.Level1)
1252 {
1253 const DeviceID deviceID_A = "deviceA";
1254 const DeviceID deviceID_B = "deviceB";
1255 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath);
1256 RelationalTestUtils::CreateDeviceTable(db, g_tableName, deviceID_B);
1257
1258 DBStatus status = g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate);
1259 EXPECT_EQ(status, DBStatus::OK);
1260 ASSERT_NE(g_delegate, nullptr);
1261 EXPECT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1262
1263 auto store = const_cast<RelationalSyncAbleStorage *>(GetRelationalStore());
1264 ASSERT_NE(store, nullptr);
1265
1266 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1001,'VAL_1');");
1267 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1002,'VAL_2');");
1268 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1003,'VAL_3');");
1269
1270 DataSizeSpecInfo sizeInfo {MTU_SIZE, 50};
1271 ContinueToken token = nullptr;
1272 QueryObject query(Query::Select(g_tableName));
1273 std::vector<SingleVerKvEntry *> entries;
1274 int errCode = store->GetSyncData(query, {}, sizeInfo, token, entries);
1275 EXPECT_EQ(errCode, E_OK);
1276
1277 SetRemoteSchema(store, deviceID_B);
1278 errCode = store->PutSyncDataWithQuery(query, entries, deviceID_B);
1279 EXPECT_EQ(errCode, E_OK);
1280 GenericSingleVerKvEntry::Release(entries);
1281
1282 QueryObject query2(Query::Select(g_tableName).EqualTo("key", 1001));
1283 std::vector<SingleVerKvEntry *> entries2;
1284 store->GetSyncData(query2, {}, sizeInfo, token, entries2);
1285
1286 errCode = store->PutSyncDataWithQuery(query, entries2, deviceID_B);
1287 EXPECT_EQ(errCode, E_OK);
1288 GenericSingleVerKvEntry::Release(entries2);
1289
1290 RefObject::DecObjRef(g_store);
1291
1292 std::string deviceTable = DBCommon::GetDistributedTableName(deviceID_B, g_tableName);
1293 EXPECT_EQ(RelationalTestUtils::CheckTableRecords(db, deviceTable), 3);
1294 sqlite3_close_v2(db);
1295 }
1296
1297 /**
1298 * @tc.name: SaveNonexistDevdata1
1299 * @tc.desc: Save non-exist device data and check errCode.
1300 * @tc.type: FUNC
1301 * @tc.require: AR000GK58H
1302 * @tc.author: lidongwei
1303 */
1304 HWTEST_F(DistributedDBRelationalGetDataTest, SaveNonexistDevdata1, TestSize.Level1)
1305 {
1306 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1307 ASSERT_NE(g_delegate, nullptr);
1308 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1309 /**
1310 * @tc.steps: step1. Create distributed table "dataPlus".
1311 * @tc.expected: Succeed, return OK.
1312 */
1313 const string tableName = g_tableName + "Plus";
1314 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1315 extra_field TEXT NOT NULL DEFAULT 'default_value');";
1316 sqlite3 *db = nullptr;
1317 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1318 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
1319 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1320 /**
1321 * @tc.steps: step2. Put 1 record into data table.
1322 * @tc.expected: Succeed, return OK.
1323 */
1324 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1325
1326 /**
1327 * @tc.steps: step3. Get all data from "data" table.
1328 * @tc.expected: Succeed and the count is right.
1329 */
1330 auto store = GetRelationalStore();
1331 ASSERT_NE(store, nullptr);
1332 ContinueToken token = nullptr;
1333 QueryObject query(Query::Select(g_tableName));
1334 std::vector<SingleVerKvEntry *> entries;
1335 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK);
1336 EXPECT_EQ(entries.size(), 1UL);
1337
1338 /**
1339 * @tc.steps: step4. Put data into "data_plus" table from deviceA and deviceA does not exist.
1340 * @tc.expected: Succeed, return OK.
1341 */
1342 query = QueryObject(Query::Select(tableName));
1343 const DeviceID deviceID = "deviceA";
1344 SetRemoteSchema(store, deviceID);
1345 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID),
1346 -1); // -1 means error
1347 SingleVerKvEntry::Release(entries);
1348
1349 sqlite3_close(db);
1350 RefObject::DecObjRef(g_store);
1351 }
1352
1353 /**
1354 * @tc.name: GetMaxTimestamp1
1355 * @tc.desc: Get max timestamp.
1356 * @tc.type: FUNC
1357 * @tc.require: AR000GK58H
1358 * @tc.author: lidongwei
1359 */
1360 HWTEST_F(DistributedDBRelationalGetDataTest, GetMaxTimestamp1, TestSize.Level1)
1361 {
1362 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1363 ASSERT_NE(g_delegate, nullptr);
1364 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1365 /**
1366 * @tc.steps: step1. Create distributed table "dataPlus".
1367 * @tc.expected: Succeed, return OK.
1368 */
1369 sqlite3 *db = nullptr;
1370 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1371 const string tableName = g_tableName + "Plus";
1372 ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \
1373 extra_field TEXT NOT NULL DEFAULT 'default_value');");
1374 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1375
1376 /**
1377 * @tc.steps: step2. Get max timestamp when no data exists.
1378 * @tc.expected: Succeed and the time is 0;
1379 */
1380 auto store = GetRelationalStore();
1381 ASSERT_NE(store, nullptr);
1382
1383 Timestamp time1 = 0;
1384 store->GetMaxTimestamp(time1);
1385 EXPECT_EQ(time1, 0ull);
1386
1387 /**
1388 * @tc.steps: step3. Put 1 record into data table and get max timestamp.
1389 * @tc.expected: Succeed and the time is updated.
1390 */
1391 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK);
1392 Timestamp time2 = 0;
1393 store->GetMaxTimestamp(time2);
1394 EXPECT_GT(time2, time1);
1395
1396 /**
1397 * @tc.steps: step4. Put 1 record into data table and get max timestamp.
1398 * @tc.expected: Succeed and the time is updated.
1399 */
1400 ASSERT_EQ(AddOrUpdateRecord(2, 102), E_OK);
1401 Timestamp time3 = 0;
1402 store->GetMaxTimestamp(time3);
1403 EXPECT_GT(time3, time2);
1404
1405 /**
1406 * @tc.steps: step5. Put 1 record into data table and get the max timestamp of data table.
1407 * @tc.expected: Succeed and the time is equals to max timestamp in DB.
1408 */
1409 Timestamp time4 = 0;
1410 store->GetMaxTimestamp(g_tableName, time4);
1411 EXPECT_EQ(time4, time3);
1412
1413 /**
1414 * @tc.steps: step6. Put 1 record into data table and get the max timestamp of dataPlus table.
1415 * @tc.expected: Succeed and the time is 0.
1416 */
1417 Timestamp time5 = 0;
1418 store->GetMaxTimestamp(tableName, time5);
1419 EXPECT_EQ(time5, 0ull);
1420
1421 sqlite3_close(db);
1422 RefObject::DecObjRef(g_store);
1423 }
1424
1425 /**
1426 * @tc.name: NoPkData1
1427 * @tc.desc: For no pk data.
1428 * @tc.type: FUNC
1429 * @tc.require: AR000GK58H
1430 * @tc.author: lidongwei
1431 */
1432 HWTEST_F(DistributedDBRelationalGetDataTest, NoPkData1, TestSize.Level1)
1433 {
1434 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1435 ASSERT_NE(g_delegate, nullptr);
1436
1437 sqlite3 *db = nullptr;
1438 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1439 ExecSqlAndAssertOK(db, "DROP TABLE IF EXISTS " + g_tableName + "; \
1440 CREATE TABLE " + g_tableName + "(key INTEGER NOT NULL, value INTEGER);");
1441 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1442
1443 /**
1444 * @tc.steps: step1. Create distributed table "dataPlus".
1445 * @tc.expected: Succeed, return OK.
1446 */
1447 const string tableName = g_tableName + "Plus";
1448 ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER NOT NULL, value INTEGER);");
1449 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK);
1450
1451 /**
1452 * @tc.steps: step2. Put 2 data into "data" table.
1453 * @tc.expected: Succeed.
1454 */
1455 ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK);
1456 ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK);
1457
1458 /**
1459 * @tc.steps: step3. Get data from "data" table.
1460 * @tc.expected: Succeed.
1461 */
1462 auto store = GetRelationalStore();
1463 ASSERT_NE(store, nullptr);
1464
1465 ContinueToken token = nullptr;
1466 QueryObject query(Query::Select(g_tableName));
1467 std::vector<SingleVerKvEntry *> entries;
1468 EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK);
1469 EXPECT_EQ(entries.size(), 2U); // expect 2 data.
1470
1471 /**
1472 * @tc.steps: step4. Put data into "data" table from deviceA.
1473 * @tc.expected: Succeed, return OK.
1474 */
1475 QueryObject queryPlus(Query::Select(tableName));
1476 const DeviceID deviceID = "deviceA";
1477 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName),
1478 DBCommon::GetDistributedTableName(deviceID, tableName)));
1479 SetRemoteSchema(store, deviceID);
1480 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1481 SingleVerKvEntry::Release(entries);
1482
1483 /**
1484 * @tc.steps: step5. Changet data in "data" table.
1485 * @tc.expected: Succeed.
1486 */
1487 ExecSqlAndAssertOK(db, {"UPDATE " + g_tableName + " SET value=101 WHERE key=1;",
1488 "DELETE FROM " + g_tableName + " WHERE key=2;",
1489 "INSERT INTO " + g_tableName + " VALUES(2, 102);"});
1490
1491 /**
1492 * @tc.steps: step6. Get data from "data" table.
1493 * @tc.expected: Succeed.
1494 */
1495 EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK);
1496 EXPECT_EQ(entries.size(), 2U); // expect 2 data.
1497
1498 /**
1499 * @tc.steps: step7. Put data into "data" table from deviceA.
1500 * @tc.expected: Succeed, return OK.
1501 */
1502 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK);
1503 SingleVerKvEntry::Release(entries);
1504
1505 /**
1506 * @tc.steps: step8. Check data.
1507 * @tc.expected: There is 2 data.
1508 */
1509 std::string sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_" +
1510 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";";
1511 size_t count = 0;
1512 EXPECT_EQ(GetCount(db, sql, count), E_OK);
1513 EXPECT_EQ(count, 2U); // expect 2 data.
1514
1515 sqlite3_close(db);
1516 RefObject::DecObjRef(g_store);
1517 }
1518
1519 /**
1520 * @tc.name: GetAfterDropTable1
1521 * @tc.desc: Get data after drop table.
1522 * @tc.type: FUNC
1523 * @tc.require: AR000H2QPN
1524 * @tc.author: lidongwei
1525 */
1526 HWTEST_F(DistributedDBRelationalGetDataTest, GetAfterDropTable1, TestSize.Level1)
1527 {
1528 /**
1529 * @tc.steps: step1. Create distributed table.
1530 * @tc.expected: Succeed, return OK.
1531 */
1532 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1533 ASSERT_NE(g_delegate, nullptr);
1534 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1535
1536 /**
1537 * @tc.steps: step2. Insert several data.
1538 * @tc.expected: Succeed, return OK.
1539 */
1540 ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK);
1541 ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK);
1542 ASSERT_EQ(AddOrUpdateRecord(3, 3), E_OK);
1543
1544 /**
1545 * @tc.steps: step3. Check data in distributed log table.
1546 * @tc.expected: The data in log table is in expect. All the flag in log table is 1.
1547 */
1548 sqlite3 *db = nullptr;
1549 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1550
1551 std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log "
1552 "WHERE flag&0x01<>0;";
1553 ExpectCount(db, getLogSql, 0u); // 0 means no deleted data.
1554
1555 /**
1556 * @tc.steps: step4. Drop the table in another connection.
1557 * @tc.expected: Succeed.
1558 */
__anon74d830320202null1559 std::thread t1([] {
1560 sqlite3 *db = nullptr;
1561 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
1562 ExecSqlAndAssertOK(db, "DROP TABLE " + g_tableName);
1563 sqlite3_close(db);
1564 });
1565 t1.join();
1566 std::this_thread::sleep_for(std::chrono::seconds(1));
1567 /**
1568 * @tc.steps: step5. Check data in distributed log table.
1569 * @tc.expected: The data in log table is in expect. All the flag in log table is 3.
1570 */
1571 ExpectCount(db, getLogSql, 3u); // 3 means all deleted data.
1572 sqlite3_close(db);
1573 }
1574
1575 /**
1576 * @tc.name: SetSchema1
1577 * @tc.desc: Test invalid parameters of query_object.cpp
1578 * @tc.type: FUNC
1579 * @tc.require:
1580 * @tc.author: bty
1581 */
1582 HWTEST_F(DistributedDBRelationalGetDataTest, SetSchema1, TestSize.Level1)
1583 {
1584 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1585 ASSERT_NE(g_delegate, nullptr);
1586 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1587 auto store = GetRelationalStore();
1588 ASSERT_NE(store, nullptr);
1589 Query query = Query::Select().OrderBy("errDevice", false);
1590 QueryObject queryObj1(query);
1591 int errorNo = E_OK;
1592 errorNo = queryObj1.SetSchema(store->GetSchemaInfo());
1593 EXPECT_EQ(errorNo, -E_INVALID_ARGS);
1594 EXPECT_FALSE(queryObj1.IsQueryForRelationalDB());
1595 errorNo = queryObj1.Init();
1596 EXPECT_EQ(errorNo, -E_NOT_SUPPORT);
1597 QueryObject queryObj2(query);
1598 queryObj2.SetTableName(g_tableName);
1599 errorNo = queryObj2.SetSchema(store->GetSchemaInfo());
1600 EXPECT_EQ(errorNo, E_OK);
1601 errorNo = queryObj2.Init();
1602 EXPECT_EQ(errorNo, -E_INVALID_QUERY_FIELD);
1603 RefObject::DecObjRef(g_store);
1604 }
1605
1606 /**
1607 * @tc.name: SetNextBeginTime001
1608 * @tc.desc: Test invalid parameters of query_object.cpp
1609 * @tc.type: FUNC
1610 * @tc.require:
1611 * @tc.author: bty
1612 */
1613 HWTEST_F(DistributedDBRelationalGetDataTest, SetNextBeginTime001, TestSize.Level1)
1614 {
1615 ASSERT_NO_FATAL_FAILURE(SetNextBeginTime001());
1616 }
1617
1618 /**
1619 * @tc.name: CloseStore001
1620 * @tc.desc: Test Relational Store Close Action.
1621 * @tc.type: FUNC
1622 * @tc.require: AR000H2QPN
1623 * @tc.author: zhangqiquan
1624 */
1625 HWTEST_F(DistributedDBRelationalGetDataTest, CloseStore001, TestSize.Level1)
1626 {
1627 /**
1628 * @tc.steps: step1. new store and get connection now ref count is 2.
1629 * @tc.expected: Succeed.
1630 */
1631 auto store = new (std::nothrow) SQLiteRelationalStore();
1632 ASSERT_NE(store, nullptr);
1633 RelationalDBProperties properties;
1634 InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1635 EXPECT_EQ(store->Open(properties), E_OK);
1636 int errCode = E_OK;
1637 auto connection = store->GetDBConnection(errCode);
1638 EXPECT_EQ(errCode, E_OK);
1639 ASSERT_NE(connection, nullptr);
__anon74d830320302(const std::string &, const std::string &) 1640 errCode = store->RegisterLifeCycleCallback([](const std::string &, const std::string &) {
1641 });
1642 EXPECT_EQ(errCode, E_OK);
1643 errCode = store->RegisterLifeCycleCallback(nullptr);
1644 EXPECT_EQ(errCode, E_OK);
1645 auto syncInterface = store->GetStorageEngine();
1646 ASSERT_NE(syncInterface, nullptr);
1647 RefObject::IncObjRef(syncInterface);
1648 /**
1649 * @tc.steps: step2. release store.
1650 * @tc.expected: Succeed.
1651 */
1652 store->ReleaseDBConnection(1, connection); // 1 is connection id
1653 RefObject::DecObjRef(store);
1654 store = nullptr;
1655 std::this_thread::sleep_for(std::chrono::seconds(1));
1656
1657 /**
1658 * @tc.steps: step3. try trigger heart beat after store release.
1659 * @tc.expected: No crash.
1660 */
1661 Timestamp maxTimestamp = 0u;
1662 syncInterface->GetMaxTimestamp(maxTimestamp);
1663 RefObject::DecObjRef(syncInterface);
1664 }
1665
1666 /**
1667 * @tc.name: ReleaseContinueTokenTest001
1668 * @tc.desc: Test relaese continue token
1669 * @tc.type: FUNC
1670 * @tc.require:
1671 * @tc.author: zhangshijie
1672 */
1673 HWTEST_F(DistributedDBRelationalGetDataTest, ReleaseContinueTokenTest001, TestSize.Level1)
1674 {
1675 /**
1676 * @tc.steps: step1. open store prepare data.
1677 * @tc.expected: Succeed.
1678 */
1679 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
1680 ASSERT_NE(g_delegate, nullptr);
1681 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
1682
1683 for (int i = 1; i <= 5; ++i) { // 5 is loop count
1684 EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK); // 1024*1024 equals 1M.
1685 }
1686
1687 EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
1688 g_delegate = nullptr;
1689
1690 /**
1691 * @tc.steps: step2. call GetSyncData.
1692 * @tc.expected: return -E_UNFINISHED.
1693 */
1694 auto store = new(std::nothrow) SQLiteRelationalStore();
1695 ASSERT_NE(store, nullptr);
1696 RelationalDBProperties properties;
1697 InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1698 EXPECT_EQ(store->Open(properties), E_OK);
1699 int errCode = E_OK;
1700 auto connection = store->GetDBConnection(errCode);
1701 EXPECT_EQ(errCode, E_OK);
1702 ASSERT_NE(connection, nullptr);
__anon74d830320402(const std::string &, const std::string &) 1703 errCode = store->RegisterLifeCycleCallback([](const std::string &, const std::string &) {
1704 });
1705 EXPECT_EQ(errCode, E_OK);
1706 errCode = store->RegisterLifeCycleCallback(nullptr);
1707 EXPECT_EQ(errCode, E_OK);
1708 auto syncInterface = store->GetStorageEngine();
1709 ASSERT_NE(syncInterface, nullptr);
1710
1711 ContinueToken token = nullptr;
1712 QueryObject query(Query::Select(g_tableName));
1713 std::vector<SingleVerKvEntry *> entries;
1714
1715 DataSizeSpecInfo sizeInfo;
1716 sizeInfo.blockSize = 1 * 1024 * 1024; // permit 1M.
1717 EXPECT_EQ(syncInterface->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries), -E_UNFINISHED);
1718 EXPECT_NE(token, nullptr);
1719 syncInterface->ReleaseContinueToken(token);
1720 RefObject::IncObjRef(syncInterface);
1721
1722 SingleVerKvEntry::Release(entries);
1723 store->ReleaseDBConnection(1, connection); // 1 is connection id
1724 RefObject::DecObjRef(store);
1725 store = nullptr;
1726 std::this_thread::sleep_for(std::chrono::seconds(1));
1727 RefObject::DecObjRef(syncInterface);
1728 }
1729
1730 /**
1731 * @tc.name: StopSync001
1732 * @tc.desc: Test Relational Stop Sync Action.
1733 * @tc.type: FUNC
1734 * @tc.require: AR000H2QPN
1735 * @tc.author: zhangqiquan
1736 */
1737 HWTEST_F(DistributedDBRelationalGetDataTest, StopSync001, TestSize.Level1)
1738 {
1739 RelationalDBProperties properties;
1740 InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
1741 properties.SetBoolProp(DBProperties::SYNC_DUAL_TUPLE_MODE, true);
1742 const int loopCount = 1000;
__anon74d830320502() 1743 std::thread userChangeThread([]() {
1744 for (int i = 0; i < loopCount; ++i) {
1745 RuntimeConfig::NotifyUserChanged();
1746 std::this_thread::sleep_for(std::chrono::milliseconds(1));
1747 }
1748 });
1749 std::string hashIdentifier = properties.GetStringProp(RelationalDBProperties::IDENTIFIER_DATA, "");
1750 properties.SetStringProp(DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, hashIdentifier);
1751 OpenDbProperties option;
1752 option.uri = properties.GetStringProp(DBProperties::DATA_DIR, "");
1753 option.createIfNecessary = true;
1754 for (int i = 0; i < loopCount; ++i) {
1755 auto sqliteStorageEngine = std::make_shared<SQLiteSingleRelationalStorageEngine>(properties);
1756 ASSERT_NE(sqliteStorageEngine, nullptr);
1757 StorageEngineAttr poolSize = {1, 1, 0, 16}; // at most 1 write 16 read.
1758 int errCode = sqliteStorageEngine->InitSQLiteStorageEngine(poolSize, option, hashIdentifier);
1759 EXPECT_EQ(errCode, E_OK);
1760 auto storageEngine = new (std::nothrow) RelationalSyncAbleStorage(sqliteStorageEngine);
1761 ASSERT_NE(storageEngine, nullptr);
1762 auto syncAbleEngine = std::make_unique<SyncAbleEngine>(storageEngine);
1763 ASSERT_NE(syncAbleEngine, nullptr);
1764 syncAbleEngine->WakeUpSyncer();
1765 syncAbleEngine->Close();
1766 RefObject::KillAndDecObjRef(storageEngine);
1767 }
1768 userChangeThread.join();
1769 }
1770
1771 /**
1772 * @tc.name: EraseDeviceWaterMark001
1773 * @tc.desc: Test Relational erase water mark.
1774 * @tc.type: FUNC
1775 * @tc.require: AR000H2QPN
1776 * @tc.author: zhangqiquan
1777 */
1778 HWTEST_F(DistributedDBRelationalGetDataTest, EraseDeviceWaterMark001, TestSize.Level1)
1779 {
1780 auto syncAbleEngine = std::make_unique<SyncAbleEngine>(nullptr);
1781 ASSERT_NE(syncAbleEngine, nullptr);
1782 EXPECT_EQ(syncAbleEngine->EraseDeviceWaterMark("", true), -E_INVALID_ARGS);
1783 }
1784 }
1785 #endif
1786