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 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 " + DBConstant::RELATIONAL_PREFIX + g_tableName + 530 "_log WHERE flag&0x01=0x01;", 2U); // 2 deleted log 531 ExpectCount(db, "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + 532 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceA)) + ";", 3U); // 3 records in A 533 ExpectCount(db, "SELECT count(*) FROM " + 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, " + DBConstant::RELATIONAL_PREFIX + g_tableName + 727 "_" + 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='" + DBConstant::RELATIONAL_PREFIX + 736 g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "'", 2U); // 2 index 737 sqlite3_close(db); 738 RefObject::DecObjRef(g_store); 739 } 740 741 /** 742 * @tc.name: UpdateData1 743 * @tc.desc: UpdateData succeed when the table has primary key. 744 * @tc.type: FUNC 745 * @tc.require: AR000GK58H 746 * @tc.author: lidongwei 747 */ 748 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateData1, TestSize.Level1) 749 { 750 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 751 ASSERT_NE(g_delegate, nullptr); 752 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 753 754 /** 755 * @tc.steps: step1. Create distributed table "dataPlus". 756 * @tc.expected: Succeed, return OK. 757 */ 758 const string tableName = g_tableName + "Plus"; 759 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);"; 760 sqlite3 *db = nullptr; 761 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 762 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 763 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); 764 765 /** 766 * @tc.steps: step2. Put 5 records with different type into "dataPlus" table. 767 * @tc.expected: Succeed, return OK. 768 */ 769 vector<string> sqls = { 770 "INSERT INTO " + tableName + " VALUES(NULL, 1);", 771 "INSERT INTO " + tableName + " VALUES(NULL, 0.01);", 772 "INSERT INTO " + tableName + " VALUES(NULL, NULL);", 773 "INSERT INTO " + tableName + " VALUES(NULL, 'This is a text.');", 774 "INSERT INTO " + tableName + " VALUES(NULL, x'0123456789');", 775 }; 776 const size_t RECORD_COUNT = sqls.size(); 777 for (const auto &item : sqls) { 778 ASSERT_EQ(sqlite3_exec(db, item.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 779 } 780 781 /** 782 * @tc.steps: step3. Get all data from "dataPlus" table. 783 * @tc.expected: Succeed and the count is right. 784 */ 785 auto store = GetRelationalStore(); 786 ASSERT_NE(store, nullptr); 787 ContinueToken token = nullptr; 788 QueryObject query(Query::Select(tableName)); 789 std::vector<SingleVerKvEntry *> entries; 790 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 791 EXPECT_EQ(entries.size(), RECORD_COUNT); 792 793 /** 794 * @tc.steps: step4. Put data into "data" table from deviceA for 10 times. 795 * @tc.expected: Succeed, return OK. 796 */ 797 query = QueryObject(Query::Select(g_tableName)); 798 const DeviceID deviceID = "deviceA"; 799 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName), 800 DBCommon::GetDistributedTableName(deviceID, g_tableName))); 801 802 SetRemoteSchema(store, deviceID); 803 for (uint32_t i = 0; i < 10; ++i) { // 10 for test. 804 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK); 805 } 806 SingleVerKvEntry::Release(entries); 807 808 /** 809 * @tc.steps: step5. Check data. 810 * @tc.expected: There is 5 data in table. 811 */ 812 sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + 813 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";"; 814 size_t count = 0; 815 EXPECT_EQ(GetCount(db, sql, count), E_OK); 816 EXPECT_EQ(count, RECORD_COUNT); 817 818 sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;"; 819 count = 0; 820 EXPECT_EQ(GetCount(db, sql, count), E_OK); 821 EXPECT_EQ(count, RECORD_COUNT); 822 823 sqlite3_close(db); 824 RefObject::DecObjRef(g_store); 825 } 826 827 /** 828 * @tc.name: UpdateDataWithMulDevData1 829 * @tc.desc: UpdateData succeed when there is multiple devices data exists. 830 * @tc.type: FUNC 831 * @tc.require: AR000GK58H 832 * @tc.author: lidongwei 833 */ 834 HWTEST_F(DistributedDBRelationalGetDataTest, UpdateDataWithMulDevData1, TestSize.Level1) 835 { 836 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 837 ASSERT_NE(g_delegate, nullptr); 838 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 839 /** 840 * @tc.steps: step1. Create distributed table "dataPlus". 841 * @tc.expected: Succeed, return OK. 842 */ 843 const string tableName = g_tableName + "Plus"; 844 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);"; 845 sqlite3 *db = nullptr; 846 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 847 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 848 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); 849 /** 850 * @tc.steps: step2. Put k1v1 into "dataPlus" table. 851 * @tc.expected: Succeed, return OK. 852 */ 853 sql = "INSERT INTO " + tableName + " VALUES(1, 1);"; // k1v1 854 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 855 /** 856 * @tc.steps: step3. Get k1v1 from "dataPlus" table. 857 * @tc.expected: Succeed and the count is right. 858 */ 859 auto store = GetRelationalStore(); 860 ASSERT_NE(store, nullptr); 861 ContinueToken token = nullptr; 862 QueryObject query(Query::Select(tableName)); 863 std::vector<SingleVerKvEntry *> entries; 864 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 865 /** 866 * @tc.steps: step4. Put k1v1 into "data" table from deviceA. 867 * @tc.expected: Succeed, return OK. 868 */ 869 query = QueryObject(Query::Select(g_tableName)); 870 const DeviceID deviceID = "deviceA"; 871 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName), 872 DBCommon::GetDistributedTableName(deviceID, g_tableName))); 873 874 SetRemoteSchema(store, deviceID); 875 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK); 876 SingleVerKvEntry::Release(entries); 877 /** 878 * @tc.steps: step4. Put k1v1 into "data" table. 879 * @tc.expected: Succeed, return OK. 880 */ 881 EXPECT_EQ(AddOrUpdateRecord(1, 1), E_OK); // k1v1 882 /** 883 * @tc.steps: step5. Change k1v1 to k1v2 884 * @tc.expected: Succeed, return OK. 885 */ 886 sql = "UPDATE " + g_tableName + " SET value=2 WHERE key=1;"; // k1v1 887 EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); // change k1v1 to k1v2 888 889 sqlite3_close(db); 890 RefObject::DecObjRef(g_store); 891 } 892 893 /** 894 * @tc.name: MissQuery1 895 * @tc.desc: Check REMOTE_DEVICE_DATA_MISS_QUERY flag succeed. 896 * @tc.type: FUNC 897 * @tc.require: AR000GK58H 898 * @tc.author: lidongwei 899 */ 900 HWTEST_F(DistributedDBRelationalGetDataTest, MissQuery1, TestSize.Level1) 901 { 902 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 903 ASSERT_NE(g_delegate, nullptr); 904 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 905 /** 906 * @tc.steps: step1. Create distributed table "dataPlus". 907 * @tc.expected: Succeed, return OK. 908 */ 909 const string tableName = g_tableName + "Plus"; 910 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);"; 911 sqlite3 *db = nullptr; 912 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 913 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 914 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); 915 916 /** 917 * @tc.steps: step2. Put 5 records with different type into "dataPlus" table. 918 * @tc.expected: Succeed, return OK. 919 */ 920 ExecSqlAndAssertOK(db, {"INSERT INTO " + tableName + " VALUES(NULL, 1);", 921 "INSERT INTO " + tableName + " VALUES(NULL, 2);", "INSERT INTO " + tableName + " VALUES(NULL, 3);", 922 "INSERT INTO " + tableName + " VALUES(NULL, 4);", "INSERT INTO " + tableName + " VALUES(NULL, 5);"}); 923 924 /** 925 * @tc.steps: step3. Get all data from "dataPlus" table. 926 * @tc.expected: Succeed and the count is right. 927 */ 928 auto store = GetRelationalStore(); 929 ASSERT_NE(store, nullptr); 930 ContinueToken token = nullptr; 931 SyncTimeRange timeRange; 932 QueryObject query(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4)); 933 std::vector<SingleVerKvEntry *> entries; 934 EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK); 935 timeRange.lastQueryTime = (*(entries.rbegin()))->GetTimestamp(); 936 EXPECT_EQ(entries.size(), 3U); // 3 for test 937 938 /** 939 * @tc.steps: step4. Put data into "data" table from deviceA for 10 times. 940 * @tc.expected: Succeed, return OK. 941 */ 942 query = QueryObject(Query::Select(g_tableName)); 943 const DeviceID deviceID = "deviceA"; 944 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName), 945 DBCommon::GetDistributedTableName(deviceID, g_tableName))); 946 947 SetRemoteSchema(store, deviceID); 948 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK); 949 SingleVerKvEntry::Release(entries); 950 951 /** 952 * @tc.steps: step5. Check data. 953 * @tc.expected: There is 3 data in table. 954 */ 955 std::string getDataSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + 956 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";"; 957 ExpectCount(db, getDataSql, 3); // 2,3,4 958 959 std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log;"; 960 ExpectCount(db, getLogSql, 3); // 2,3,4 961 962 /** 963 * @tc.steps: step6. Update data. k2v2 to k2v102, k3v3 to k3v103, k4v4 to k4v104. 964 * @tc.expected: Update succeed. 965 */ 966 ExecSqlAndAssertOK(db, {"INSERT OR REPLACE INTO " + tableName + " VALUES(2, 102);", 967 "UPDATE " + tableName + " SET value=103 WHERE value=3;", 968 "DELETE FROM " + tableName + " WHERE key=4;", 969 "INSERT INTO " + tableName + " VALUES(4, 104);"}); 970 971 /** 972 * @tc.steps: step7. Get all data from "dataPlus" table. 973 * @tc.expected: Succeed and the count is right. 974 */ 975 query = QueryObject(Query::Select(tableName).EqualTo("value", 2).Or().EqualTo("value", 3).Or().EqualTo("value", 4)); 976 EXPECT_EQ(store->GetSyncData(query, timeRange, DataSizeSpecInfo {}, token, entries), E_OK); 977 EXPECT_EQ(entries.size(), 3U); // 3 miss query data. 978 979 /** 980 * @tc.steps: step8. Put data into "data" table from deviceA for 10 times. 981 * @tc.expected: Succeed, return OK. 982 */ 983 SetRemoteSchema(store, deviceID); 984 query = QueryObject(Query::Select(g_tableName)); 985 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK); 986 SingleVerKvEntry::Release(entries); 987 988 /** 989 * @tc.steps: step9. Check data. 990 * @tc.expected: There is 0 data in table. 991 */ 992 ExpectCount(db, getDataSql, 0U); // 0 data exists 993 ExpectCount(db, getLogSql, 0U); // 0 data exists 994 995 sqlite3_close(db); 996 RefObject::DecObjRef(g_store); 997 } 998 999 /** 1000 * @tc.name: CompatibleData1 1001 * @tc.desc: Check compatibility. 1002 * @tc.type: FUNC 1003 * @tc.require: AR000GK58H 1004 * @tc.author: lidongwei 1005 */ 1006 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData1, TestSize.Level1) 1007 { 1008 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1009 ASSERT_NE(g_delegate, nullptr); 1010 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1011 /** 1012 * @tc.steps: step1. Create distributed table "dataPlus". 1013 * @tc.expected: Succeed, return OK. 1014 */ 1015 const string tableName = g_tableName + "Plus"; 1016 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \ 1017 extra_field TEXT NOT NULL DEFAULT 'default_value');"; 1018 sqlite3 *db = nullptr; 1019 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1020 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1021 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); 1022 /** 1023 * @tc.steps: step2. Put 1 record into data and dataPlus table. 1024 * @tc.expected: Succeed, return OK. 1025 */ 1026 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK); 1027 sql = "INSERT INTO " + tableName + " VALUES(2, 102, 'f3');"; // k2v102 1028 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1029 /** 1030 * @tc.steps: step3. Get all data from "data" table. 1031 * @tc.expected: Succeed and the count is right. 1032 */ 1033 auto store = GetRelationalStore(); 1034 ASSERT_NE(store, nullptr); 1035 ContinueToken token = nullptr; 1036 QueryObject query(Query::Select(g_tableName)); 1037 std::vector<SingleVerKvEntry *> entries; 1038 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 1039 EXPECT_EQ(entries.size(), 1UL); 1040 /** 1041 * @tc.steps: step4. Put data into "data_plus" table from deviceA. 1042 * @tc.expected: Succeed, return OK. 1043 */ 1044 QueryObject queryPlus(Query::Select(tableName)); 1045 const DeviceID deviceID = "deviceA"; 1046 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName), 1047 DBCommon::GetDistributedTableName(deviceID, tableName))); 1048 1049 SetRemoteSchema(store, deviceID); 1050 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK); 1051 SingleVerKvEntry::Release(entries); 1052 /** 1053 * @tc.steps: step4. Get all data from "dataPlus" table. 1054 * @tc.expected: Succeed and the count is right. 1055 */ 1056 EXPECT_EQ(store->GetSyncData(queryPlus, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 1057 EXPECT_EQ(entries.size(), 1UL); 1058 /** 1059 * @tc.steps: step5. Put data into "data" table from deviceA. 1060 * @tc.expected: Succeed, return OK. 1061 */ 1062 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName), 1063 DBCommon::GetDistributedTableName(deviceID, g_tableName))); 1064 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), E_OK); 1065 SingleVerKvEntry::Release(entries); 1066 /** 1067 * @tc.steps: step6. Check data. 1068 * @tc.expected: All data in the two tables are same. 1069 */ 1070 sql = "SELECT count(*) FROM " + g_tableName + " as a," + DBConstant::RELATIONAL_PREFIX + tableName + "_" + 1071 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " + 1072 "WHERE a.key=b.key AND a.value=b.value;"; 1073 size_t count = 0; 1074 EXPECT_EQ(GetCount(db, sql, count), E_OK); 1075 EXPECT_EQ(count, 1UL); 1076 sql = "SELECT count(*) FROM " + tableName + " as a," + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + 1077 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + " as b " + 1078 "WHERE a.key=b.key AND a.value=b.value;"; 1079 count = 0; 1080 EXPECT_EQ(GetCount(db, sql, count), E_OK); 1081 EXPECT_EQ(count, 1UL); 1082 sqlite3_close(db); 1083 RefObject::DecObjRef(g_store); 1084 } 1085 1086 /** 1087 * @tc.name: GetDataSortByTime1 1088 * @tc.desc: All query get data sort by time asc. 1089 * @tc.type: FUNC 1090 * @tc.require: AR000GK58H 1091 * @tc.author: lidongwei 1092 */ 1093 HWTEST_F(DistributedDBRelationalGetDataTest, GetDataSortByTime1, TestSize.Level1) 1094 { 1095 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1096 ASSERT_NE(g_delegate, nullptr); 1097 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1098 /** 1099 * @tc.steps: step2. Add 3 record into data. k1v105, k2v104, k3v103, timestamp desc. 1100 * @tc.expected: Succeed, return OK. 1101 */ 1102 sqlite3 *db = nullptr; 1103 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1104 std::string sql = "INSERT INTO " + g_tableName + " VALUES(1, 101);"; // k1v101 1105 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1106 sql = "INSERT INTO " + g_tableName + " VALUES(2, 102);"; // k2v102 1107 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1108 sql = "INSERT INTO " + g_tableName + " VALUES(3, 103);"; // k3v103 1109 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1110 sql = "UPDATE " + g_tableName + " SET value=104 WHERE key=2;"; // k2v104 1111 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1112 sql = "UPDATE " + g_tableName + " SET value=105 WHERE key=1;"; // k1v105 1113 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1114 /** 1115 * @tc.steps: step3. Get all data from "data" table by all query. 1116 * @tc.expected: Succeed and the count is right. 1117 */ 1118 auto store = GetRelationalStore(); 1119 ASSERT_NE(store, nullptr); 1120 ContinueToken token = nullptr; 1121 QueryObject query(Query::Select(g_tableName)); 1122 std::vector<SingleVerKvEntry *> entries; 1123 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 1124 ExpectMissQueryCnt(entries, 3UL); // 3 data 1125 SingleVerKvEntry::Release(entries); 1126 1127 query = QueryObject(Query::Select(g_tableName).EqualTo("key", 1).Or().EqualTo("key", 3)); 1128 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 1129 ExpectMissQueryCnt(entries, 2UL); // 2 data 1130 SingleVerKvEntry::Release(entries); 1131 1132 query = QueryObject(Query::Select(g_tableName).OrderBy("key", 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).OrderBy("value", false)); 1138 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 1139 ExpectMissQueryCnt(entries, 3UL); // 3 data 1140 SingleVerKvEntry::Release(entries); 1141 1142 query = QueryObject(Query::Select(g_tableName).Limit(2)); 1143 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 1144 ExpectMissQueryCnt(entries, 2UL); // 2 data 1145 SingleVerKvEntry::Release(entries); 1146 1147 sqlite3_close(db); 1148 RefObject::DecObjRef(g_store); 1149 } 1150 1151 /** 1152 * @tc.name: SameFieldWithLogTable1 1153 * @tc.desc: Get query data OK when the table has same field with log table. 1154 * @tc.type: FUNC 1155 * @tc.require: AR000GK58H 1156 * @tc.author: lidongwei 1157 */ 1158 HWTEST_F(DistributedDBRelationalGetDataTest, SameFieldWithLogTable1, TestSize.Level1) 1159 { 1160 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1161 ASSERT_NE(g_delegate, nullptr); 1162 /** 1163 * @tc.steps: step1. Create distributed table "dataPlus". 1164 * @tc.expected: Succeed, return OK. 1165 */ 1166 const string tableName = g_tableName + "Plus"; 1167 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, flag INTEGER NOT NULL, \ 1168 device TEXT NOT NULL DEFAULT 'default_value');"; 1169 sqlite3 *db = nullptr; 1170 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1171 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1172 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); 1173 /** 1174 * @tc.steps: step2. Put 1 record into dataPlus table. 1175 * @tc.expected: Succeed, return OK. 1176 */ 1177 sql = "INSERT INTO " + tableName + " VALUES(1, 101, 'f3');"; // k1v101 1178 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1179 /** 1180 * @tc.steps: step3. Get all data from dataPlus table. 1181 * @tc.expected: Succeed and the count is right. 1182 */ 1183 auto store = GetRelationalStore(); 1184 ASSERT_NE(store, nullptr); 1185 ContinueToken token = nullptr; 1186 QueryObject query(Query::Select(tableName).EqualTo("flag", 101).OrderBy("device", false)); 1187 std::vector<SingleVerKvEntry *> entries; 1188 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 1189 EXPECT_EQ(entries.size(), 1UL); 1190 SingleVerKvEntry::Release(entries); 1191 sqlite3_close(db); 1192 RefObject::DecObjRef(g_store); 1193 } 1194 1195 /** 1196 * @tc.name: CompatibleData2 1197 * @tc.desc: Check compatibility. 1198 * @tc.type: FUNC 1199 * @tc.require: AR000GK58H 1200 * @tc.author: lidongwei 1201 */ 1202 HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData2, TestSize.Level1) 1203 { 1204 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1205 ASSERT_NE(g_delegate, nullptr); 1206 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1207 1208 sqlite3 *db = nullptr; 1209 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1210 1211 auto store = GetRelationalStore(); 1212 ASSERT_NE(store, nullptr); 1213 1214 /** 1215 * @tc.steps: step1. Create distributed table from deviceA. 1216 * @tc.expected: Succeed, return OK. 1217 */ 1218 const DeviceID deviceID = "deviceA"; 1219 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(g_tableName), 1220 DBCommon::GetDistributedTableName(deviceID, g_tableName))); 1221 1222 /** 1223 * @tc.steps: step2. Alter "data" table and create distributed table again. 1224 * @tc.expected: Succeed. 1225 */ 1226 std::string sql = "ALTER TABLE " + g_tableName + " ADD COLUMN integer_type INTEGER DEFAULT 123 not null;" 1227 "ALTER TABLE " + g_tableName + " ADD COLUMN text_type TEXT DEFAULT 'high_version' not null;" 1228 "ALTER TABLE " + g_tableName + " ADD COLUMN real_type REAL DEFAULT 123.123456 not null;" 1229 "ALTER TABLE " + g_tableName + " ADD COLUMN blob_type BLOB DEFAULT 123 not null;"; 1230 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1231 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1232 1233 /** 1234 * @tc.steps: step3. Check deviceA's distributed table. 1235 * @tc.expected: The create sql is correct. 1236 */ 1237 std::string expectSql = "CREATE TABLE 'naturalbase_rdb_aux_data_" 1238 "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f' ('key' 'integer' NOT NULL,'value' 'integer'," 1239 " 'integer_type' 'integer' NOT NULL DEFAULT 123, 'text_type' 'text' NOT NULL DEFAULT 'high_version', " 1240 "'real_type' 'real' NOT NULL DEFAULT 123.123456, 'blob_type' 'blob' NOT NULL DEFAULT 123, PRIMARY KEY ('key'))"; 1241 sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + 1242 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';"; 1243 EXPECT_EQ(GetOneText(db, sql), expectSql); 1244 1245 sqlite3_close(db); 1246 RefObject::DecObjRef(g_store); 1247 } 1248 1249 /** 1250 * @tc.name: PutSyncDataConflictDataTest001 1251 * @tc.desc: Check put with conflict sync data. 1252 * @tc.type: FUNC 1253 * @tc.require: AR000GK58H 1254 * @tc.author: lianhuix 1255 */ 1256 HWTEST_F(DistributedDBRelationalGetDataTest, PutSyncDataConflictDataTest001, TestSize.Level1) 1257 { 1258 const DeviceID deviceID_A = "deviceA"; 1259 const DeviceID deviceID_B = "deviceB"; 1260 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_storePath); 1261 RelationalTestUtils::CreateDeviceTable(db, g_tableName, deviceID_B); 1262 1263 DBStatus status = g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate); 1264 EXPECT_EQ(status, DBStatus::OK); 1265 ASSERT_NE(g_delegate, nullptr); 1266 EXPECT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1267 1268 auto store = const_cast<RelationalSyncAbleStorage *>(GetRelationalStore()); 1269 ASSERT_NE(store, nullptr); 1270 1271 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1001,'VAL_1');"); 1272 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1002,'VAL_2');"); 1273 RelationalTestUtils::ExecSql(db, "INSERT OR REPLACE INTO " + g_tableName + " (key,value) VALUES (1003,'VAL_3');"); 1274 1275 DataSizeSpecInfo sizeInfo {MTU_SIZE, 50}; 1276 ContinueToken token = nullptr; 1277 QueryObject query(Query::Select(g_tableName)); 1278 std::vector<SingleVerKvEntry *> entries; 1279 int errCode = store->GetSyncData(query, {}, sizeInfo, token, entries); 1280 EXPECT_EQ(errCode, E_OK); 1281 1282 SetRemoteSchema(store, deviceID_B); 1283 errCode = store->PutSyncDataWithQuery(query, entries, deviceID_B); 1284 EXPECT_EQ(errCode, E_OK); 1285 GenericSingleVerKvEntry::Release(entries); 1286 1287 QueryObject query2(Query::Select(g_tableName).EqualTo("key", 1001)); 1288 std::vector<SingleVerKvEntry *> entries2; 1289 store->GetSyncData(query2, {}, sizeInfo, token, entries2); 1290 1291 errCode = store->PutSyncDataWithQuery(query, entries2, deviceID_B); 1292 EXPECT_EQ(errCode, E_OK); 1293 GenericSingleVerKvEntry::Release(entries2); 1294 1295 RefObject::DecObjRef(g_store); 1296 1297 std::string deviceTable = DBCommon::GetDistributedTableName(deviceID_B, g_tableName); 1298 EXPECT_EQ(RelationalTestUtils::CheckTableRecords(db, deviceTable), 3); 1299 sqlite3_close_v2(db); 1300 } 1301 1302 /** 1303 * @tc.name: SaveNonexistDevdata1 1304 * @tc.desc: Save non-exist device data and check errCode. 1305 * @tc.type: FUNC 1306 * @tc.require: AR000GK58H 1307 * @tc.author: lidongwei 1308 */ 1309 HWTEST_F(DistributedDBRelationalGetDataTest, SaveNonexistDevdata1, TestSize.Level1) 1310 { 1311 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1312 ASSERT_NE(g_delegate, nullptr); 1313 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1314 /** 1315 * @tc.steps: step1. Create distributed table "dataPlus". 1316 * @tc.expected: Succeed, return OK. 1317 */ 1318 const string tableName = g_tableName + "Plus"; 1319 std::string sql = "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \ 1320 extra_field TEXT NOT NULL DEFAULT 'default_value');"; 1321 sqlite3 *db = nullptr; 1322 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1323 ASSERT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK); 1324 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); 1325 /** 1326 * @tc.steps: step2. Put 1 record into data table. 1327 * @tc.expected: Succeed, return OK. 1328 */ 1329 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK); 1330 1331 /** 1332 * @tc.steps: step3. Get all data from "data" table. 1333 * @tc.expected: Succeed and the count is right. 1334 */ 1335 auto store = GetRelationalStore(); 1336 ASSERT_NE(store, nullptr); 1337 ContinueToken token = nullptr; 1338 QueryObject query(Query::Select(g_tableName)); 1339 std::vector<SingleVerKvEntry *> entries; 1340 EXPECT_EQ(store->GetSyncData(query, SyncTimeRange {}, DataSizeSpecInfo {}, token, entries), E_OK); 1341 EXPECT_EQ(entries.size(), 1UL); 1342 1343 /** 1344 * @tc.steps: step4. Put data into "data_plus" table from deviceA and deviceA does not exist. 1345 * @tc.expected: Succeed, return OK. 1346 */ 1347 query = QueryObject(Query::Select(tableName)); 1348 const DeviceID deviceID = "deviceA"; 1349 SetRemoteSchema(store, deviceID); 1350 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(query, entries, deviceID), 1351 -1); // -1 means error 1352 SingleVerKvEntry::Release(entries); 1353 1354 sqlite3_close(db); 1355 RefObject::DecObjRef(g_store); 1356 } 1357 1358 /** 1359 * @tc.name: GetMaxTimestamp1 1360 * @tc.desc: Get max timestamp. 1361 * @tc.type: FUNC 1362 * @tc.require: AR000GK58H 1363 * @tc.author: lidongwei 1364 */ 1365 HWTEST_F(DistributedDBRelationalGetDataTest, GetMaxTimestamp1, TestSize.Level1) 1366 { 1367 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1368 ASSERT_NE(g_delegate, nullptr); 1369 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1370 /** 1371 * @tc.steps: step1. Create distributed table "dataPlus". 1372 * @tc.expected: Succeed, return OK. 1373 */ 1374 sqlite3 *db = nullptr; 1375 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1376 const string tableName = g_tableName + "Plus"; 1377 ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER, value INTEGER NOT NULL, \ 1378 extra_field TEXT NOT NULL DEFAULT 'default_value');"); 1379 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); 1380 1381 /** 1382 * @tc.steps: step2. Get max timestamp when no data exists. 1383 * @tc.expected: Succeed and the time is 0; 1384 */ 1385 auto store = GetRelationalStore(); 1386 ASSERT_NE(store, nullptr); 1387 1388 Timestamp time1 = 0; 1389 store->GetMaxTimestamp(time1); 1390 EXPECT_EQ(time1, 0uLL); 1391 1392 /** 1393 * @tc.steps: step3. Put 1 record into data table and get max timestamp. 1394 * @tc.expected: Succeed and the time is updated. 1395 */ 1396 ASSERT_EQ(AddOrUpdateRecord(1, 101), E_OK); 1397 Timestamp time2 = 0; 1398 store->GetMaxTimestamp(time2); 1399 EXPECT_GT(time2, time1); 1400 1401 /** 1402 * @tc.steps: step4. Put 1 record into data table and get max timestamp. 1403 * @tc.expected: Succeed and the time is updated. 1404 */ 1405 ASSERT_EQ(AddOrUpdateRecord(2, 102), E_OK); 1406 Timestamp time3 = 0; 1407 store->GetMaxTimestamp(time3); 1408 EXPECT_GT(time3, time2); 1409 1410 /** 1411 * @tc.steps: step5. Put 1 record into data table and get the max timestamp of data table. 1412 * @tc.expected: Succeed and the time is equals to max timestamp in DB. 1413 */ 1414 Timestamp time4 = 0; 1415 store->GetMaxTimestamp(g_tableName, time4); 1416 EXPECT_EQ(time4, time3); 1417 1418 /** 1419 * @tc.steps: step6. Put 1 record into data table and get the max timestamp of dataPlus table. 1420 * @tc.expected: Succeed and the time is 0. 1421 */ 1422 Timestamp time5 = 0; 1423 store->GetMaxTimestamp(tableName, time5); 1424 EXPECT_EQ(time5, 0uLL); 1425 1426 sqlite3_close(db); 1427 RefObject::DecObjRef(g_store); 1428 } 1429 1430 /** 1431 * @tc.name: NoPkData1 1432 * @tc.desc: For no pk data. 1433 * @tc.type: FUNC 1434 * @tc.require: AR000GK58H 1435 * @tc.author: lidongwei 1436 */ 1437 HWTEST_F(DistributedDBRelationalGetDataTest, NoPkData1, TestSize.Level1) 1438 { 1439 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1440 ASSERT_NE(g_delegate, nullptr); 1441 1442 sqlite3 *db = nullptr; 1443 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1444 ExecSqlAndAssertOK(db, "DROP TABLE IF EXISTS " + g_tableName + "; \ 1445 CREATE TABLE " + g_tableName + "(key INTEGER NOT NULL, value INTEGER);"); 1446 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1447 1448 /** 1449 * @tc.steps: step1. Create distributed table "dataPlus". 1450 * @tc.expected: Succeed, return OK. 1451 */ 1452 const string tableName = g_tableName + "Plus"; 1453 ExecSqlAndAssertOK(db, "CREATE TABLE " + tableName + "(key INTEGER NOT NULL, value INTEGER);"); 1454 ASSERT_EQ(g_delegate->CreateDistributedTable(tableName), DBStatus::OK); 1455 1456 /** 1457 * @tc.steps: step2. Put 2 data into "data" table. 1458 * @tc.expected: Succeed. 1459 */ 1460 ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK); 1461 ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK); 1462 1463 /** 1464 * @tc.steps: step3. Get data from "data" table. 1465 * @tc.expected: Succeed. 1466 */ 1467 auto store = GetRelationalStore(); 1468 ASSERT_NE(store, nullptr); 1469 1470 ContinueToken token = nullptr; 1471 QueryObject query(Query::Select(g_tableName)); 1472 std::vector<SingleVerKvEntry *> entries; 1473 EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK); 1474 EXPECT_EQ(entries.size(), 2U); // expect 2 data. 1475 1476 /** 1477 * @tc.steps: step4. Put data into "data" table from deviceA. 1478 * @tc.expected: Succeed, return OK. 1479 */ 1480 QueryObject queryPlus(Query::Select(tableName)); 1481 const DeviceID deviceID = "deviceA"; 1482 ASSERT_EQ(E_OK, SQLiteUtils::CreateSameStuTable(db, store->GetSchemaInfo().GetTable(tableName), 1483 DBCommon::GetDistributedTableName(deviceID, tableName))); 1484 SetRemoteSchema(store, deviceID); 1485 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK); 1486 SingleVerKvEntry::Release(entries); 1487 1488 /** 1489 * @tc.steps: step5. Changet data in "data" table. 1490 * @tc.expected: Succeed. 1491 */ 1492 ExecSqlAndAssertOK(db, {"UPDATE " + g_tableName + " SET value=101 WHERE key=1;", 1493 "DELETE FROM " + g_tableName + " WHERE key=2;", 1494 "INSERT INTO " + g_tableName + " VALUES(2, 102);"}); 1495 1496 /** 1497 * @tc.steps: step6. Get data from "data" table. 1498 * @tc.expected: Succeed. 1499 */ 1500 EXPECT_EQ(store->GetSyncData(query, {}, DataSizeSpecInfo {}, token, entries), E_OK); 1501 EXPECT_EQ(entries.size(), 2U); // expect 2 data. 1502 1503 /** 1504 * @tc.steps: step7. Put data into "data" table from deviceA. 1505 * @tc.expected: Succeed, return OK. 1506 */ 1507 EXPECT_EQ(const_cast<RelationalSyncAbleStorage *>(store)->PutSyncDataWithQuery(queryPlus, entries, deviceID), E_OK); 1508 SingleVerKvEntry::Release(entries); 1509 1510 /** 1511 * @tc.steps: step8. Check data. 1512 * @tc.expected: There is 2 data. 1513 */ 1514 std::string sql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + tableName + "_" + 1515 DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + ";"; 1516 size_t count = 0; 1517 EXPECT_EQ(GetCount(db, sql, count), E_OK); 1518 EXPECT_EQ(count, 2U); // expect 2 data. 1519 1520 sqlite3_close(db); 1521 RefObject::DecObjRef(g_store); 1522 } 1523 1524 /** 1525 * @tc.name: GetAfterDropTable1 1526 * @tc.desc: Get data after drop table. 1527 * @tc.type: FUNC 1528 * @tc.require: AR000H2QPN 1529 * @tc.author: lidongwei 1530 */ 1531 HWTEST_F(DistributedDBRelationalGetDataTest, GetAfterDropTable1, TestSize.Level1) 1532 { 1533 /** 1534 * @tc.steps: step1. Create distributed table. 1535 * @tc.expected: Succeed, return OK. 1536 */ 1537 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1538 ASSERT_NE(g_delegate, nullptr); 1539 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1540 1541 /** 1542 * @tc.steps: step2. Insert several data. 1543 * @tc.expected: Succeed, return OK. 1544 */ 1545 ASSERT_EQ(AddOrUpdateRecord(1, 1), E_OK); 1546 ASSERT_EQ(AddOrUpdateRecord(2, 2), E_OK); 1547 ASSERT_EQ(AddOrUpdateRecord(3, 3), E_OK); 1548 1549 /** 1550 * @tc.steps: step3. Check data in distributed log table. 1551 * @tc.expected: The data in log table is in expect. All the flag in log table is 1. 1552 */ 1553 sqlite3 *db = nullptr; 1554 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1555 1556 std::string getLogSql = "SELECT count(*) FROM " + DBConstant::RELATIONAL_PREFIX + g_tableName + "_log " 1557 "WHERE flag&0x01<>0;"; 1558 ExpectCount(db, getLogSql, 0u); // 0 means no deleted data. 1559 1560 /** 1561 * @tc.steps: step4. Drop the table in another connection. 1562 * @tc.expected: Succeed. 1563 */ __anona733078b0202null1564 std::thread t1([] { 1565 sqlite3 *db = nullptr; 1566 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK); 1567 ExecSqlAndAssertOK(db, "DROP TABLE " + g_tableName); 1568 sqlite3_close(db); 1569 }); 1570 t1.join(); 1571 std::this_thread::sleep_for(std::chrono::seconds(1)); 1572 /** 1573 * @tc.steps: step5. Check data in distributed log table. 1574 * @tc.expected: The data in log table is in expect. All the flag in log table is 3. 1575 */ 1576 ExpectCount(db, getLogSql, 3u); // 3 means all deleted data. 1577 sqlite3_close(db); 1578 } 1579 1580 /** 1581 * @tc.name: SetSchema1 1582 * @tc.desc: Test invalid parameters of query_object.cpp 1583 * @tc.type: FUNC 1584 * @tc.require: 1585 * @tc.author: bty 1586 */ 1587 HWTEST_F(DistributedDBRelationalGetDataTest, SetSchema1, TestSize.Level1) 1588 { 1589 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1590 ASSERT_NE(g_delegate, nullptr); 1591 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1592 auto store = GetRelationalStore(); 1593 ASSERT_NE(store, nullptr); 1594 Query query = Query::Select().OrderBy("errDevice", false); 1595 QueryObject queryObj1(query); 1596 int errorNo = E_OK; 1597 errorNo = queryObj1.SetSchema(store->GetSchemaInfo()); 1598 EXPECT_EQ(errorNo, -E_INVALID_ARGS); 1599 EXPECT_FALSE(queryObj1.IsQueryForRelationalDB()); 1600 errorNo = queryObj1.Init(); 1601 EXPECT_EQ(errorNo, -E_NOT_SUPPORT); 1602 QueryObject queryObj2(query); 1603 queryObj2.SetTableName(g_tableName); 1604 errorNo = queryObj2.SetSchema(store->GetSchemaInfo()); 1605 EXPECT_EQ(errorNo, E_OK); 1606 errorNo = queryObj2.Init(); 1607 EXPECT_EQ(errorNo, -E_INVALID_QUERY_FIELD); 1608 RefObject::DecObjRef(g_store); 1609 } 1610 1611 /** 1612 * @tc.name: SetNextBeginTime001 1613 * @tc.desc: Test invalid parameters of query_object.cpp 1614 * @tc.type: FUNC 1615 * @tc.require: 1616 * @tc.author: bty 1617 */ 1618 HWTEST_F(DistributedDBRelationalGetDataTest, SetNextBeginTime001, TestSize.Level1) 1619 { 1620 ASSERT_NO_FATAL_FAILURE(SetNextBeginTime001()); 1621 } 1622 1623 /** 1624 * @tc.name: CloseStore001 1625 * @tc.desc: Test Relational Store Close Action. 1626 * @tc.type: FUNC 1627 * @tc.require: AR000H2QPN 1628 * @tc.author: zhangqiquan 1629 */ 1630 HWTEST_F(DistributedDBRelationalGetDataTest, CloseStore001, TestSize.Level1) 1631 { 1632 /** 1633 * @tc.steps: step1. new store and get connection now ref count is 2. 1634 * @tc.expected: Succeed. 1635 */ 1636 auto store = new (std::nothrow) SQLiteRelationalStore(); 1637 ASSERT_NE(store, nullptr); 1638 RelationalDBProperties properties; 1639 InitStoreProp(g_storePath, APP_ID, USER_ID, properties); 1640 EXPECT_EQ(store->Open(properties), E_OK); 1641 int errCode = E_OK; 1642 auto connection = store->GetDBConnection(errCode); 1643 EXPECT_EQ(errCode, E_OK); 1644 ASSERT_NE(connection, nullptr); __anona733078b0302(const std::string &, const std::string &) 1645 errCode = store->RegisterLifeCycleCallback([](const std::string &, const std::string &) { 1646 }); 1647 EXPECT_EQ(errCode, E_OK); 1648 errCode = store->RegisterLifeCycleCallback(nullptr); 1649 EXPECT_EQ(errCode, E_OK); 1650 auto syncInterface = store->GetStorageEngine(); 1651 ASSERT_NE(syncInterface, nullptr); 1652 RefObject::IncObjRef(syncInterface); 1653 /** 1654 * @tc.steps: step2. release store. 1655 * @tc.expected: Succeed. 1656 */ 1657 store->ReleaseDBConnection(1, connection); // 1 is connection id 1658 RefObject::DecObjRef(store); 1659 store = nullptr; 1660 std::this_thread::sleep_for(std::chrono::seconds(1)); 1661 1662 /** 1663 * @tc.steps: step3. try trigger heart beat after store release. 1664 * @tc.expected: No crash. 1665 */ 1666 Timestamp maxTimestamp = 0u; 1667 syncInterface->GetMaxTimestamp(maxTimestamp); 1668 RefObject::DecObjRef(syncInterface); 1669 } 1670 1671 /** 1672 * @tc.name: ReleaseContinueTokenTest001 1673 * @tc.desc: Test relaese continue token 1674 * @tc.type: FUNC 1675 * @tc.require: 1676 * @tc.author: zhangshijie 1677 */ 1678 HWTEST_F(DistributedDBRelationalGetDataTest, ReleaseContinueTokenTest001, TestSize.Level1) 1679 { 1680 /** 1681 * @tc.steps: step1. open store prepare data. 1682 * @tc.expected: Succeed. 1683 */ 1684 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK); 1685 ASSERT_NE(g_delegate, nullptr); 1686 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK); 1687 1688 for (int i = 1; i <= 5; ++i) { // 5 is loop count 1689 EXPECT_EQ(PutBatchData(1, i * 1024 * 1024), E_OK); // 1024*1024 equals 1M. 1690 } 1691 1692 EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK); 1693 g_delegate = nullptr; 1694 1695 /** 1696 * @tc.steps: step2. call GetSyncData. 1697 * @tc.expected: return -E_UNFINISHED. 1698 */ 1699 auto store = new(std::nothrow) SQLiteRelationalStore(); 1700 ASSERT_NE(store, nullptr); 1701 RelationalDBProperties properties; 1702 InitStoreProp(g_storePath, APP_ID, USER_ID, properties); 1703 EXPECT_EQ(store->Open(properties), E_OK); 1704 int errCode = E_OK; 1705 auto connection = store->GetDBConnection(errCode); 1706 EXPECT_EQ(errCode, E_OK); 1707 ASSERT_NE(connection, nullptr); __anona733078b0402(const std::string &, const std::string &) 1708 errCode = store->RegisterLifeCycleCallback([](const std::string &, const std::string &) { 1709 }); 1710 EXPECT_EQ(errCode, E_OK); 1711 errCode = store->RegisterLifeCycleCallback(nullptr); 1712 EXPECT_EQ(errCode, E_OK); 1713 auto syncInterface = store->GetStorageEngine(); 1714 ASSERT_NE(syncInterface, nullptr); 1715 1716 ContinueToken token = nullptr; 1717 QueryObject query(Query::Select(g_tableName)); 1718 std::vector<SingleVerKvEntry *> entries; 1719 1720 DataSizeSpecInfo sizeInfo; 1721 sizeInfo.blockSize = 1 * 1024 * 1024; // permit 1M. 1722 EXPECT_EQ(syncInterface->GetSyncData(query, SyncTimeRange {}, sizeInfo, token, entries), -E_UNFINISHED); 1723 EXPECT_NE(token, nullptr); 1724 syncInterface->ReleaseContinueToken(token); 1725 RefObject::IncObjRef(syncInterface); 1726 1727 SingleVerKvEntry::Release(entries); 1728 store->ReleaseDBConnection(1, connection); // 1 is connection id 1729 RefObject::DecObjRef(store); 1730 store = nullptr; 1731 std::this_thread::sleep_for(std::chrono::seconds(1)); 1732 RefObject::DecObjRef(syncInterface); 1733 } 1734 1735 /** 1736 * @tc.name: StopSync001 1737 * @tc.desc: Test Relational Stop Sync Action. 1738 * @tc.type: FUNC 1739 * @tc.require: AR000H2QPN 1740 * @tc.author: zhangqiquan 1741 */ 1742 HWTEST_F(DistributedDBRelationalGetDataTest, StopSync001, TestSize.Level1) 1743 { 1744 RelationalDBProperties properties; 1745 InitStoreProp(g_storePath, APP_ID, USER_ID, properties); 1746 properties.SetBoolProp(DBProperties::SYNC_DUAL_TUPLE_MODE, true); 1747 const int loopCount = 1000; __anona733078b0502() 1748 std::thread userChangeThread([]() { 1749 for (int i = 0; i < loopCount; ++i) { 1750 RuntimeConfig::NotifyUserChanged(); 1751 std::this_thread::sleep_for(std::chrono::milliseconds(1)); 1752 } 1753 }); 1754 std::string hashIdentifier = properties.GetStringProp(RelationalDBProperties::IDENTIFIER_DATA, ""); 1755 properties.SetStringProp(DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, hashIdentifier); 1756 OpenDbProperties option; 1757 option.uri = properties.GetStringProp(DBProperties::DATA_DIR, ""); 1758 option.createIfNecessary = true; 1759 for (int i = 0; i < loopCount; ++i) { 1760 auto sqliteStorageEngine = std::make_shared<SQLiteSingleRelationalStorageEngine>(properties); 1761 ASSERT_NE(sqliteStorageEngine, nullptr); 1762 StorageEngineAttr poolSize = {1, 1, 0, 16}; // at most 1 write 16 read. 1763 int errCode = sqliteStorageEngine->InitSQLiteStorageEngine(poolSize, option, hashIdentifier); 1764 EXPECT_EQ(errCode, E_OK); 1765 auto storageEngine = new (std::nothrow) RelationalSyncAbleStorage(sqliteStorageEngine); 1766 ASSERT_NE(storageEngine, nullptr); 1767 auto syncAbleEngine = std::make_unique<SyncAbleEngine>(storageEngine); 1768 ASSERT_NE(syncAbleEngine, nullptr); 1769 syncAbleEngine->WakeUpSyncer(); 1770 syncAbleEngine->Close(); 1771 RefObject::KillAndDecObjRef(storageEngine); 1772 } 1773 userChangeThread.join(); 1774 } 1775 1776 /** 1777 * @tc.name: EraseDeviceWaterMark001 1778 * @tc.desc: Test Relational erase water mark. 1779 * @tc.type: FUNC 1780 * @tc.require: AR000H2QPN 1781 * @tc.author: zhangqiquan 1782 */ 1783 HWTEST_F(DistributedDBRelationalGetDataTest, EraseDeviceWaterMark001, TestSize.Level1) 1784 { 1785 auto syncAbleEngine = std::make_unique<SyncAbleEngine>(nullptr); 1786 ASSERT_NE(syncAbleEngine, nullptr); 1787 EXPECT_EQ(syncAbleEngine->EraseDeviceWaterMark("", true), -E_INVALID_ARGS); 1788 } 1789 } 1790 #endif 1791