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
16 #include <gtest/gtest.h>
17
18 #include <string>
19
20 #include "common.h"
21 #include "grd_api_manager.h"
22 #include "rdb_errno.h"
23 #include "rdb_helper.h"
24 #include "rdb_open_callback.h"
25 using namespace testing::ext;
26 using namespace OHOS::NativeRdb;
27 namespace Test {
28 class RdbReadOnlyTest : public testing::Test {
29 public:
30 static void SetUpTestCase(void);
31 static void TearDownTestCase(void);
32 void SetUp();
33 void TearDown();
34
35 static const std::string READONLY_DATABASE_NAME;
36 static const std::string READONLY_DATABASE_NAME_18; // for testcase 18
37 static const std::string READONLY_DATABASE_BAK_NAME;
38 static const std::string DATABASE_NAME;
39 static std::shared_ptr<RdbStore> readOnlyStore;
40 };
41
42 const std::string RdbReadOnlyTest::DATABASE_NAME = RDB_TEST_PATH + "database.db";
43 const std::string RdbReadOnlyTest::READONLY_DATABASE_NAME = RDB_TEST_PATH + "readOnly.db";
44 const std::string RdbReadOnlyTest::READONLY_DATABASE_NAME_18 = RDB_TEST_PATH + "readOnly1.db";
45 const std::string RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME = RDB_TEST_PATH + "readOnlyBak.db";
46 std::shared_ptr<RdbStore> RdbReadOnlyTest::readOnlyStore = nullptr;
47
48 class ReadOnlyTestOpenCallback : public RdbOpenCallback {
49 public:
50 int OnCreate(RdbStore &store) override;
51 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
52 static const std::string CREATE_TABLE_TEST;
53 };
54
55 const std::string ReadOnlyTestOpenCallback::CREATE_TABLE_TEST =
56 "CREATE TABLE IF NOT EXISTS test "
57 "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, salary REAL, blobType BLOB)";
58
OnCreate(RdbStore & store)59 int ReadOnlyTestOpenCallback::OnCreate(RdbStore &store)
60 {
61 return store.ExecuteSql(CREATE_TABLE_TEST);
62 }
63
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)64 int ReadOnlyTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
65 {
66 return E_OK;
67 }
68
SetUpTestCase(void)69 void RdbReadOnlyTest::SetUpTestCase(void)
70 {
71 int errCode = E_ERROR;
72 RdbHelper::DeleteRdbStore(READONLY_DATABASE_NAME);
73 RdbStoreConfig config(READONLY_DATABASE_NAME);
74 config.SetBundleName("com.example.readOnly.rdb");
75 ReadOnlyTestOpenCallback helper;
76 // user_version is 1
77 auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
78 EXPECT_NE(nullptr, store);
79 EXPECT_EQ(E_OK, errCode);
80
81 int64_t id;
82 ValuesBucket values;
83 values.PutString("name", "zhangSan");
84 int ret = store->Insert(id, "test", values);
85 EXPECT_EQ(E_OK, ret);
86 // id is 1
87 EXPECT_EQ(1, id);
88
89 RdbHelper::ClearCache();
90
91 RdbStoreConfig config1(READONLY_DATABASE_NAME);
92 config1.SetBundleName("com.example.readOnly.rdb");
93 config1.SetReadOnly(true);
94 ReadOnlyTestOpenCallback helper1;
95 // user_version is 1
96 readOnlyStore = RdbHelper::GetRdbStore(config1, 1, helper1, errCode);
97 EXPECT_NE(nullptr, readOnlyStore);
98 EXPECT_EQ(E_OK, errCode);
99 }
100
TearDownTestCase(void)101 void RdbReadOnlyTest::TearDownTestCase(void)
102 {
103 readOnlyStore = nullptr;
104 EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::DATABASE_NAME));
105 EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::READONLY_DATABASE_NAME));
106 EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME));
107 }
108
SetUp()109 void RdbReadOnlyTest::SetUp()
110 {
111 }
112
TearDown()113 void RdbReadOnlyTest::TearDown()
114 {
115 }
116
117 /**
118 * @tc.name: RdbStore_ReadOnly_0001, open read-only database if the database is not exist
119 * @tc.desc: 1. set isReadOnly as true
120 * 2. open read-only database
121 * @tc.type: FUNC
122 */
123 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0001, TestSize.Level1)
124 {
125 int errCode = E_ERROR;
126 RdbStoreConfig config(RdbReadOnlyTest::DATABASE_NAME);
127 config.SetReadOnly(true);
128 ReadOnlyTestOpenCallback helper;
129 // create read-only database, user_version is 1
130 auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
131 EXPECT_EQ(nullptr, store);
132 EXPECT_EQ(E_SQLITE_CANTOPEN, errCode);
133 }
134
135 /**
136 * @tc.name: RdbStore_ReadOnly_0002, insert data
137 * @tc.desc: insert data into read-only database
138 * @tc.type: FUNC
139 */
140 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0002, TestSize.Level1)
141 {
142 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
143
144 int64_t id;
145 ValuesBucket values;
146 values.PutString("name", "liSi");
147 int ret = store->Insert(id, "test", values);
148 EXPECT_EQ(E_NOT_SUPPORT, ret);
149 }
150
151 /**
152 * @tc.name: RdbStore_ReadOnly_0003, update data
153 * @tc.desc: update data in read-only database
154 * @tc.type: FUNC
155 */
156 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0003, TestSize.Level1)
157 {
158 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
159
160 int changedRows;
161 ValuesBucket values;
162 // salary is 300.5
163 values.PutDouble("salary", 300.5);
164 auto ret = store->Update(changedRows, "test", values);
165 EXPECT_EQ(E_NOT_SUPPORT, ret);
166 }
167
168 /**
169 * @tc.name: RdbStore_ReadOnly_0004, delete data
170 * @tc.desc: delete data from read-only database
171 * @tc.type: FUNC
172 */
173 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0004, TestSize.Level1)
174 {
175 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
176
177 int deletedRows;
178 auto ret = store->Delete(deletedRows, "test", "id = 1");
179 EXPECT_EQ(E_NOT_SUPPORT, ret);
180 }
181
182 /**
183 * @tc.name: RdbStore_ReadOnly_0005
184 * @tc.desc: execute transaction
185 * @tc.type: FUNC
186 */
187 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0005, TestSize.Level1)
188 {
189 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
190
191 auto ret = store->BeginTransaction();
192 EXPECT_EQ(E_NOT_SUPPORT, ret);
193
194 ret = store->Commit();
195 EXPECT_EQ(E_NOT_SUPPORT, ret);
196
197 ret = store->RollBack();
198 EXPECT_EQ(E_NOT_SUPPORT, ret);
199 }
200
201 /**
202 * @tc.name: RdbStore_ReadOnly_0006
203 * @tc.desc: batch insert data
204 * @tc.type: FUNC
205 */
206 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0006, TestSize.Level1)
207 {
208 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
209
210 int64_t number = 0;
211 std::vector<ValuesBucket> valuesBuckets;
212 ValuesBucket values;
213 values.PutString("name", "zhangSan");
214 valuesBuckets.push_back(std::move(values));
215 int error = store->BatchInsert(number, "test", valuesBuckets);
216 EXPECT_EQ(E_NOT_SUPPORT, error);
217 }
218
219 /**
220 * @tc.name: RdbStore_ReadOnly_0007
221 * @tc.desc: get user_version by querySql
222 * @tc.type: FUNC
223 */
224 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0007, TestSize.Level1)
225 {
226 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
227
228 auto resultSet = store->QuerySql("PRAGMA user_version");
229
230 EXPECT_NE(nullptr, resultSet);
231 EXPECT_EQ(E_OK, resultSet->GoToFirstRow());
232
233 int value = 0;
234 // column index is 0
235 EXPECT_EQ(E_OK, resultSet->GetInt(0, value));
236 EXPECT_EQ(1, value);
237
238 EXPECT_EQ(E_OK, resultSet->Close());
239 }
240
241 /**
242 * @tc.name: RdbStore_ReadOnly_0008
243 * @tc.desc: get user_version by execute
244 * @tc.type: FUNC
245 */
246 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0008, TestSize.Level1)
247 {
248 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
249
250 auto [ret, object] = store->Execute("PRAGMA user_version");
251 EXPECT_EQ(E_NOT_SUPPORT, ret);
252
253 std::tie(ret, object) = store->Execute("PRAGMA user_version=2");
254 EXPECT_EQ(E_NOT_SUPPORT, ret);
255 }
256
257 /**
258 * @tc.name: RdbStore_ReadOnly_0009
259 * @tc.desc: query data
260 * @tc.type: FUNC
261 */
262 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0009, TestSize.Level1)
263 {
264 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
265
266 auto resultSet = store->QuerySql("SELECT * FROM test");
267
268 int count = 0;
269 EXPECT_EQ(E_OK, resultSet->GetRowCount(count));
270 // count is 1
271 EXPECT_EQ(1, count);
272
273 EXPECT_EQ(E_OK, resultSet->Close());
274 }
275
276 /**
277 * @tc.name: RdbStore_ReadOnly_0010
278 * @tc.desc: get user_version by executeSql
279 * @tc.type: FUNC
280 */
281 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0010, TestSize.Level1)
282 {
283 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
284
285 auto ret = store->ExecuteSql("PRAGMA user_version");
286 EXPECT_EQ(E_NOT_SUPPORT, ret);
287
288 ret = store->ExecuteSql("SELECT * FROM test");
289 EXPECT_EQ(E_NOT_SUPPORT, ret);
290 }
291
292 /**
293 * @tc.name: RdbStore_ReadOnly_0011
294 * @tc.desc: replace data
295 * @tc.type: FUNC
296 */
297 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0011, TestSize.Level1)
298 {
299 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
300
301 int64_t id;
302 ValuesBucket values;
303 values.PutString("name", "zhangSan");
304 int ret = store->Replace(id, "test", values);
305 EXPECT_EQ(E_NOT_SUPPORT, ret);
306 }
307
308 /**
309 * @tc.name: RdbStore_ReadOnly_0012
310 * @tc.desc: test ExecuteAndGetLong
311 * @tc.type: FUNC
312 */
313 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0012, TestSize.Level1)
314 {
315 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
316
317 int64_t count;
318 int ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
319 EXPECT_EQ(E_OK, ret);
320
321 ret = store->ExecuteAndGetLong(count, "PRAGMA user_version");
322 EXPECT_EQ(E_DATABASE_BUSY, ret);
323 }
324
325 /**
326 * @tc.name: RdbStore_ReadOnly_0013
327 * @tc.desc: test ExecuteAndGetString
328 * @tc.type: FUNC
329 */
330 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0013, TestSize.Level1)
331 {
332 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
333
334 std::string count;
335 int ret = store->ExecuteAndGetString(count, "SELECT COUNT(*) FROM test");
336 EXPECT_EQ(E_OK, ret);
337
338 ret = store->ExecuteAndGetString(count, "PRAGMA user_version");
339 EXPECT_EQ(E_DATABASE_BUSY, ret);
340 }
341
342 /**
343 * @tc.name: RdbStore_ReadOnly_0014
344 * @tc.desc: test ExecuteForLastInsertedRowId
345 * @tc.type: FUNC
346 */
347 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0014, TestSize.Level1)
348 {
349 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
350
351 int64_t outValue;
352 int ret = store->ExecuteForLastInsertedRowId(outValue, "", {});
353 EXPECT_EQ(E_NOT_SUPPORT, ret);
354 }
355
356 /**
357 * @tc.name: RdbStore_ReadOnly_0015
358 * @tc.desc: test ExecuteForChangedRowCount
359 * @tc.type: FUNC
360 */
361 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0015, TestSize.Level1)
362 {
363 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
364
365 int64_t outValue;
366 int ret = store->ExecuteForChangedRowCount(outValue, "", {});
367 EXPECT_EQ(E_NOT_SUPPORT, ret);
368 }
369
370 /**
371 * @tc.name: RdbStore_ReadOnly_0016
372 * @tc.desc: get user_version by GetVersion
373 * @tc.type: FUNC
374 */
375 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0016, TestSize.Level1)
376 {
377 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
378
379 int version = -1;
380 auto ret = store->GetVersion(version);
381 EXPECT_EQ(E_OK, ret);
382 // version is 1
383 EXPECT_EQ(1, version);
384 }
385
386 /**
387 * @tc.name: RdbStore_ReadOnly_0017
388 * @tc.desc: set user_version by SetVersion
389 * @tc.type: FUNC
390 */
391 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0017, TestSize.Level1)
392 {
393 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
394
395 int version = 2;
396 auto ret = store->SetVersion(version);
397 EXPECT_EQ(E_NOT_SUPPORT, ret);
398 }
399
400 /**
401 * @tc.name: RdbStore_ReadOnly_0018
402 * @tc.desc: test vector db
403 * @tc.type: FUNC
404 */
405 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0018, TestSize.Level1)
406 {
407 if (!OHOS::NativeRdb::IsUsingArkData()) {
408 return;
409 }
410 int errCode = E_ERROR;
411 RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME_18);
412 config.SetBundleName("com.example.readOnly.rdb");
413 config.SetReadOnly(true);
414 config.SetIsVector(true);
415 ReadOnlyTestOpenCallback helper;
416 // user_version is 1
417 auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
418 ASSERT_NE(nullptr, store);
419
420 auto [ret, id] = store->BeginTrans();
421 EXPECT_EQ(E_NOT_SUPPORT, ret);
422
423 // id is 1
424 ret = store->Commit(1);
425 EXPECT_EQ(E_NOT_SUPPORT, ret);
426
427 // id is 1
428 ret = store->RollBack(1);
429 EXPECT_EQ(E_NOT_SUPPORT, ret);
430
431 ValueObject obj;
432 // id is 1
433 std::tie(ret, obj) = store->Execute("PRAGMA user_version", {}, 1);
434 EXPECT_EQ(E_NOT_SUPPORT, ret);
435 }
436
437 /**
438 * @tc.name: RdbStore_ReadOnly_0019
439 * @tc.desc: test encrypt db
440 * @tc.type: FUNC
441 */
442 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0019, TestSize.Level1)
443 {
444 int errCode = E_ERROR;
445 RdbStoreConfig config(RdbReadOnlyTest::DATABASE_NAME);
446 config.SetBundleName("com.example.encrypt.rdb");
447 config.SetEncryptStatus(true);
448 ReadOnlyTestOpenCallback helper;
449 // user_version is 1
450 auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
451 EXPECT_NE(nullptr, store);
452
453 RdbHelper::ClearCache();
454
455 RdbStoreConfig config1(RdbReadOnlyTest::DATABASE_NAME);
456 config1.SetBundleName("com.example.encrypt.rdb");
457 config1.SetReadOnly(true);
458 config1.SetEncryptStatus(true);
459 // user_version is 1
460 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
461 EXPECT_NE(nullptr, store);
462
463 EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::DATABASE_NAME));
464 }
465
466 /**
467 * @tc.name: RdbStore_ReadOnly_0020
468 * @tc.desc: test attach and detach
469 * @tc.type: FUNC
470 */
471 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0020, TestSize.Level1)
472 {
473 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
474
475 RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME);
476 auto [ret, size] = store->Attach(config, RdbReadOnlyTest::DATABASE_NAME);
477 EXPECT_EQ(E_NOT_SUPPORT, ret);
478
479 std::tie(ret, size) = store->Detach(RdbReadOnlyTest::DATABASE_NAME);
480 EXPECT_EQ(E_NOT_SUPPORT, ret);
481 }
482
483 /**
484 * @tc.name: RdbStore_ReadOnly_0021
485 * @tc.desc: test SetDistributedTables
486 * @tc.type: FUNC
487 */
488 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0021, TestSize.Level1)
489 {
490 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
491
492 AbsRdbPredicates predicates("test");
493 OHOS::DistributedRdb::DistributedConfig config;
494 // type is 0
495 auto ret = store->SetDistributedTables({}, 0, config);
496 EXPECT_EQ(E_NOT_SUPPORT, ret);
497 }
498
499 /**
500 * @tc.name: RdbStore_ReadOnly_0022
501 * @tc.desc: test CleanDirtyData
502 * @tc.type: FUNC
503 */
504 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0022, TestSize.Level1)
505 {
506 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
507
508 uint64_t cursor = 1;
509 auto ret = store->CleanDirtyData("test", cursor);
510 EXPECT_EQ(E_NOT_SUPPORT, ret);
511 }
512
513 /**
514 * @tc.name: RdbStore_ReadOnly_0023
515 * @tc.desc: test BatchInsertWithConflictResolution
516 * @tc.type: FUNC
517 */
518 HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0023, TestSize.Level1)
519 {
520 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
521
522 ValuesBuckets rows;
523 for (int i = 0; i < 5; i++) {
524 ValuesBucket row;
525 row.Put("name", "Jim");
526 rows.Put(row);
527 }
528 auto ret = store->BatchInsertWithConflictResolution("test", rows, ConflictResolution::ON_CONFLICT_NONE);
529 EXPECT_EQ(E_NOT_SUPPORT, ret.first);
530 ret = store->BatchInsertWithConflictResolution("test", rows, ConflictResolution::ON_CONFLICT_ROLLBACK);
531 EXPECT_EQ(E_NOT_SUPPORT, ret.first);
532 ret = store->BatchInsertWithConflictResolution("test", rows, ConflictResolution::ON_CONFLICT_ABORT);
533 EXPECT_EQ(E_NOT_SUPPORT, ret.first);
534 ret = store->BatchInsertWithConflictResolution("test", rows, ConflictResolution::ON_CONFLICT_FAIL);
535 EXPECT_EQ(E_NOT_SUPPORT, ret.first);
536 ret = store->BatchInsertWithConflictResolution("test", rows, ConflictResolution::ON_CONFLICT_IGNORE);
537 EXPECT_EQ(E_NOT_SUPPORT, ret.first);
538 ret = store->BatchInsertWithConflictResolution("test", rows, ConflictResolution::ON_CONFLICT_REPLACE);
539 EXPECT_EQ(E_NOT_SUPPORT, ret.first);
540 }
541
542 /**
543 * @tc.name: RdbStore_CreateTransaction_001
544 * @tc.desc: test Create Transaction
545 * @tc.type: FUNC
546 */
547 HWTEST_F(RdbReadOnlyTest, RdbStore_CreateTransaction_001, TestSize.Level1)
548 {
549 std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
550 auto [errCode, trans] = store->CreateTransaction(Transaction::DEFERRED);
551 EXPECT_EQ(E_NOT_SUPPORT, errCode);
552 EXPECT_EQ(trans, nullptr);
553
554 std::tie(errCode, trans) = store->CreateTransaction(Transaction::IMMEDIATE);
555 EXPECT_EQ(E_NOT_SUPPORT, errCode);
556 EXPECT_EQ(trans, nullptr);
557
558 std::tie(errCode, trans) = store->CreateTransaction(Transaction::EXCLUSIVE);
559 EXPECT_EQ(E_NOT_SUPPORT, errCode);
560 EXPECT_EQ(trans, nullptr);
561 }
562 }