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 #define LOG_TAG "RdbOpenCallbackTest"
16 #include "rdb_open_callback.h"
17 
18 #include <gtest/gtest.h>
19 
20 #include <string>
21 
22 #include "common.h"
23 #include "logger.h"
24 #include "rdb_errno.h"
25 #include "rdb_helper.h"
26 
27 using namespace testing::ext;
28 using namespace OHOS::Rdb;
29 using namespace OHOS::NativeRdb;
30 
31 class RdbOpenCallbackTest : public testing::Test {
32 public:
33     static void SetUpTestCase(void);
34     static void TearDownTestCase(void);
35     void SetUp();
36     void TearDown();
37 
38     static const std::string DATABASE_NAME;
39 };
40 
41 const std::string RdbOpenCallbackTest::DATABASE_NAME = RDB_TEST_PATH + "open_helper.db";
42 
SetUpTestCase(void)43 void RdbOpenCallbackTest::SetUpTestCase(void)
44 {
45 }
46 
TearDownTestCase(void)47 void RdbOpenCallbackTest::TearDownTestCase(void)
48 {
49     RdbHelper::DeleteRdbStore(RdbOpenCallbackTest::DATABASE_NAME);
50 }
51 
SetUp(void)52 void RdbOpenCallbackTest::SetUp(void)
53 {
54 }
55 
TearDown(void)56 void RdbOpenCallbackTest::TearDown(void)
57 {
58     RdbHelper::ClearCache();
59 }
60 
61 class OpenCallbackA : public RdbOpenCallback {
62 public:
63     int OnCreate(RdbStore &store) override;
64     int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
65     int OnDowngrade(RdbStore &store, int oldVersion, int newVersion) override;
66     int OnOpen(RdbStore &store) override;
67     int onCorruption(std::string databaseFile) override;
68 
69     static std::string CreateTableSQL(const std::string &tableName);
70     static std::string DropTableSQL(const std::string &tableName);
71 };
72 
CreateTableSQL(const std::string & tableName)73 std::string OpenCallbackA::CreateTableSQL(const std::string &tableName)
74 {
75     return "CREATE TABLE IF NOT EXISTS " + tableName +
76            " (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)";
77 }
78 
DropTableSQL(const std::string & tableName)79 std::string OpenCallbackA::DropTableSQL(const std::string &tableName)
80 {
81     return "DROP TABLE IF EXISTS " + tableName + ";";
82 }
83 
OnCreate(RdbStore & store)84 int OpenCallbackA::OnCreate(RdbStore &store)
85 {
86     return store.ExecuteSql(CreateTableSQL("test1"));
87 }
88 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)89 int OpenCallbackA::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
90 {
91     LOG_INFO("RdbOpenCallbackTest onUpgrade begin.");
92     if (oldVersion < newVersion) {
93         if (oldVersion <= 1) {
94             return store.ExecuteSql(CreateTableSQL("test2"));
95         }
96     }
97     return E_OK;
98 }
99 
OnDowngrade(RdbStore & store,int oldVersion,int newVersion)100 int OpenCallbackA::OnDowngrade(RdbStore &store, int oldVersion, int newVersion)
101 {
102     LOG_INFO("RdbOpenCallbackTest OnDowngrade begin");
103     if (oldVersion > newVersion) {
104         if (oldVersion >= 2) {
105             return store.ExecuteSql(DropTableSQL("test2"));
106         }
107     }
108     return E_OK;
109 }
110 
OnOpen(RdbStore & store)111 int OpenCallbackA::OnOpen(RdbStore &store)
112 {
113     int64_t id;
114     ValuesBucket values;
115 
116     values.PutInt("id", 1);
117     values.PutString("name", std::string("zhangsan"));
118     values.PutInt("age", 18);
119     int errCode = store.Replace(id, "test1", values);
120     if (errCode != E_OK) {
121         return errCode;
122     }
123 
124     values.Clear();
125     values.PutInt("id", 2);
126     values.PutString("name", std::string("lisi"));
127     values.PutInt("age", 18);
128     errCode = store.Replace(id, "test1", values);
129     if (errCode != E_OK) {
130         return errCode;
131     }
132 
133     return E_OK;
134 }
135 
onCorruption(std::string databaseFile)136 int OpenCallbackA::onCorruption(std::string databaseFile)
137 {
138     int errCode = RdbHelper::DeleteRdbStore(RdbOpenCallbackTest::DATABASE_NAME);
139     if (errCode != E_OK) {
140         return errCode;
141     }
142     return E_OK;
143 }
144 
145 /**
146  * @tc.name: RdbOpenCallback_01
147  * @tc.desc: test RdbOpenCallback
148  * @tc.type: FUNC
149  */
150 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_01, TestSize.Level1)
151 {
152     RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
153     OpenCallbackA helper;
154 
155     int errCode = E_OK;
156     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
157     EXPECT_NE(store, nullptr);
158     EXPECT_EQ(errCode, E_OK);
159 
160     int currentVersion;
161     int ret = store->GetVersion(currentVersion);
162     EXPECT_EQ(ret, E_OK);
163     EXPECT_EQ(currentVersion, 1);
164 
165     int64_t id;
166     int changedRows;
167     ValuesBucket values;
168 
169     values.PutInt("id", 3);
170     values.PutString("name", std::string("lisi"));
171     values.PutInt("age", 20);
172     ret = store->Replace(id, "test1", values);
173     EXPECT_EQ(ret, E_OK);
174     EXPECT_EQ(3, id);
175 
176     values.Clear();
177     values.PutInt("age", 20);
178     ret = store->Update(changedRows, "test1", values, "age = ?", std::vector<std::string>{ "18" });
179     EXPECT_EQ(ret, E_OK);
180     EXPECT_EQ(2, changedRows);
181 
182     ret = store->Delete(changedRows, "test1", "age = ?", std::vector<std::string>{ "20" });
183     EXPECT_EQ(ret, E_OK);
184     EXPECT_EQ(3, changedRows);
185 }
186 
187 /**
188  * @tc.name: RdbOpenCallback_02
189  * @tc.desc: test RdbOpenCallback
190  * @tc.type: FUNC
191  */
192 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_02, TestSize.Level1)
193 {
194     int errCode = E_OK;
195     RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
196     OpenCallbackA helper;
197     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 2, helper, errCode);
198     EXPECT_NE(store, nullptr);
199 
200     int currentVersion;
201     int ret = store->GetVersion(currentVersion);
202     EXPECT_EQ(ret, E_OK);
203     EXPECT_EQ(currentVersion, 2);
204 
205     int64_t id;
206     int changedRows;
207     ValuesBucket values;
208 
209     values.PutInt("id", 1);
210     values.PutString("name", std::string("zhangsan"));
211     values.PutInt("age", 18);
212     ret = store->Insert(id, "test2", values);
213     EXPECT_EQ(ret, E_OK);
214     EXPECT_EQ(1, id);
215 
216     values.Clear();
217     values.PutInt("id", 2);
218     values.PutString("name", std::string("lisi"));
219     values.PutInt("age", 18);
220     ret = store->Insert(id, "test2", values);
221     EXPECT_EQ(ret, E_OK);
222     EXPECT_EQ(2, id);
223 
224     values.Clear();
225     values.PutInt("id", 3L);
226     values.PutString("name", std::string("lisi"));
227     values.PutInt("age", 20);
228     ret = store->Insert(id, "test2", values);
229     EXPECT_EQ(ret, E_OK);
230     EXPECT_EQ(3, id);
231 
232     values.Clear();
233     values.PutInt("age", 20);
234     ret = store->Update(changedRows, "test2", values, "age = ?", std::vector<std::string>{ "18" });
235     EXPECT_EQ(ret, E_OK);
236     EXPECT_EQ(2, changedRows);
237 
238     ret = store->Delete(changedRows, "test2", "age = ?", std::vector<std::string>{ "20" });
239     EXPECT_EQ(ret, E_OK);
240     EXPECT_EQ(3, changedRows);
241 }
242 
243 /**
244  * @tc.name: RdbOpenCallback_03
245  * @tc.desc: test RdbOpenCallback
246  * @tc.type: FUNC
247  */
248 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_03, TestSize.Level1)
249 {
250     int errCode = E_OK;
251     RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
252     OpenCallbackA helper;
253     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
254     EXPECT_NE(store, nullptr);
255 
256     int currentVersion;
257     int ret = store->GetVersion(currentVersion);
258     EXPECT_EQ(ret, E_OK);
259     EXPECT_EQ(currentVersion, 1);
260 
261     int64_t id;
262     ValuesBucket values;
263 
264     values.PutInt("id", 1);
265     values.PutString("name", std::string("zhangsan"));
266     values.PutInt("age", 18);
267     ret = store->Insert(id, "test2", values);
268     EXPECT_NE(ret, E_OK);
269 }
270 
271 class OpenCallbackB : public RdbOpenCallback {
272 public:
273     int OnCreate(RdbStore &store) override;
274     int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
275 
276     static std::string CreateTableSQL(const std::string &tableName);
277     static std::string DropTableSQL(const std::string &tableName);
278 };
279 
CreateTableSQL(const std::string & tableName)280 std::string OpenCallbackB::CreateTableSQL(const std::string &tableName)
281 {
282     return "CREATE TABLE IF NOT EXISTS " + tableName +
283            " (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)";
284 }
285 
DropTableSQL(const std::string & tableName)286 std::string OpenCallbackB::DropTableSQL(const std::string &tableName)
287 {
288     return "DROP TABLE IF EXISTS " + tableName + ";";
289 }
290 
OnCreate(RdbStore & store)291 int OpenCallbackB::OnCreate(RdbStore &store)
292 {
293     return store.ExecuteSql(CreateTableSQL("test1"));
294 }
295 
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)296 int OpenCallbackB::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
297 {
298     if (oldVersion < newVersion) {
299         if (oldVersion <= 1) {
300             return store.ExecuteSql(CreateTableSQL("test2"));
301         }
302     }
303     return E_OK;
304 }
305 
306 /**
307  * @tc.name: RdbOpenCallback_04
308  * @tc.desc: test RdbOpenCallback
309  * @tc.type: FUNC
310  */
311 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_04, TestSize.Level1)
312 {
313     int errCode = E_OK;
314     RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
315     OpenCallbackB helper;
316     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 2, helper, errCode);
317     EXPECT_NE(store, nullptr);
318 
319     int currentVersion;
320     int ret = store->GetVersion(currentVersion);
321     EXPECT_EQ(ret, E_OK);
322     EXPECT_EQ(currentVersion, 2);
323 
324     int64_t id;
325     int changedRows;
326     ValuesBucket values;
327 
328     values.PutInt("id", 1);
329     values.PutString("name", std::string("zhangsan"));
330     values.PutInt("age", 18);
331     ret = store->Insert(id, "test2", values);
332     EXPECT_EQ(ret, E_OK);
333     EXPECT_EQ(1, id);
334 
335     values.Clear();
336     values.PutInt("id", 2);
337     values.PutString("name", std::string("lisi"));
338     values.PutInt("age", 18);
339     ret = store->Insert(id, "test2", values);
340     EXPECT_EQ(ret, E_OK);
341     EXPECT_EQ(2, id);
342 
343     values.Clear();
344     values.PutInt("id", 3L);
345     values.PutString("name", std::string("lisi"));
346     values.PutInt("age", 20);
347     ret = store->Insert(id, "test2", values);
348     EXPECT_EQ(ret, E_OK);
349     EXPECT_EQ(3, id);
350 
351     values.Clear();
352     values.PutInt("age", 20);
353     ret = store->Update(changedRows, "test2", values, "age = ?", std::vector<std::string>{ "18" });
354     EXPECT_EQ(ret, E_OK);
355     EXPECT_EQ(2, changedRows);
356 
357     ret = store->Delete(changedRows, "test2", "age = ?", std::vector<std::string>{ "20" });
358     EXPECT_EQ(ret, E_OK);
359     EXPECT_EQ(3, changedRows);
360 }
361 
362 /**
363  * @tc.name: RdbOpenCallback_05
364  * @tc.desc: test RdbOpenCallback
365  * @tc.type: FUNC
366  */
367 HWTEST_F(RdbOpenCallbackTest, RdbOpenCallback_05, TestSize.Level1)
368 {
369     int errCode = E_OK;
370     RdbStoreConfig config(RdbOpenCallbackTest::DATABASE_NAME);
371     OpenCallbackB helper;
372     std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
373     EXPECT_NE(store, nullptr);
374 
375     int currentVersion;
376     int ret = store->GetVersion(currentVersion);
377     EXPECT_EQ(ret, E_OK);
378     EXPECT_EQ(currentVersion, 1);
379 
380     int64_t id;
381     ValuesBucket values;
382     values.PutInt("id", 1);
383     values.PutString("name", std::string("zhangsan"));
384     values.PutInt("age", 18);
385     ret = store->Insert(id, "test2", values);
386     EXPECT_EQ(ret, E_OK);
387 
388     ret = helper.OnDowngrade(*store, 2, 1);
389     EXPECT_EQ(ret, E_OK);
390 
391     ret = helper.OnOpen(*store);
392     EXPECT_EQ(ret, E_OK);
393 }
394