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