1 /*
2  * Copyright (c) 2023 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 "sqlite_helper.h"
17 #include "sandbox_manager_log.h"
18 
19 namespace OHOS {
20 namespace AccessControl {
21 namespace SandboxManager {
22 namespace {
23 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, ACCESSCONTROL_DOMAIN_SANDBOXMANAGER, "SqliteHelper"};
24 }
25 
SqliteHelper(const std::string & dbName,const std::string & dbPath,int32_t version)26 SqliteHelper::SqliteHelper(const std::string &dbName, const std::string &dbPath, int32_t version)
27     : dbName_(dbName), dbPath_(dbPath), currentVersion_(version), db_(nullptr)
28 {}
29 
~SqliteHelper()30 SqliteHelper::~SqliteHelper()
31 {}
32 
Open()33 void SqliteHelper::Open()
34 {
35     if (db_ != nullptr) {
36         SANDBOXMANAGER_LOG_WARN(LABEL, "db s already open");
37         return;
38     }
39     if (dbName_.empty() || dbPath_.empty() || currentVersion_ < 0) {
40         SANDBOXMANAGER_LOG_ERROR(LABEL, "param invalid, dbName: %{public}s, "
41             "dbPath: %{private}s, currentVersion: %{public}d",
42             dbName_.c_str(), dbPath_.c_str(), currentVersion_);
43         return;
44     }
45     std::string fileName = dbPath_ + dbName_;
46     int32_t res = sqlite3_open(fileName.c_str(), &db_);
47     if (res != SQLITE_OK) {
48         SANDBOXMANAGER_LOG_ERROR(LABEL, "Failed to open db: %{public}s", sqlite3_errmsg(db_));
49         return;
50     }
51 
52     int32_t version = GetVersion();
53     if (version == currentVersion_) {
54         return;
55     }
56 
57     BeginTransaction();
58     if (version == 0) {
59         OnCreate();
60     } else {
61         if (version < currentVersion_) {
62             OnUpdate();
63         }
64     }
65     SetVersion();
66     CommitTransaction();
67 }
68 
Close()69 void SqliteHelper::Close()
70 {
71     if (db_ == nullptr) {
72         SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
73         return;
74     }
75     int32_t ret = sqlite3_close(db_);
76     if (ret != SQLITE_OK) {
77         SANDBOXMANAGER_LOG_WARN(LABEL, "sqlite3_close error, ret=%{public}d", ret);
78         return;
79     }
80     db_ = nullptr;
81 }
82 
BeginTransaction() const83 int32_t SqliteHelper::BeginTransaction() const
84 {
85     if (db_ == nullptr) {
86         SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
87         return GENERAL_ERROR;
88     }
89     char* errorMessage = nullptr;
90     int32_t result = 0;
91     int32_t ret = sqlite3_exec(db_, "BEGIN;", nullptr, nullptr, &errorMessage);
92     if (ret != SQLITE_OK) {
93         SANDBOXMANAGER_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage);
94         result = GENERAL_ERROR;
95     }
96     sqlite3_free(errorMessage);
97     return result;
98 }
99 
CommitTransaction() const100 int32_t SqliteHelper::CommitTransaction() const
101 {
102     if (db_ == nullptr) {
103         SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
104         return GENERAL_ERROR;
105     }
106     char* errorMessage = nullptr;
107     int32_t result = 0;
108     int32_t ret = sqlite3_exec(db_, "COMMIT;", nullptr, nullptr, &errorMessage);
109     if (ret != SQLITE_OK) {
110         SANDBOXMANAGER_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage);
111         result = GENERAL_ERROR;
112     }
113     sqlite3_free(errorMessage);
114     return result;
115 }
116 
RollbackTransaction() const117 int32_t SqliteHelper::RollbackTransaction() const
118 {
119     if (db_ == nullptr) {
120         SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
121         return GENERAL_ERROR;
122     }
123     int32_t result = 0;
124     char* errorMessage = nullptr;
125     int32_t ret = sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, &errorMessage);
126     if (ret != SQLITE_OK) {
127         SANDBOXMANAGER_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage);
128         result = GENERAL_ERROR;
129     }
130     sqlite3_free(errorMessage);
131     return result;
132 }
133 
Prepare(const std::string & sql) const134 Statement SqliteHelper::Prepare(const std::string &sql) const
135 {
136     return Statement(db_, sql);
137 }
138 
ExecuteSql(const std::string & sql) const139 int32_t SqliteHelper::ExecuteSql(const std::string &sql) const
140 {
141     if (db_ == nullptr) {
142         SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
143         return GENERAL_ERROR;
144     }
145     char* errorMessage = nullptr;
146     int32_t result = 0;
147     int32_t res = sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, &errorMessage);
148     if (res != SQLITE_OK) {
149         SANDBOXMANAGER_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", errorMessage);
150         result = GENERAL_ERROR;
151     }
152     sqlite3_free(errorMessage);
153     return result;
154 }
155 
GetVersion() const156 int32_t SqliteHelper::GetVersion() const
157 {
158     if (db_ == nullptr) {
159         SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
160         return GENERAL_ERROR;
161     }
162     auto statement = Prepare(PRAGMA_VERSION_COMMAND);
163     int32_t version = 0;
164     while (statement.Step() == Statement::State::ROW) {
165         version = statement.GetColumnInt(0);
166     }
167     SANDBOXMANAGER_LOG_INFO(LABEL, "version: %{public}d", version);
168     return version;
169 }
170 
SetVersion() const171 void SqliteHelper::SetVersion() const
172 {
173     if (db_ == nullptr) {
174         SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
175         return;
176     }
177     auto statement = Prepare(PRAGMA_VERSION_COMMAND + " = " + std::to_string(currentVersion_));
178     statement.Step();
179 }
180 
SpitError() const181 std::string SqliteHelper::SpitError() const
182 {
183     if (db_ == nullptr) {
184         SANDBOXMANAGER_LOG_WARN(LABEL, "do open data base first!");
185         return "";
186     }
187     return sqlite3_errmsg(db_);
188 }
189 } // namespace SandboxManager
190 } // namespace AccessControl
191 } // namespace OHOS
192