• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }