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: NormalQuery1
209 * @tc.desc: test sql len is larger than 100,0000
210 * @tc.type: FUNC
211 * @tc.require: AR000GK58G
212 * @tc.author: zhuwentao
213 */
214 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NormalQuery2, 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 std::string device = "deviceB";
220 RemoteCondition sqlCondition;
221 sqlCondition.sql.resize(1000001, 'a');
222 std::shared_ptr<ResultSet> result = nullptr;
223 EXPECT_EQ(g_delegate->RemoteQuery(device, sqlCondition, 5000, result), OVER_MAX_LIMITS);
224 }
225
226 /**
227 * @tc.name: BoolQuery1
228 * @tc.desc: Query bool.
229 * @tc.type: FUNC
230 * @tc.require: AR000GK58G
231 * @tc.author: lidongwei
232 */
233 HWTEST_F(DistributedDBRelationalRemoteQueryTest, BoolQuery1, TestSize.Level1)
234 {
235 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
236 ASSERT_NE(g_delegate, nullptr);
237 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
238
239 /**
240 * @tc.steps: step1. Put data.
241 * @tc.expected: Succeed, return OK.
242 */
243 sqlite3 *db = nullptr;
244 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
245 ASSERT_NE(db, nullptr);
246
247 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"), 0);
248 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(2, '1');"), 0);
249 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(3, true);"), 0);
250 sqlite3_close(db);
251
252 /**
253 * @tc.steps: step2. Check bool.
254 * @tc.expected: '1' and 1 and true in sql is OK. 1 in bindArgs is OK.
255 */
256 auto store = GetRelationalStore();
257 ASSERT_NE(store, nullptr);
258
259 RelationalRowDataSet rowDataSet {};
260 ContinueToken token = nullptr;
261
262 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"1"});
263 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
264 EXPECT_EQ(rowDataSet.GetSize(), 3);
265
266 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value='1'", {} };
267 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
268 EXPECT_EQ(rowDataSet.GetSize(), 3);
269
270 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=1", {} };
271 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
272 EXPECT_EQ(rowDataSet.GetSize(), 3);
273
274 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=true", {} };
275 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
276 EXPECT_EQ(rowDataSet.GetSize(), 3);
277
278 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"'1'"} };
279 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
280 EXPECT_EQ(rowDataSet.GetSize(), 0);
281
282 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value='true'", {} };
283 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
284 EXPECT_EQ(rowDataSet.GetSize(), 0);
285
286 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"true"} };
287 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
288 EXPECT_EQ(rowDataSet.GetSize(), 0);
289
290 RefObject::DecObjRef(g_store);
291 }
292
293 /**
294 * @tc.name: BlobQuery1
295 * @tc.desc: Query blob.
296 * @tc.type: FUNC
297 * @tc.require: AR000GK58G
298 * @tc.author: lidongwei
299 */
300 HWTEST_F(DistributedDBRelationalRemoteQueryTest, BlobQuery1, TestSize.Level1)
301 {
302 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
303 ASSERT_NE(g_delegate, nullptr);
304 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
305
306 /**
307 * @tc.steps: step1. Put data.
308 * @tc.expected: Succeed, return OK.
309 */
310 sqlite3 *db = nullptr;
311 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
312 ASSERT_NE(db, nullptr);
313
314 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, x'10101010001000');"), 0);
315 sqlite3_close(db);
316
317 /**
318 * @tc.steps: step2. Check blob.
319 * @tc.expected: x'xxx' in sql is OK. Not ok in bindArgs.
320 */
321 auto store = GetRelationalStore();
322 ASSERT_NE(store, nullptr);
323
324 RelationalRowDataSet rowDataSet {};
325 ContinueToken token = nullptr;
326
327 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=x'10101010001000'", {});
328 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
329 EXPECT_EQ(rowDataSet.GetSize(), 1);
330 EXPECT_FALSE(rowDataSet.GetColNames().empty());
331
332 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"x'10101010001000'"} };
333 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
334 EXPECT_EQ(rowDataSet.GetSize(), 0);
335 EXPECT_TRUE(rowDataSet.GetColNames().empty());
336
337 RefObject::DecObjRef(g_store);
338 }
339
340 /**
341 * @tc.name: InsertQuery1
342 * @tc.desc: Query with insert statement.
343 * @tc.type: FUNC
344 * @tc.require: AR000GK58G
345 * @tc.author: lidongwei
346 */
347 HWTEST_F(DistributedDBRelationalRemoteQueryTest, InsertQuery1, TestSize.Level1)
348 {
349 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
350 ASSERT_NE(g_delegate, nullptr);
351 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
352
353 /**
354 * @tc.steps: step1. Put data.
355 * @tc.expected: Succeed, return OK.
356 */
357 sqlite3 *db = nullptr;
358 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
359 ASSERT_NE(db, nullptr);
360
361 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, x'10101010001000');"), 0);
362 sqlite3_close(db);
363
364 /**
365 * @tc.steps: step2. Query with a insert statement.
366 * @tc.expected: Query failed.
367 */
368 auto store = GetRelationalStore();
369 ASSERT_NE(store, nullptr);
370
371 RelationalRowDataSet rowDataSet {};
372 ContinueToken token = nullptr;
373
374 /**
375 * @tc.steps: step3. Query with INSERT opcode.
376 * @tc.expected: Query failed. Return E_INVALID_ARGS.
377 */
378 PreparedStmt prepStmt(PreparedStmt::INSERT, "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {});
379 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -E_INVALID_ARGS);
380 EXPECT_EQ(rowDataSet.GetSize(), 0);
381
382 /**
383 * @tc.steps: step4. Query with QUERY opcode and a insert sql.
384 * @tc.expected: Query failed. Return E_DENIED_SQL.
385 */
386 prepStmt = { PreparedStmt::QUERY, "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {} };
387 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -E_DENIED_SQL);
388 EXPECT_EQ(rowDataSet.GetSize(), 0);
389
390 /**
391 * @tc.steps: step5. Query with QUERY opcode and two sql(one select and one insert).
392 * @tc.expected: Query OK. The second sql is ignored.
393 */
394 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=x'10101010001000';"
395 "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {} };
396 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
397 EXPECT_EQ(rowDataSet.GetSize(), 1);
398
399 RefObject::DecObjRef(g_store);
400 }
401
402 /**
403 * @tc.name: NonexistentTable1
404 * @tc.desc: Nonexistent table or column.
405 * @tc.type: FUNC
406 * @tc.require: AR000GK58G
407 * @tc.author: lidongwei
408 */
409 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NonexistentTable1, TestSize.Level1)
410 {
411 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
412 ASSERT_NE(g_delegate, nullptr);
413 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
414
415 /**
416 * @tc.steps: step1. Query when nonexistent table or nonexistent column.
417 * @tc.expected: Failed, return SQLITE_ERROR
418 */
419 auto store = GetRelationalStore();
420 ASSERT_NE(store, nullptr);
421
422 RelationalRowDataSet rowDataSet {};
423 ContinueToken token = nullptr;
424
425 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM nonexistent_table WHERE value=1;", {});
426 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -SQLITE_ERROR);
427
428 prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE nonexistent_column=1;", {} };
429 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -SQLITE_ERROR);
430
431 RefObject::DecObjRef(g_store);
432 }
433
434 /**
435 * @tc.name: PreparedStmtSerialize
436 * @tc.desc: Test the serialization and deserialization of PreparedStmt.
437 * @tc.type: FUNC
438 * @tc.require: AR000GK58G
439 * @tc.author: lidongwei
440 */
441 HWTEST_F(DistributedDBRelationalRemoteQueryTest, PreparedStmtSerialize, TestSize.Level1)
442 {
443 /**
444 * @tc.steps: step1. Create a prepared stmt;
445 * @tc.expected: OK.
446 */
447 PreparedStmt prepStmt1(PreparedStmt::QUERY, "SELECT * FROM test WHERE value=? or value=?", {"1", "2"});
448 int len = static_cast<int>(prepStmt1.CalcLength());
449
450 /**
451 * @tc.steps: step2. Serialize the prepared stmt;
452 * @tc.expected: Serialize OK.
453 */
454 std::vector<uint8_t> buffer(len);
455 Parcel parcel1(buffer.data(), buffer.size());
456 ASSERT_EQ(prepStmt1.Serialize(parcel1), E_OK);
457 ASSERT_FALSE(parcel1.IsError());
458
459 /**
460 * @tc.steps: step3. Deserialize the prepared stmt;
461 * @tc.expected: Deserialize OK.
462 */
463 PreparedStmt prepStmt2;
464 Parcel parcel2(buffer.data(), buffer.size());
465 ASSERT_EQ(prepStmt2.DeSerialize(parcel2), E_OK);
466 ASSERT_FALSE(parcel2.IsError());
467
468 /**
469 * @tc.steps: step4. Compare the deserialized prepared stmt with the original;
470 * @tc.expected: Compare OK. They are the same.
471 */
472 EXPECT_EQ(prepStmt1.GetOpCode(), prepStmt2.GetOpCode());
473 EXPECT_EQ(prepStmt1.GetSql(), prepStmt2.GetSql());
474 EXPECT_EQ(prepStmt1.GetBindArgs(), prepStmt2.GetBindArgs());
475 }
476
477 /**
478 * @tc.name: ComplexQuery1
479 * @tc.desc: Complex query with join or aggregate func.
480 * @tc.type: FUNC
481 * @tc.require: AR000GK58G
482 * @tc.author: lidongwei
483 */
484 HWTEST_F(DistributedDBRelationalRemoteQueryTest, ComplexQuery1, TestSize.Level1)
485 {
486 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
487 ASSERT_NE(g_delegate, nullptr);
488 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
489
490 sqlite3 *db = nullptr;
491 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
492 ASSERT_NE(db, nullptr);
493
494 EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"
495 "CREATE TABLE IF NOT EXISTS r(key INTEGER, value INTEGER);"
496 "INSERT INTO r VALUES(1, 1);"), 0);
497 sqlite3_close(db);
498
499 /**
500 * @tc.steps: step1. Query with a complex sql.
501 * @tc.expected: Succeed.
502 */
503 auto store = GetRelationalStore();
504 ASSERT_NE(store, nullptr);
505
506 RelationalRowDataSet rowDataSet {};
507 ContinueToken token = nullptr;
508
509 PreparedStmt prepStmt(PreparedStmt::QUERY,
510 "SELECT COUNT(*) FROM " + g_tableName + " INNER JOIN r ON " + g_tableName + ".key=r.key "
511 "WHERE r.value IN (1,2,3);", {});
512 EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
513 EXPECT_EQ(rowDataSet.GetSize(), 1);
514
515 RefObject::DecObjRef(g_store);
516 }
517
518 /**
519 * @tc.name: LargeAmountOfData1
520 * @tc.desc: Large Amount Of Data.
521 * @tc.type: FUNC
522 * @tc.require: AR000GK58G
523 * @tc.author: lidongwei
524 */
525 HWTEST_F(DistributedDBRelationalRemoteQueryTest, LargeAmountOfData1, TestSize.Level1)
526 {
527 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
528 ASSERT_NE(g_delegate, nullptr);
529 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
530
531 sqlite3 *db = nullptr;
532 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
533 ASSERT_NE(db, nullptr);
534
535 /**
536 * @tc.steps: step1. Insert 20 data.
537 * @tc.expected: Succeed.
538 */
539 int i = 10; // 10 for test.
540 while (i-- > 0) {
541 ASSERT_EQ(InsertData(db, 500), 0); // 500 for test.
542 ASSERT_EQ(InsertData(db, 1500), 0); // 1500 for test.
543 }
544 sqlite3_close(db);
545
546 /**
547 * @tc.steps: step2. Query.
548 * @tc.expected: Get 20 data.
549 */
550 auto store = GetRelationalStore();
551 ASSERT_NE(store, nullptr);
552
553 ContinueToken token = nullptr;
554 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
555
556 size_t totalCnt = 0;
557 RelationalRowDataSet allRowDataSet {};
558 do {
559 RelationalRowDataSet rowDataSet {};
560 EXPECT_EQ(store->ExecuteQuery(prepStmt, 1024, rowDataSet, token), E_OK); // 1024 is min mtu.
561 totalCnt += static_cast<size_t>(rowDataSet.GetSize());
562 EXPECT_EQ(allRowDataSet.Merge(std::move(rowDataSet)), E_OK);
563 } while (token != nullptr);
564
565 EXPECT_EQ(totalCnt, 20u);
566 EXPECT_EQ(allRowDataSet.GetSize(), 20);
567
568 RefObject::DecObjRef(g_store);
569 }
570
571 /**
572 * @tc.name: OverSize1
573 * @tc.desc: Over size.
574 * @tc.type: FUNC
575 * @tc.require: AR000GK58G
576 * @tc.author: lidongwei
577 */
578 HWTEST_F(DistributedDBRelationalRemoteQueryTest, OverSize1, TestSize.Level1)
579 {
580 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
581 ASSERT_NE(g_delegate, nullptr);
582 ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
583
584 sqlite3 *db = nullptr;
585 ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
586 ASSERT_NE(db, nullptr);
587
588 /**
589 * @tc.steps: step1. Insert over 4M data.
590 * @tc.expected: Succeed.
591 */
592 int i = 4; // 4MB
593 while (i-- > 0) {
594 ASSERT_EQ(InsertData(db, 1024 * 1024), 0); // 1024*1024 means 1MB.
595 }
596 sqlite3_close(db);
597
598 /**
599 * @tc.steps: step2. Query.
600 * @tc.expected: Failed, return E_REMOTE_OVER_SIZE.
601 */
602 auto store = GetRelationalStore();
603 ASSERT_NE(store, nullptr);
604
605 ContinueToken token = nullptr;
606 PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
607
608 RelationalRowDataSet rowDataSet {};
609 EXPECT_EQ(store->ExecuteQuery(prepStmt, 1200, rowDataSet, token), -E_REMOTE_OVER_SIZE);
610 RefObject::DecObjRef(g_store);
611 }
612
613 /**
614 * @tc.name: RemoteQueryForNotDistributedDb
615 * @tc.desc: Not create distributed table, exec remote query.
616 * @tc.type: FUNC
617 * @tc.require: AR000GK58G
618 * @tc.author: lidongwei
619 */
620 HWTEST_F(DistributedDBRelationalRemoteQueryTest, RemoteQueryForNotDistributedDb, TestSize.Level1)
621 {
622 ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
623 ASSERT_NE(g_delegate, nullptr);
624
625 std::shared_ptr<ResultSet> result = nullptr;
626 EXPECT_EQ(g_delegate->RemoteQuery("deviceA", RemoteCondition {}, 1000, result), DBStatus::NOT_SUPPORT);
627 }
628 #endif
629