• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 
18 #include "accesstoken_common_log.h"
19 #include "sqlite3ext.h"
20 #include <sys/types.h>
21 
22 namespace OHOS {
23 namespace Security {
24 namespace AccessToken {
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() __attribute__((no_sanitize("cfi")))
34 {
35     if (db_ != nullptr) {
36         LOGW(ATM_DOMAIN, ATM_TAG, "Db s already open");
37         return;
38     }
39     if (dbName_.empty() || dbPath_.empty() || currentVersion_ < 0) {
40         LOGE(ATM_DOMAIN, ATM_TAG, "Param invalid, dbName: %{public}s, dbPath: %{public}s, currentVersion: %{public}d",
41             dbName_.c_str(), dbPath_.c_str(), currentVersion_);
42         return;
43     }
44     // set soft heap limit as 10KB
45     const int32_t heapLimit = 10 * 1024;
46     sqlite3_soft_heap_limit64(heapLimit);
47     std::string fileName = dbPath_ + dbName_;
48     int32_t res = sqlite3_open(fileName.c_str(), &db_);
49     if (res != SQLITE_OK) {
50         LOGE(ATM_DOMAIN, ATM_TAG, "Failed to open db: %{public}s", sqlite3_errmsg(db_));
51         return;
52     }
53 
54     SetWal();
55 
56     int32_t version = GetVersion();
57     if (version == currentVersion_) {
58         return;
59     }
60 
61     BeginTransaction();
62     if (version == DataBaseVersion::VERISION_0) {
63         OnCreate();
64     } else {
65         if (version < currentVersion_) {
66             OnUpdate(version);
67         }
68     }
69     SetVersion();
70     CommitTransaction();
71 }
72 
Close()73 void SqliteHelper::Close()
74 {
75     if (db_ == nullptr) {
76         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
77         return;
78     }
79     int32_t ret = sqlite3_close(db_);
80     if (ret != SQLITE_OK) {
81         LOGW(ATM_DOMAIN, ATM_TAG, "Sqlite3_close error, ret=%{public}d", ret);
82         return;
83     }
84     db_ = nullptr;
85 }
86 
BeginTransaction() const87 int32_t SqliteHelper::BeginTransaction() const
88 {
89     if (db_ == nullptr) {
90         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
91         return GENERAL_ERROR;
92     }
93     char* errorMessage = nullptr;
94     int32_t result = 0;
95     int32_t ret = sqlite3_exec(db_, "BEGIN;", nullptr, nullptr, &errorMessage);
96     if (ret != SQLITE_OK) {
97         LOGE(ATM_DOMAIN, ATM_TAG, "Failed, errorMsg: %{public}s", errorMessage);
98         result = GENERAL_ERROR;
99     }
100     sqlite3_free(errorMessage);
101     return result;
102 }
103 
CommitTransaction() const104 int32_t SqliteHelper::CommitTransaction() const
105 {
106     if (db_ == nullptr) {
107         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
108         return GENERAL_ERROR;
109     }
110     char* errorMessage = nullptr;
111     int32_t result = 0;
112     int32_t ret = sqlite3_exec(db_, "COMMIT;", nullptr, nullptr, &errorMessage);
113     if (ret != SQLITE_OK) {
114         LOGE(ATM_DOMAIN, ATM_TAG, "Failed, errorMsg: %{public}s", errorMessage);
115         result = GENERAL_ERROR;
116     }
117     sqlite3_free(errorMessage);
118     sqlite3_db_cacheflush(db_);
119     return result;
120 }
121 
RollbackTransaction() const122 int32_t SqliteHelper::RollbackTransaction() const
123 {
124     if (db_ == nullptr) {
125         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
126         return GENERAL_ERROR;
127     }
128     int32_t result = 0;
129     char* errorMessage = nullptr;
130     int32_t ret = sqlite3_exec(db_, "ROLLBACK;", nullptr, nullptr, &errorMessage);
131     if (ret != SQLITE_OK) {
132         LOGE(ATM_DOMAIN, ATM_TAG, "Failed, errorMsg: %{public}s", errorMessage);
133         result = GENERAL_ERROR;
134     }
135     sqlite3_free(errorMessage);
136     return result;
137 }
138 
Prepare(const std::string & sql) const139 Statement SqliteHelper::Prepare(const std::string& sql) const
140 {
141     return Statement(db_, sql);
142 }
143 
ExecuteSql(const std::string & sql) const144 int32_t SqliteHelper::ExecuteSql(const std::string& sql) const
145 {
146     if (db_ == nullptr) {
147         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
148         return GENERAL_ERROR;
149     }
150     char* errorMessage = nullptr;
151     int32_t result = 0;
152     int32_t res = sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, &errorMessage);
153     if (res != SQLITE_OK) {
154         LOGE(ATM_DOMAIN, ATM_TAG, "Failed, errorMsg: %{public}s", errorMessage);
155         result = GENERAL_ERROR;
156     }
157     sqlite3_free(errorMessage);
158     return result;
159 }
160 
SetWal() const161 void SqliteHelper::SetWal() const
162 {
163     if (db_ == nullptr) {
164         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
165         return;
166     }
167     auto statement = Prepare(PRAGMA_WAL_COMMAND);
168     if (statement.Step() != Statement::State::DONE) {
169         LOGE(ATM_DOMAIN, ATM_TAG, "Set wal mode failed, errorMsg: %{public}s", SpitError().c_str());
170     } else {
171         LOGI(ATM_DOMAIN, ATM_TAG, "Set wal mode success!");
172     }
173 }
174 
GetVersion() const175 int32_t SqliteHelper::GetVersion() const __attribute__((no_sanitize("cfi")))
176 {
177     if (db_ == nullptr) {
178         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
179         return GENERAL_ERROR;
180     }
181     auto statement = Prepare(PRAGMA_VERSION_COMMAND);
182     int32_t version = 0;
183     while (statement.Step() == Statement::State::ROW) {
184         version = statement.GetColumnInt(0);
185     }
186     LOGI(ATM_DOMAIN, ATM_TAG, "Version: %{public}d", version);
187     return version;
188 }
189 
SetVersion() const190 void SqliteHelper::SetVersion() const
191 {
192     if (db_ == nullptr) {
193         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
194         return;
195     }
196     auto statement = Prepare(PRAGMA_VERSION_COMMAND + " = " + std::to_string(currentVersion_));
197     statement.Step();
198 }
199 
SpitError() const200 std::string SqliteHelper::SpitError() const
201 {
202     if (db_ == nullptr) {
203         LOGW(ATM_DOMAIN, ATM_TAG, "Do open data base first!");
204         return "";
205     }
206     return sqlite3_errmsg(db_);
207 }
208 } // namespace AccessToken
209 } // namespace Security
210 } // namespace OHOS
211