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