1 /*
2 * Copyright (c) 2024 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 "RdConnection"
16 #include "rd_connection.h"
17
18 #include "logger.h"
19 #include "rd_statement.h"
20 #include "rdb_errno.h"
21 #include "sqlite_global_config.h"
22 namespace OHOS {
23 namespace NativeRdb {
24 using namespace OHOS::Rdb;
25 __attribute__((used))
26 const int32_t RdConnection::regCreator_ = Connection::RegisterCreator(DB_VECTOR, RdConnection::Create);
27 __attribute__((used))
28 const int32_t RdConnection::regRepairer_ = Connection::RegisterRepairer(DB_VECTOR, RdConnection::Repair);
29 __attribute__((used))
30 const int32_t RdConnection::regDeleter_ = Connection::RegisterDeleter(DB_VECTOR, RdConnection::Delete);
31
Create(const RdbStoreConfig & config,bool isWrite)32 std::pair<int32_t, std::shared_ptr<Connection>> RdConnection::Create(const RdbStoreConfig& config, bool isWrite)
33 {
34 std::pair<int32_t, std::shared_ptr<Connection>> result;
35 auto& [errCode, conn] = result;
36 for (size_t i = 0; i < ITERS_COUNT; i++) {
37 std::shared_ptr<RdConnection> connection = std::make_shared<RdConnection>(config, isWrite);
38 if (connection == nullptr) {
39 LOG_ERROR("SqliteConnection::Open new failed, connection is nullptr.");
40 return result;
41 }
42 errCode = connection->InnerOpen(config);
43 if (errCode == E_OK) {
44 conn = connection;
45 break;
46 }
47 }
48 return result;
49 }
50
Repair(const RdbStoreConfig & config)51 int32_t RdConnection::Repair(const RdbStoreConfig& config)
52 {
53 std::string dbPath = "";
54 auto errCode = SqliteGlobalConfig::GetDbPath(config, dbPath);
55 if (errCode != E_OK) {
56 LOG_ERROR("Can not get db path.");
57 return errCode;
58 }
59 errCode = RdUtils::RdDbRepair(dbPath.c_str(), GRD_OPEN_CONFIG_STR);
60 if (errCode != E_OK) {
61 LOG_ERROR("Fail to repair db.");
62 }
63 return errCode;
64 }
65
66 static constexpr const char *RD_POST_FIXES[] = {
67 "",
68 ".redo",
69 ".undo",
70 ".ctrl",
71 ".ctrl.dwr",
72 ".safe",
73 ".map",
74 ".corruptedflg",
75 };
76
Delete(const RdbStoreConfig & config)77 int32_t RdConnection::Delete(const RdbStoreConfig &config)
78 {
79 auto path = config.GetPath();
80 for (auto postFix : RD_POST_FIXES) {
81 std::string shmFilePath = path + postFix;
82 if (access(shmFilePath.c_str(), F_OK) == 0) {
83 remove(shmFilePath.c_str());
84 }
85 }
86 return E_OK;
87 }
88
RdConnection(const RdbStoreConfig & config,bool isWriter)89 RdConnection::RdConnection(const RdbStoreConfig &config, bool isWriter) : isWriter_(isWriter), config_(config)
90 {
91 }
92
~RdConnection()93 RdConnection::~RdConnection()
94 {
95 if (dbHandle_ != nullptr) {
96 int errCode = RdUtils::RdDbClose(dbHandle_, 0);
97 if (errCode != E_OK) {
98 LOG_ERROR("~RdConnection ~RdConnection: could not close database err = %{public}d", errCode);
99 }
100 dbHandle_ = nullptr;
101 }
102 }
103
InnerOpen(const RdbStoreConfig & config)104 int RdConnection::InnerOpen(const RdbStoreConfig &config)
105 {
106 std::string dbPath = "";
107 auto errCode = SqliteGlobalConfig::GetDbPath(config, dbPath);
108 if (errCode != E_OK) {
109 LOG_ERROR("Can not get db path.");
110 return errCode;
111 }
112 errCode = RdUtils::RdDbOpen(dbPath.c_str(), configStr_.c_str(), GRD_DB_OPEN_CREATE, &dbHandle_);
113 if (errCode != E_OK) {
114 LOG_ERROR("Can not open rd db.");
115 return errCode;
116 }
117 return errCode;
118 }
119
OnInitialize()120 int32_t RdConnection::OnInitialize()
121 {
122 return E_NOT_SUPPORT;
123 }
124
CreateStatement(const std::string & sql,Connection::SConn conn)125 std::pair<int32_t, RdConnection::Stmt> RdConnection::CreateStatement(const std::string& sql, Connection::SConn conn)
126 {
127 auto stmt = std::make_shared<RdStatement>();
128 stmt->conn_ = conn;
129 stmt->config_ = &config_;
130 stmt->setPragmas_["user_version"] = ([this](const int &value) -> int32_t {
131 return RdUtils::RdDbSetVersion(dbHandle_, GRD_CONFIG_USER_VERSION, value);
132 });
133 stmt->getPragmas_["user_version"] = ([this](int &version) -> int32_t {
134 return RdUtils::RdDbGetVersion(dbHandle_, GRD_CONFIG_USER_VERSION, version);
135 });
136 int32_t ret = stmt->Prepare(dbHandle_, sql);
137 if (ret != E_OK) {
138 return { ret, nullptr };
139 }
140 return { ret, stmt };
141 }
142
GetDBType() const143 int32_t RdConnection::GetDBType() const
144 {
145 return DB_VECTOR;
146 }
147
IsWriter() const148 bool RdConnection::IsWriter() const
149 {
150 return isWriter_;
151 }
152
ReSetKey(const RdbStoreConfig & config)153 int32_t RdConnection::ReSetKey(const RdbStoreConfig& config)
154 {
155 return E_NOT_SUPPORT;
156 }
157
TryCheckPoint(bool timeout)158 int32_t RdConnection::TryCheckPoint(bool timeout)
159 {
160 return E_NOT_SUPPORT;
161 }
162
LimitWalSize()163 int32_t RdConnection::LimitWalSize()
164 {
165 return E_NOT_SUPPORT;
166 }
167
ConfigLocale(const std::string & localeStr)168 int32_t RdConnection::ConfigLocale(const std::string& localeStr)
169 {
170 return E_NOT_SUPPORT;
171 }
172
CleanDirtyData(const std::string & table,uint64_t cursor)173 int32_t RdConnection::CleanDirtyData(const std::string& table, uint64_t cursor)
174 {
175 return E_NOT_SUPPORT;
176 }
177
SubscribeTableChanges(const Connection::Notifier & notifier)178 int32_t RdConnection::SubscribeTableChanges(const Connection::Notifier& notifier)
179 {
180 return E_NOT_SUPPORT;
181 }
182
GetMaxVariable() const183 int32_t RdConnection::GetMaxVariable() const
184 {
185 return MAX_VARIABLE_NUM;
186 }
187
GetJournalMode()188 int32_t RdConnection::GetJournalMode()
189 {
190 return E_NOT_SUPPORT;
191 }
192
ClearCache()193 int32_t RdConnection::ClearCache()
194 {
195 return E_NOT_SUPPORT;
196 }
197
Subscribe(const std::string & event,const std::shared_ptr<DistributedRdb::RdbStoreObserver> & observer)198 int32_t RdConnection::Subscribe(const std::string& event,
199 const std::shared_ptr<DistributedRdb::RdbStoreObserver>& observer)
200 {
201 return E_NOT_SUPPORT;
202 }
203
Unsubscribe(const std::string & event,const std::shared_ptr<DistributedRdb::RdbStoreObserver> & observer)204 int32_t RdConnection::Unsubscribe(const std::string& event,
205 const std::shared_ptr<DistributedRdb::RdbStoreObserver>& observer)
206 {
207 return E_NOT_SUPPORT;
208 }
209
Backup(const std::string & databasePath,const std::vector<uint8_t> & destEncryptKey,bool isAsync,SlaveStatus & slaveStatus)210 int32_t RdConnection::Backup(const std::string &databasePath, const std::vector<uint8_t> &destEncryptKey,
211 bool isAsync, SlaveStatus &slaveStatus)
212 {
213 uint32_t size = destEncryptKey.size();
214 if (size != 0) {
215 return RdUtils::RdDbBackup(dbHandle_, databasePath.c_str(), const_cast<uint8_t*>(&destEncryptKey[0]), size);
216 }
217 return RdUtils::RdDbBackup(dbHandle_, databasePath.c_str(), nullptr, 0);
218 }
219
Restore(const std::string & databasePath,const std::vector<uint8_t> & destEncryptKey,SlaveStatus & slaveStatus)220 int32_t RdConnection::Restore(const std::string &databasePath, const std::vector<uint8_t> &destEncryptKey,
221 SlaveStatus &slaveStatus)
222 {
223 uint32_t size = destEncryptKey.size();
224 if (size != 0) {
225 return RdUtils::RdDbRestore(dbHandle_, databasePath.c_str(), const_cast<uint8_t*>(&destEncryptKey[0]), size);
226 }
227 return RdUtils::RdDbRestore(dbHandle_, databasePath.c_str(), nullptr, 0);
228 }
229
GenerateExchangeStrategy(const SlaveStatus & status)230 ExchangeStrategy RdConnection::GenerateExchangeStrategy(const SlaveStatus &status)
231 {
232 return ExchangeStrategy::NOT_HANDLE;
233 }
234 } // namespace NativeRdb
235 } // namespace OHOS