• 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 "sqlite_local_storage_executor.h"
17 
18 #include "log_print.h"
19 #include "db_errno.h"
20 #include "sqlite_utils.h"
21 
22 namespace DistributedDB {
23 namespace {
24     const std::string CLEAR_SQL = "DELETE FROM data;";
25     const std::string SELECT_SQL = "SELECT value FROM data WHERE key=?;";
26     const std::string SELECT_BATCH_SQL =
27         "SELECT key, value FROM data WHERE key>=? AND key<=? ORDER BY key ASC;";
28     const std::string INSERT_SQL = "INSERT OR REPLACE INTO data VALUES(?,?);";
29     const std::string DELETE_SQL = "DELETE FROM data WHERE key=?;";
30 
31     const int BIND_KEY_INDEX = 1;
32     const int BIND_VAL_INDEX = 2;
33 
34     const int SELECT_BIND_KEY_INDEX = 1; // index of the binding key index for select one entry.
35 
36     const int SELECT_RESULT_KEY_INDEX = 0;
37     const int SELECT_RESULT_VAL_INDEX = 1;
38 }
39 
SQLiteLocalStorageExecutor(sqlite3 * dbHandle,bool writable,bool isMemDb)40 SQLiteLocalStorageExecutor::SQLiteLocalStorageExecutor(sqlite3 *dbHandle, bool writable, bool isMemDb)
41     : SQLiteStorageExecutor(dbHandle, writable, isMemDb)
42 {}
43 
~SQLiteLocalStorageExecutor()44 SQLiteLocalStorageExecutor::~SQLiteLocalStorageExecutor()
45 {}
46 
Get(const Key & key,Value & value) const47 int SQLiteLocalStorageExecutor::Get(const Key &key, Value &value) const
48 {
49     sqlite3_stmt *statement = nullptr;
50     int errCode = SQLiteUtils::GetStatement(dbHandle_, SELECT_SQL, statement);
51     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
52         return CheckCorruptedStatus(errCode);
53     }
54 
55     errCode = SQLiteUtils::BindBlobToStatement(statement, SELECT_BIND_KEY_INDEX, key, false);
56     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
57         goto END;
58     }
59 
60     errCode = SQLiteUtils::StepWithRetry(statement);
61     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { // LCOV_EXCL_BR_LINE
62         errCode = -E_NOT_FOUND;
63         goto END;
64     } else if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
65         goto END;
66     }
67 
68     errCode = SQLiteUtils::GetColumnBlobValue(statement, 0, value);
69 
70 END:
71     int ret = E_OK;
72     SQLiteUtils::ResetStatement(statement, true, ret);
73     return CheckCorruptedStatus(errCode);
74 }
75 
Clear()76 int SQLiteLocalStorageExecutor::Clear()
77 {
78     int errCode = SQLiteUtils::ExecuteRawSQL(dbHandle_, CLEAR_SQL);
79     return CheckCorruptedStatus(errCode);
80 }
81 
GetEntries(const Key & keyPrefix,std::vector<Entry> & entries) const82 int SQLiteLocalStorageExecutor::GetEntries(const Key &keyPrefix,
83     std::vector<Entry> &entries) const
84 {
85     sqlite3_stmt *statement = nullptr;
86     int errCode = SQLiteUtils::GetStatement(dbHandle_, SELECT_BATCH_SQL, statement);
87     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
88         return CheckCorruptedStatus(errCode);
89     }
90 
91     Entry entry;
92     errCode = SQLiteUtils::BindPrefixKey(statement, SELECT_BIND_KEY_INDEX, keyPrefix); // first arg is prefix key
93     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
94         goto END;
95     }
96 
97     do {
98         errCode = SQLiteUtils::StepWithRetry(statement);
99         if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
100             errCode = SQLiteUtils::GetColumnBlobValue(statement, SELECT_RESULT_KEY_INDEX, entry.key);
101             if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
102                 goto END;
103             }
104 
105             errCode = SQLiteUtils::GetColumnBlobValue(statement, SELECT_RESULT_VAL_INDEX, entry.value);
106             if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
107                 goto END;
108             }
109 
110             entries.push_back(std::move(entry));
111         } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
112             break;
113         } else {
114             LOGE("SQLite step failed:%d", errCode);
115             goto END;
116         }
117     } while (true);
118 
119     // if select no result, return the -E_NOT_FOUND.
120     if (entries.empty()) { // LCOV_EXCL_BR_LINE
121         errCode = -E_NOT_FOUND;
122     } else {
123         errCode = E_OK;
124     }
125 
126 END:
127     int ret = E_OK;
128     SQLiteUtils::ResetStatement(statement, true, ret);
129     return CheckCorruptedStatus(errCode);
130 }
131 
PutBatch(const std::vector<Entry> & entries)132 int SQLiteLocalStorageExecutor::PutBatch(const std::vector<Entry> &entries)
133 {
134     if (entries.empty()) { // LCOV_EXCL_BR_LINE
135         return -E_INVALID_ARGS;
136     }
137 
138     for (const auto &entry : entries) {
139         // first argument is key and second argument is value.
140         int errCode = Put(entry.key, entry.value);
141         if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
142             LOGE("PutBatch failed: %d", errCode);
143             return CheckCorruptedStatus(errCode);
144         }
145     }
146 
147     return E_OK;
148 }
149 
DeleteBatch(const std::vector<Key> & keys)150 int SQLiteLocalStorageExecutor::DeleteBatch(const std::vector<Key> &keys)
151 {
152     if (keys.empty()) { // LCOV_EXCL_BR_LINE
153         return -E_INVALID_ARGS;
154     }
155 
156     bool isAllNoExisted = true;
157 
158     for (const auto &key : keys) {
159         int errCode = Delete(key);
160         if (errCode != E_OK && errCode != -E_NOT_FOUND) { // LCOV_EXCL_BR_LINE
161             return CheckCorruptedStatus(errCode);
162         }
163         if (errCode != -E_NOT_FOUND && isAllNoExisted == true) { // LCOV_EXCL_BR_LINE
164             isAllNoExisted = false;
165         }
166     }
167 
168     if (isAllNoExisted) { // LCOV_EXCL_BR_LINE
169         return -E_NOT_FOUND;
170     }
171 
172     return E_OK;
173 }
174 
StartTransaction()175 int SQLiteLocalStorageExecutor::StartTransaction()
176 {
177     int errCode = SQLiteUtils::BeginTransaction(dbHandle_);
178     return CheckCorruptedStatus(errCode);
179 }
180 
Commit()181 int SQLiteLocalStorageExecutor::Commit()
182 {
183     int errCode = SQLiteUtils::CommitTransaction(dbHandle_);
184     return CheckCorruptedStatus(errCode);
185 }
186 
RollBack()187 int SQLiteLocalStorageExecutor::RollBack()
188 {
189     int errCode = SQLiteUtils::RollbackTransaction(dbHandle_);
190     return CheckCorruptedStatus(errCode);
191 }
192 
Put(const Key & key,const Value & value)193 int SQLiteLocalStorageExecutor::Put(const Key &key, const Value &value)
194 {
195     sqlite3_stmt *statement = nullptr;
196     int errCode = SQLiteUtils::GetStatement(dbHandle_, INSERT_SQL, statement);
197     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
198         return CheckCorruptedStatus(errCode);
199     }
200 
201     errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_KEY_INDEX, key, false);
202     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
203         LOGE("Failed to bind the key.");
204         goto END;
205     }
206 
207     errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_VAL_INDEX, value, true);
208     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
209         LOGE("Failed to bind the value");
210         goto END;
211     }
212 
213     errCode = SQLiteUtils::StepWithRetry(statement);
214     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { // LCOV_EXCL_BR_LINE
215         errCode = E_OK;
216     } else {
217         errCode = SQLiteUtils::MapSQLiteErrno(errCode);
218     }
219 
220 END:
221     int ret = E_OK;
222     SQLiteUtils::ResetStatement(statement, true, ret);
223     return CheckCorruptedStatus(errCode);
224 }
225 
Delete(const Key & key)226 int SQLiteLocalStorageExecutor::Delete(const Key &key)
227 {
228     sqlite3_stmt *statement = nullptr;
229     int errCode = SQLiteUtils::GetStatement(dbHandle_, DELETE_SQL, statement);
230     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
231         LOGE("Failed to get the delete statememt.");
232         return CheckCorruptedStatus(errCode);
233     }
234 
235     errCode = SQLiteUtils::BindBlobToStatement(statement, BIND_KEY_INDEX, key, false);
236     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
237         LOGE("Bind key failed");
238         goto END;
239     }
240 
241     errCode = SQLiteUtils::StepWithRetry(statement);
242     if (errCode != SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { // LCOV_EXCL_BR_LINE
243         LOGE("Delete step error:%d", errCode);
244     } else {
245         if (sqlite3_changes(dbHandle_) > 0) { // LCOV_EXCL_BR_LINE
246             errCode = E_OK;
247         } else {
248             errCode = -E_NOT_FOUND;
249         }
250     }
251 END:
252     int ret = E_OK;
253     SQLiteUtils::ResetStatement(statement, true, ret);
254     return CheckCorruptedStatus(errCode);
255 }
256 } // namespace DistributedDB
257