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 }