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 "logger.h"
22 #include "rdb_errno.h"
23 #include "rdb_helper.h"
24 #include "rdb_open_callback.h"
25
26 using namespace testing::ext;
27 using namespace OHOS::NativeRdb;
28
29 class RdbAttachTest : public testing::Test {
30 public:
31 static void SetUpTestCase(void);
32 static void TearDownTestCase(void);
33 void SetUp();
34 void TearDown();
35 void QueryCheck1(std::shared_ptr<RdbStore> &store) const;
36 void QueryCheck2(std::shared_ptr<RdbStore> &store) const;
37
38 static const std::string MAIN_DATABASE_NAME;
39 static const std::string ATTACHED_DATABASE_NAME;
40 };
41
42 const std::string RdbAttachTest::MAIN_DATABASE_NAME = RDB_TEST_PATH + "main.db";
43
44 class MainOpenCallback : public RdbOpenCallback {
45 public:
46 int OnCreate(RdbStore &rdbStore) override;
47 int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override;
48 static const std::string CREATE_TABLE_TEST;
49 };
50
51 std::string const MainOpenCallback::CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test1(id INTEGER PRIMARY KEY "
52 "AUTOINCREMENT, name TEXT NOT NULL)";
53
OnCreate(RdbStore & store)54 int MainOpenCallback::OnCreate(RdbStore &store)
55 {
56 return store.ExecuteSql(CREATE_TABLE_TEST);
57 }
58
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)59 int MainOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
60 {
61 return E_OK;
62 }
63
64 const std::string RdbAttachTest::ATTACHED_DATABASE_NAME = RDB_TEST_PATH + "attached.db";
65
66 class AttachedOpenCallback : public RdbOpenCallback {
67 public:
68 int OnCreate(RdbStore &rdbStore) override;
69 int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override;
70 static const std::string CREATE_TABLE_TEST;
71 };
72
73 std::string const AttachedOpenCallback::CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test2(id INTEGER PRIMARY KEY "
74 "AUTOINCREMENT, name TEXT NOT NULL)";
75
OnCreate(RdbStore & store)76 int AttachedOpenCallback::OnCreate(RdbStore &store)
77 {
78 return store.ExecuteSql(CREATE_TABLE_TEST);
79 }
80
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)81 int AttachedOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
82 {
83 return E_OK;
84 }
85
SetUpTestCase(void)86 void RdbAttachTest::SetUpTestCase(void)
87 {
88 RdbStoreConfig attachedConfig(RdbAttachTest::ATTACHED_DATABASE_NAME);
89 AttachedOpenCallback attachedHelper;
90 int errCode = E_OK;
91 std::shared_ptr<RdbStore> attachedStore = RdbHelper::GetRdbStore(attachedConfig, 1, attachedHelper, errCode);
92 EXPECT_NE(attachedStore, nullptr);
93 }
94
TearDownTestCase(void)95 void RdbAttachTest::TearDownTestCase(void)
96 {
97 RdbHelper::DeleteRdbStore(MAIN_DATABASE_NAME);
98 RdbHelper::DeleteRdbStore(ATTACHED_DATABASE_NAME);
99 }
100
SetUp(void)101 void RdbAttachTest::SetUp(void)
102 {
103 }
104
TearDown(void)105 void RdbAttachTest::TearDown(void)
106 {
107 RdbHelper::ClearCache();
108 }
109
110 /**
111 * @tc.name: RdbStore_Attach_001
112 * @tc.desc: test attach, attach is not supported in wal mode
113 * @tc.type: FUNC
114 * @tc.require: AR000CU2BO
115 * @tc.author: chenxi
116 */
117 HWTEST_F(RdbAttachTest, RdbStore_Attach_001, TestSize.Level1)
118 {
119 RdbStoreConfig config(RdbAttachTest::MAIN_DATABASE_NAME);
120 MainOpenCallback helper;
121 int errCode = E_OK;
122 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
123 EXPECT_NE(store, nullptr);
124
125 int ret = store->ExecuteSql("ATTACH '" + ATTACHED_DATABASE_NAME + "' as attached");
126 EXPECT_EQ(ret, E_NOT_SUPPORTED_ATTACH_IN_WAL_MODE);
127
128 ret = store->ExecuteSql("attach '" + ATTACHED_DATABASE_NAME + "' as attached");
129 EXPECT_EQ(ret, E_NOT_SUPPORTED_ATTACH_IN_WAL_MODE);
130 }
131
132 /**
133 * @tc.name: RdbStore_Attach_002
134 * @tc.desc: test RdbStore attach
135 * @tc.type: FUNC
136 * @tc.require: AR000CU2BO
137 * @tc.author: chenxi
138 */
139 HWTEST_F(RdbAttachTest, RdbStore_Attach_002, TestSize.Level1)
140 {
141 RdbStoreConfig config(RdbAttachTest::MAIN_DATABASE_NAME);
142 config.SetJournalMode(JournalMode::MODE_TRUNCATE);
143 MainOpenCallback helper;
144 int errCode = E_OK;
145 std::shared_ptr<RdbStore> store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
146 EXPECT_NE(store, nullptr);
147
148 int ret = store->ExecuteSql("ATTACH DATABASE '" + ATTACHED_DATABASE_NAME + "' as 'attached'");
149 EXPECT_EQ(ret, E_OK);
150
151 int64_t id;
152 ValuesBucket values;
153 values.PutInt("id", 1);
154 values.PutString("name", std::string("zhangsan"));
155 ret = store->Insert(id, "test1", values);
156 EXPECT_EQ(ret, E_OK);
157 EXPECT_EQ(id, 1);
158
159 values.Clear();
160 values.PutInt("id", 1);
161 values.PutString("name", std::string("lisi"));
162 ret = store->Insert(id, "test2", values);
163 EXPECT_EQ(ret, E_OK);
164 EXPECT_EQ(id, 1);
165
166 QueryCheck1(store);
167
168 ret = store->ExecuteSql("DETACH DATABASE 'attached'");
169 EXPECT_EQ(ret, E_OK);
170
171 QueryCheck2(store);
172
173 ret = store->ExecuteSql("attach database '" + ATTACHED_DATABASE_NAME + "' as 'attached'");
174 EXPECT_EQ(ret, E_OK);
175
176 ret = store->ExecuteSql("detach database 'attached'");
177 EXPECT_EQ(ret, E_OK);
178 }
179
QueryCheck1(std::shared_ptr<RdbStore> & store) const180 void RdbAttachTest::QueryCheck1(std::shared_ptr<RdbStore> &store) const
181 {
182 std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test1");
183 EXPECT_NE(resultSet, nullptr);
184 int ret = resultSet->GoToNextRow();
185 EXPECT_EQ(ret, E_OK);
186 int columnIndex;
187 int intVal;
188 ret = resultSet->GetColumnIndex("id", columnIndex);
189 EXPECT_EQ(ret, E_OK);
190 ret = resultSet->GetInt(columnIndex, intVal);
191 EXPECT_EQ(ret, E_OK);
192 EXPECT_EQ(intVal, 1);
193 std::string strVal;
194 ret = resultSet->GetColumnIndex("name", columnIndex);
195 EXPECT_EQ(ret, E_OK);
196 ret = resultSet->GetString(columnIndex, strVal);
197 EXPECT_EQ(ret, E_OK);
198 EXPECT_EQ(strVal, "zhangsan");
199
200 resultSet = store->QuerySql("SELECT * FROM test2");
201 EXPECT_NE(resultSet, nullptr);
202 ret = resultSet->GoToNextRow();
203 EXPECT_EQ(ret, E_OK);
204 ret = resultSet->GetColumnIndex("id", columnIndex);
205 EXPECT_EQ(ret, E_OK);
206 ret = resultSet->GetInt(columnIndex, intVal);
207 EXPECT_EQ(ret, E_OK);
208 EXPECT_EQ(intVal, 1);
209 ret = resultSet->GetColumnIndex("name", columnIndex);
210 EXPECT_EQ(ret, E_OK);
211 ret = resultSet->GetString(columnIndex, strVal);
212 EXPECT_EQ(ret, E_OK);
213 EXPECT_EQ(strVal, "lisi");
214 }
215
QueryCheck2(std::shared_ptr<RdbStore> & store) const216 void RdbAttachTest::QueryCheck2(std::shared_ptr<RdbStore> &store) const
217 {
218 std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM test1");
219 EXPECT_NE(resultSet, nullptr);
220 int ret = resultSet->GoToNextRow();
221 EXPECT_EQ(ret, E_OK);
222 int columnIndex;
223 int intVal;
224 ret = resultSet->GetColumnIndex("id", columnIndex);
225 EXPECT_EQ(ret, E_OK);
226 ret = resultSet->GetInt(columnIndex, intVal);
227 EXPECT_EQ(ret, E_OK);
228 EXPECT_EQ(intVal, 1);
229 std::string strVal;
230 ret = resultSet->GetColumnIndex("name", columnIndex);
231 EXPECT_EQ(ret, E_OK);
232 ret = resultSet->GetString(columnIndex, strVal);
233 EXPECT_EQ(ret, E_OK);
234 EXPECT_EQ(strVal, "zhangsan");
235
236 // detached, no table test2
237 resultSet = store->QuerySql("SELECT * FROM test2");
238 EXPECT_NE(resultSet, nullptr);
239 }