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 "db_common.h"
19 #include "db_errno.h"
20 #include "db_types.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "kvdb_properties.h"
24 #include "log_print.h"
25 #include "prepared_stmt.h"
26 #include "relational_row_data_set.h"
27 #include "relational_store_delegate.h"
28 #include "relational_store_instance.h"
29 #include "relational_store_manager.h"
30 #include "relational_store_sqlite_ext.h"
31 #include "relational_sync_able_storage.h"
32 #include "sqlite_relational_store.h"
33 #include "sqlite_utils.h"
34 #include "virtual_communicator_aggregator.h"
35
36 using namespace testing::ext;
37 using namespace DistributedDB;
38 using namespace DistributedDBUnitTest;
39 using namespace std;
40
41 namespace {
42 string g_testDir;
43 string g_storePath;
44 string g_storeID = "dftStoreID";
45 string g_tableName { "data" };
46 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
47 RelationalStoreDelegate *g_delegate = nullptr;
48 IRelationalStore *g_store = nullptr;
49
CreateDBAndTable()50 void CreateDBAndTable()
51 {
52 sqlite3 *db = nullptr;
53 int errCode = sqlite3_open(g_storePath.c_str(), &db);
54 if (errCode != SQLITE_OK) {
55 LOGE("open db failed:%d", errCode);
56 sqlite3_close(db);
57 return;
58 }
59
60 const string sql =
61 "PRAGMA journal_mode=WAL;"
62 "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
63 char *zErrMsg = nullptr;
64 errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &zErrMsg);
65 if (errCode != SQLITE_OK) {
66 LOGE("sql error:%s", zErrMsg);
67 sqlite3_free(zErrMsg);
68 }
69 sqlite3_close(db);
70 }
71
InitStoreProp(const std::string & storePath,const std::string & appId,const std::string & userId,RelationalDBProperties & properties)72 void InitStoreProp(const std::string &storePath, const std::string &appId, const std::string &userId,
73 RelationalDBProperties &properties)
74 {
75 properties.SetStringProp(RelationalDBProperties::DATA_DIR, storePath);
76 properties.SetStringProp(RelationalDBProperties::APP_ID, appId);
77 properties.SetStringProp(RelationalDBProperties::USER_ID, userId);
78 properties.SetStringProp(RelationalDBProperties::STORE_ID, g_storeID);
79 std::string identifier = userId + "-" + appId + "-" + g_storeID;
80 std::string hashIdentifier = DBCommon::TransferHashString(identifier);
81 properties.SetStringProp(RelationalDBProperties::IDENTIFIER_DATA, hashIdentifier);
82 }
83
GetRelationalStore()84 const RelationalSyncAbleStorage *GetRelationalStore()
85 {
86 RelationalDBProperties properties;
87 InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
88 int errCode = E_OK;
89 g_store = RelationalStoreInstance::GetDataBase(properties, errCode);
90 if (g_store == nullptr) {
91 LOGE("Get db failed:%d", errCode);
92 return nullptr;
93 }
94 return static_cast<SQLiteRelationalStore *>(g_store)->GetStorageEngine();
95 }
96
ExecSql(sqlite3 * db,const std::string & sql)97 int ExecSql(sqlite3 *db, const std::string &sql)
98 {
99 return sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
100 }
101
InsertData(sqlite3 * db,size_t byteSize)102 int InsertData(sqlite3 *db, size_t byteSize)
103 {
104 static const std::string sql = "INSERT OR REPLACE INTO " + g_tableName + " VALUES(?,?);";
105 sqlite3_stmt *stmt = nullptr;
106 int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
107 if (errCode != E_OK) {
108 return errCode;
109 }
110 std::vector<uint8_t> value(byteSize);
111 errCode = SQLiteUtils::BindBlobToStatement(stmt, 2, value, false); // 2 means value's index.
112 if (errCode != E_OK) {
113 return errCode;
114 }
115 errCode = SQLiteUtils::StepWithRetry(stmt);
116 if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
117 errCode = E_OK;
118 }
119 SQLiteUtils::ResetStatement(stmt, true, errCode);
120 return errCode;
121 }
122 }
123
124 class DistributedDBRelationalRemoteQueryTest : public testing::Test {
125 public:
126 static void SetUpTestCase();
127 static void TearDownTestCase();
128 void SetUp();
129 void TearDown();
130 };
131
SetUpTestCase(void)132 void DistributedDBRelationalRemoteQueryTest::SetUpTestCase(void)
133 {
134 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
135 g_storePath = g_testDir + "/relationalRemoteQueryTest.db";
136 LOGI("The test db is:%s", g_testDir.c_str());
137
138 auto communicator = new (std::nothrow) VirtualCommunicatorAggregator();
139 ASSERT_TRUE(communicator != nullptr);
140 RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicator);
141 }
142
TearDownTestCase(void)143 void DistributedDBRelationalRemoteQueryTest::TearDownTestCase(void)
144 {
145 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
146 }
147
SetUp(void)148 void DistributedDBRelationalRemoteQueryTest::SetUp(void)
149 {
150 g_tableName = "data";
151 DistributedDBToolsUnitTest::PrintTestCaseInfo();
152 CreateDBAndTable();
153 }
154
TearDown(void)155 void DistributedDBRelationalRemoteQueryTest::TearDown(void)
156 {
157 if (g_delegate != nullptr) {
158 EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
159 g_delegate = nullptr;
160 }
161 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
162 LOGE("rm test db files error.");
163 }
164 return;
165 }
166
167 /**
168 * @tc.name: NormalQuery1
169 * @tc.desc: Normal query.
170 * @tc.type: FUNC
171 * @tc.require: AR000GK58G
172 * @tc.author: lidongwei
173 */
174 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NormalQuery1, TestSize.Level1)
175 {
176 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
177 ASSERT_NE(g_delegate, nullptr);
178 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
179
180 /**
181 * @tc.steps: step1. Put data.
182 * @tc.expected: Succeed, return OK.
183 */
184 sqlite3 *db = nullptr;
185 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
186 ASSERT_NE(db, nullptr);
187
188 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"), 0);
189 sqlite3_close(db);
190
191 /**
192 * @tc.steps: step2. Query with QUERY opcode and a select sql.
193 * @tc.expected: Query successfully.
194 */
195 auto store = GetRelationalStore();
196
197 ASSERT_NE(store, nullptr);
198 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
199 RelationalRowDataSet rowDataSet {};
200 ContinueToken token = nullptr;
201 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
202 EXPECT_EQ(rowDataSet.GetSize(), 1);
203 EXPECT_EQ(token, nullptr);
204 RefObject::DecObjRef(g_store);
205 }
206
207 /**
208 * @tc.name: BoolQuery1
209 * @tc.desc: Query bool.
210 * @tc.type: FUNC
211 * @tc.require: AR000GK58G
212 * @tc.author: lidongwei
213 */
214 HWTEST_F(DistributedDBRelationalRemoteQueryTest, BoolQuery1, TestSize.Level1)
215 {
216 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
217 ASSERT_NE(g_delegate, nullptr);
218 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
219
220 /**
221 * @tc.steps: step1. Put data.
222 * @tc.expected: Succeed, return OK.
223 */
224 sqlite3 *db = nullptr;
225 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
226 ASSERT_NE(db, nullptr);
227
228 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"), 0);
229 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(2, '1');"), 0);
230 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(3, true);"), 0);
231 sqlite3_close(db);
232
233 /**
234 * @tc.steps: step2. Check bool.
235 * @tc.expected: '1' and 1 and true in sql is OK. 1 in bindArgs is OK.
236 */
237 auto store = GetRelationalStore();
238 ASSERT_NE(store, nullptr);
239
240 RelationalRowDataSet rowDataSet {};
241 ContinueToken token = nullptr;
242
243 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"1"});
244 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
245 EXPECT_EQ(rowDataSet.GetSize(), 3);
246
247 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value='1'", {} };
248 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
249 EXPECT_EQ(rowDataSet.GetSize(), 3);
250
251 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=1", {} };
252 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
253 EXPECT_EQ(rowDataSet.GetSize(), 3);
254
255 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=true", {} };
256 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
257 EXPECT_EQ(rowDataSet.GetSize(), 3);
258
259 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"'1'"} };
260 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
261 EXPECT_EQ(rowDataSet.GetSize(), 0);
262
263 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value='true'", {} };
264 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
265 EXPECT_EQ(rowDataSet.GetSize(), 0);
266
267 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"true"} };
268 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
269 EXPECT_EQ(rowDataSet.GetSize(), 0);
270
271 RefObject::DecObjRef(g_store);
272 }
273
274 /**
275 * @tc.name: BlobQuery1
276 * @tc.desc: Query blob.
277 * @tc.type: FUNC
278 * @tc.require: AR000GK58G
279 * @tc.author: lidongwei
280 */
281 HWTEST_F(DistributedDBRelationalRemoteQueryTest, BlobQuery1, TestSize.Level1)
282 {
283 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
284 ASSERT_NE(g_delegate, nullptr);
285 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
286
287 /**
288 * @tc.steps: step1. Put data.
289 * @tc.expected: Succeed, return OK.
290 */
291 sqlite3 *db = nullptr;
292 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
293 ASSERT_NE(db, nullptr);
294
295 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, x'10101010001000');"), 0);
296 sqlite3_close(db);
297
298 /**
299 * @tc.steps: step2. Check blob.
300 * @tc.expected: x'xxx' in sql is OK. Not ok in bindArgs.
301 */
302 auto store = GetRelationalStore();
303 ASSERT_NE(store, nullptr);
304
305 RelationalRowDataSet rowDataSet {};
306 ContinueToken token = nullptr;
307
308 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=x'10101010001000'", {});
309 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
310 EXPECT_EQ(rowDataSet.GetSize(), 1);
311 EXPECT_FALSE(rowDataSet.GetColNames().empty());
312
313 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"x'10101010001000'"} };
314 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
315 EXPECT_EQ(rowDataSet.GetSize(), 0);
316 EXPECT_TRUE(rowDataSet.GetColNames().empty());
317
318 RefObject::DecObjRef(g_store);
319 }
320
321 /**
322 * @tc.name: InsertQuery1
323 * @tc.desc: Query with insert statement.
324 * @tc.type: FUNC
325 * @tc.require: AR000GK58G
326 * @tc.author: lidongwei
327 */
328 HWTEST_F(DistributedDBRelationalRemoteQueryTest, InsertQuery1, TestSize.Level1)
329 {
330 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
331 ASSERT_NE(g_delegate, nullptr);
332 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
333
334 /**
335 * @tc.steps: step1. Put data.
336 * @tc.expected: Succeed, return OK.
337 */
338 sqlite3 *db = nullptr;
339 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
340 ASSERT_NE(db, nullptr);
341
342 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, x'10101010001000');"), 0);
343 sqlite3_close(db);
344
345 /**
346 * @tc.steps: step2. Query with a insert statement.
347 * @tc.expected: Query failed.
348 */
349 auto store = GetRelationalStore();
350 ASSERT_NE(store, nullptr);
351
352 RelationalRowDataSet rowDataSet {};
353 ContinueToken token = nullptr;
354
355 /**
356 * @tc.steps: step3. Query with INSERT opcode.
357 * @tc.expected: Query failed. Return E_INVALID_ARGS.
358 */
359 PreparedStmt prepStmt(PreparedStmt::INSERT, "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {});
360 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -E_INVALID_ARGS);
361 EXPECT_EQ(rowDataSet.GetSize(), 0);
362
363 /**
364 * @tc.steps: step4. Query with QUERY opcode and a insert sql.
365 * @tc.expected: Query failed. Return E_DENIED_SQL.
366 */
367 prepStmt = { PreparedStmt::QUERY, "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {} };
368 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -E_DENIED_SQL);
369 EXPECT_EQ(rowDataSet.GetSize(), 0);
370
371 /**
372 * @tc.steps: step5. Query with QUERY opcode and two sql(one select and one insert).
373 * @tc.expected: Query OK. The second sql is ignored.
374 */
375 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=x'10101010001000';"
376 "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {} };
377 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
378 EXPECT_EQ(rowDataSet.GetSize(), 1);
379
380 RefObject::DecObjRef(g_store);
381 }
382
383 /**
384 * @tc.name: NonexistentTable1
385 * @tc.desc: Nonexistent table or column.
386 * @tc.type: FUNC
387 * @tc.require: AR000GK58G
388 * @tc.author: lidongwei
389 */
390 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NonexistentTable1, TestSize.Level1)
391 {
392 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
393 ASSERT_NE(g_delegate, nullptr);
394 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
395
396 /**
397 * @tc.steps: step1. Query when nonexistent table or nonexistent column.
398 * @tc.expected: Failed, return SQLITE_ERROR
399 */
400 auto store = GetRelationalStore();
401 ASSERT_NE(store, nullptr);
402
403 RelationalRowDataSet rowDataSet {};
404 ContinueToken token = nullptr;
405
406 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM nonexistent_table WHERE value=1;", {});
407 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -SQLITE_ERROR);
408
409 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE nonexistent_column=1;", {} };
410 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -SQLITE_ERROR);
411
412 RefObject::DecObjRef(g_store);
413 }
414
415 /**
416 * @tc.name: PreparedStmtSerialize
417 * @tc.desc: Test the serialization and deserialization of PreparedStmt.
418 * @tc.type: FUNC
419 * @tc.require: AR000GK58G
420 * @tc.author: lidongwei
421 */
422 HWTEST_F(DistributedDBRelationalRemoteQueryTest, PreparedStmtSerialize, TestSize.Level1)
423 {
424 /**
425 * @tc.steps: step1. Create a prepared stmt;
426 * @tc.expected: OK.
427 */
428 PreparedStmt prepStmt1(PreparedStmt::QUERY, "SELECT * FROM test WHERE value=? or value=?", {"1", "2"});
429 int len = prepStmt1.CalcLength();
430
431 /**
432 * @tc.steps: step2. Serialize the prepared stmt;
433 * @tc.expected: Serialize OK.
434 */
435 std::vector<uint8_t> buffer(len);
436 Parcel parcel1(buffer.data(), buffer.size());
437 ASSERT_EQ(prepStmt1.Serialize(parcel1), E_OK);
438 ASSERT_FALSE(parcel1.IsError());
439
440 /**
441 * @tc.steps: step3. Deserialize the prepared stmt;
442 * @tc.expected: Deserialize OK.
443 */
444 PreparedStmt prepStmt2;
445 Parcel parcel2(buffer.data(), buffer.size());
446 ASSERT_EQ(prepStmt2.DeSerialize(parcel2), E_OK);
447 ASSERT_FALSE(parcel2.IsError());
448
449 /**
450 * @tc.steps: step4. Compare the deserialized prepared stmt with the original;
451 * @tc.expected: Compare OK. They are the same.
452 */
453 EXPECT_EQ(prepStmt1.GetOpCode(), prepStmt2.GetOpCode());
454 EXPECT_EQ(prepStmt1.GetSql(), prepStmt2.GetSql());
455 EXPECT_EQ(prepStmt1.GetBindArgs(), prepStmt2.GetBindArgs());
456 }
457
458 /**
459 * @tc.name: ComplexQuery1
460 * @tc.desc: Complex query with join or aggregate func.
461 * @tc.type: FUNC
462 * @tc.require: AR000GK58G
463 * @tc.author: lidongwei
464 */
465 HWTEST_F(DistributedDBRelationalRemoteQueryTest, ComplexQuery1, TestSize.Level1)
466 {
467 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
468 ASSERT_NE(g_delegate, nullptr);
469 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
470
471 sqlite3 *db = nullptr;
472 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
473 ASSERT_NE(db, nullptr);
474
475 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"
476 "CREATE TABLE IF NOT EXISTS r(key INTEGER, value INTEGER);"
477 "INSERT INTO r VALUES(1, 1);"), 0);
478 sqlite3_close(db);
479
480 /**
481 * @tc.steps: step1. Query with a complex sql.
482 * @tc.expected: Succeed.
483 */
484 auto store = GetRelationalStore();
485 ASSERT_NE(store, nullptr);
486
487 RelationalRowDataSet rowDataSet {};
488 ContinueToken token = nullptr;
489
490 PreparedStmt prepStmt(PreparedStmt::QUERY,
491 "SELECT COUNT(*) FROM " + g_tableName + " INNER JOIN r ON " + g_tableName + ".key=r.key "
492 "WHERE r.value IN (1,2,3);", {});
493 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
494 EXPECT_EQ(rowDataSet.GetSize(), 1);
495
496 RefObject::DecObjRef(g_store);
497 }
498
499 /**
500 * @tc.name: LargeAmountOfData1
501 * @tc.desc: Large Amount Of Data.
502 * @tc.type: FUNC
503 * @tc.require: AR000GK58G
504 * @tc.author: lidongwei
505 */
506 HWTEST_F(DistributedDBRelationalRemoteQueryTest, LargeAmountOfData1, TestSize.Level1)
507 {
508 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
509 ASSERT_NE(g_delegate, nullptr);
510 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
511
512 sqlite3 *db = nullptr;
513 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
514 ASSERT_NE(db, nullptr);
515
516 /**
517 * @tc.steps: step1. Insert 20 data.
518 * @tc.expected: Succeed.
519 */
520 int i = 10; // 10 for test.
521 while (i-- > 0) {
522 ASSERT_EQ(InsertData(db, 500), 0); // 500 for test.
523 ASSERT_EQ(InsertData(db, 1500), 0); // 1500 for test.
524 }
525 sqlite3_close(db);
526
527 /**
528 * @tc.steps: step2. Query.
529 * @tc.expected: Get 20 data.
530 */
531 auto store = GetRelationalStore();
532 ASSERT_NE(store, nullptr);
533
534 ContinueToken token = nullptr;
535 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
536
537 size_t totalCnt = 0;
538 RelationalRowDataSet allRowDataSet {};
539 do {
540 RelationalRowDataSet rowDataSet {};
541 EXPECT_EQ(store->ExecuteQuery(prepStmt, 1024, rowDataSet, token), E_OK); // 1024 is min mtu.
542 totalCnt += rowDataSet.GetSize();
543 EXPECT_EQ(allRowDataSet.Merge(std::move(rowDataSet)), E_OK);
544 } while (token != nullptr);
545
546 EXPECT_EQ(totalCnt, 20u);
547 EXPECT_EQ(allRowDataSet.GetSize(), 20);
548
549 RefObject::DecObjRef(g_store);
550 }
551
552 /**
553 * @tc.name: OverSize1
554 * @tc.desc: Over size.
555 * @tc.type: FUNC
556 * @tc.require: AR000GK58G
557 * @tc.author: lidongwei
558 */
559 HWTEST_F(DistributedDBRelationalRemoteQueryTest, OverSize1, TestSize.Level1)
560 {
561 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
562 ASSERT_NE(g_delegate, nullptr);
563 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
564
565 sqlite3 *db = nullptr;
566 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
567 ASSERT_NE(db, nullptr);
568
569 /**
570 * @tc.steps: step1. Insert over 4M data.
571 * @tc.expected: Succeed.
572 */
573 int i = 4; // 4MB
574 while (i-- > 0) {
575 ASSERT_EQ(InsertData(db, 1024 * 1024), 0); // 1024*1024 means 1MB.
576 }
577 sqlite3_close(db);
578
579 /**
580 * @tc.steps: step2. Query.
581 * @tc.expected: Failed, return E_REMOTE_OVER_SIZE.
582 */
583 auto store = GetRelationalStore();
584 ASSERT_NE(store, nullptr);
585
586 ContinueToken token = nullptr;
587 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
588
589 RelationalRowDataSet rowDataSet {};
590 EXPECT_EQ(store->ExecuteQuery(prepStmt, 1200, rowDataSet, token), -E_REMOTE_OVER_SIZE);
591 RefObject::DecObjRef(g_store);
592 }
593
594 /**
595 * @tc.name: RemoteQueryForNotDistributedDb
596 * @tc.desc: Not create distributed table, exec remote query.
597 * @tc.type: FUNC
598 * @tc.require: AR000GK58G
599 * @tc.author: lidongwei
600 */
601 HWTEST_F(DistributedDBRelationalRemoteQueryTest, RemoteQueryForNotDistributedDb, TestSize.Level1)
602 {
603 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
604 ASSERT_NE(g_delegate, nullptr);
605
606 std::shared_ptr<ResultSet> result = nullptr;
607 EXPECT_EQ(g_delegate->RemoteQuery("deviceA", RemoteCondition {}, 1000, result), DBStatus::NOT_SUPPORT);
608 }
609 #endif
610