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 #include "rd_utils.h"
16 #include "db_errno.h"
17 #include "log_print.h"
18 #include "sqlite_single_ver_storage_executor_sql.h"
19
20 namespace {
21 using namespace DistributedDB;
22
CheckRdOptionMode(const KvStoreNbDelegate::Option & option)23 bool CheckRdOptionMode(const KvStoreNbDelegate::Option &option)
24 {
25 return (option.mode != 0 && option.mode != 1) || option.syncDualTupleMode;
26 }
27
CheckOption(const KvStoreNbDelegate::Option & option)28 bool CheckOption(const KvStoreNbDelegate::Option &option)
29 {
30 if (option.storageEngineType == GAUSSDB_RD &&
31 (CheckRdOptionMode(option) ||
32 option.isMemoryDb ||
33 option.isEncryptedDb ||
34 option.cipher != CipherType::DEFAULT ||
35 option.passwd != CipherPassword() ||
36 !option.schema.empty() ||
37 option.conflictType != 0 ||
38 option.notifier != nullptr ||
39 option.conflictResolvePolicy != LAST_WIN ||
40 option.isNeedCompressOnSync ||
41 option.compressionRate != 100 || // Valid in [1, 100].
42 option.localOnly)) {
43 return false;
44 }
45 return true;
46 }
47 }
48
49 namespace DistributedDB {
50
InitRdConfig()51 std::string InitRdConfig()
52 {
53 return R"("redoFlushByTrx": 1, "maxConnNum": 100, "crcCheckEnable": 0, "metaInfoBak": 1)";
54 }
55
56 struct GrdErrnoPair {
57 int32_t grdCode;
58 int kvDbCode;
59 };
60
61 const GrdErrnoPair GRD_ERRNO_MAP[] = {
62 { GRD_OK, E_OK },
63 { GRD_NOT_SUPPORT, -E_NOT_SUPPORT },
64 { GRD_OVER_LIMIT, -E_MAX_LIMITS },
65 { GRD_INVALID_ARGS, -E_INVALID_ARGS },
66 { GRD_FAILED_FILE_OPERATION, -E_SYSTEM_API_FAIL },
67 { GRD_INVALID_FILE_FORMAT, -E_INVALID_PASSWD_OR_CORRUPTED_DB },
68 { GRD_INSUFFICIENT_SPACE, -E_INTERNAL_ERROR },
69 { GRD_INNER_ERR, -E_INTERNAL_ERROR },
70 { GRD_RESOURCE_BUSY, -E_BUSY },
71 { GRD_NO_DATA, -E_NOT_FOUND },
72 { GRD_FAILED_MEMORY_ALLOCATE, -E_OUT_OF_MEMORY },
73 { GRD_FAILED_MEMORY_RELEASE, -E_OUT_OF_MEMORY },
74 { GRD_DATA_CONFLICT, -E_INVALID_DATA },
75 { GRD_NOT_AVAILABLE, -E_NOT_FOUND },
76 { GRD_INVALID_FORMAT, -E_INVALID_FORMAT },
77 { GRD_TIME_OUT, -E_TIMEOUT },
78 { GRD_DB_INSTANCE_ABNORMAL, -E_INTERNAL_ERROR },
79 { GRD_DISK_SPACE_FULL, -E_INTERNAL_ERROR },
80 { GRD_CRC_CHECK_DISABLED, -E_INVALID_ARGS },
81 { GRD_PERMISSION_DENIED, -E_DENIED_SQL },
82 { GRD_REBUILD_DATABASE, -E_REBUILD_DATABASE }, // rebuild database means ok
83 { GRD_DATA_CORRUPTED, -E_INVALID_PASSWD_OR_CORRUPTED_DB },
84 { GRD_DATA_EXCEPTION, -E_UNEXPECTED_DATA },
85 { GRD_DB_BUSY, -E_BUSY },
86 };
TransferGrdErrno(int err)87 int TransferGrdErrno(int err)
88 {
89 if (err > 0) {
90 return err;
91 }
92 for (const auto &item : GRD_ERRNO_MAP) {
93 if (item.grdCode == err) {
94 return item.kvDbCode;
95 }
96 }
97 return -E_INTERNAL_ERROR;
98 }
99
KvItemToBlob(GRD_KVItemT & item)100 std::vector<uint8_t> KvItemToBlob(GRD_KVItemT &item)
101 {
102 return std::vector<uint8_t>((uint8_t *)item.data, (uint8_t *)item.data + item.dataLen);
103 }
104
GetCollNameFromType(SingleVerDataType type,std::string & collName)105 int GetCollNameFromType(SingleVerDataType type, std::string &collName)
106 {
107 switch (type) {
108 case SingleVerDataType::SYNC_TYPE:
109 collName = SYNC_COLLECTION_NAME;
110 break;
111 default:
112 LOGE("data type not support");
113 return -E_INVALID_ARGS;
114 }
115 return E_OK;
116 }
117
RdKVPut(GRD_DB * db,const char * collectionName,const Key & key,const Value & value)118 int RdKVPut(GRD_DB *db, const char *collectionName, const Key &key, const Value &value)
119 {
120 if (db == nullptr) {
121 LOGE("[rdUtils][RdKvPut] invalid db");
122 return -E_INVALID_DB;
123 }
124 GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()};
125 GRD_KVItemT innerVal{(void *)&value[0], (uint32_t)value.size()};
126 int ret = TransferGrdErrno(GRD_KVPut(db, collectionName, &innerKey, &innerVal));
127 if (ret != E_OK) {
128 LOGE("[rdUtils][RdKvPut] ERROR:%d", ret);
129 }
130 return ret;
131 }
132
RdKVGet(GRD_DB * db,const char * collectionName,const Key & key,Value & value)133 int RdKVGet(GRD_DB *db, const char *collectionName, const Key &key, Value &value)
134 {
135 if (db == nullptr) {
136 LOGE("[rdUtils][RdKvGet] invalid db");
137 return -E_INVALID_DB;
138 }
139 GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()};
140 GRD_KVItemT innerVal = { 0 };
141 int ret = TransferGrdErrno(GRD_KVGet(db, collectionName, &innerKey, &innerVal));
142 if (ret != E_OK) {
143 // log print on caller
144 return ret;
145 }
146 value = KvItemToBlob(innerVal);
147 (void)GRD_KVFreeItem(&innerVal);
148 return E_OK;
149 }
150
RdBackup(GRD_DB * db,const char * backupDbFile,uint8_t * encryptedKey,uint32_t encryptedKeyLen)151 int RdBackup(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen)
152 {
153 return TransferGrdErrno(GRD_DBBackup(db, backupDbFile, encryptedKey, encryptedKeyLen));
154 }
155
RdRestore(const char * dbFile,const char * backupDbFile,uint8_t * decryptedKey,uint32_t decryptedKeyLen)156 int RdRestore(const char *dbFile, const char *backupDbFile, uint8_t *decryptedKey, uint32_t decryptedKeyLen)
157 {
158 return TransferGrdErrno(GRD_DBRestore(dbFile, backupDbFile, decryptedKey, decryptedKeyLen));
159 }
160
RdKVDel(GRD_DB * db,const char * collectionName,const Key & key)161 int RdKVDel(GRD_DB *db, const char *collectionName, const Key &key)
162 {
163 if (db == nullptr) {
164 LOGE("[rdUtils][RdKvDel] invalid db");
165 return -E_INVALID_DB;
166 }
167 GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()};
168 int ret = TransferGrdErrno(GRD_KVDel(db, collectionName, &innerKey));
169 if (ret < 0) {
170 LOGE("[rdUtils][RdKvDel] failed:%d", ret);
171 }
172 return ret;
173 }
174
RdKVScan(GRD_DB * db,const char * collectionName,const Key & key,GRD_KvScanModeE mode,GRD_ResultSet ** resultSet)175 int RdKVScan(GRD_DB *db, const char *collectionName, const Key &key, GRD_KvScanModeE mode,
176 GRD_ResultSet **resultSet)
177 {
178 if (db == nullptr) {
179 LOGE("[rdUtils][RdKVScan] invalid db");
180 return -E_INVALID_DB;
181 }
182 if (key.empty()) {
183 return TransferGrdErrno(GRD_KVScan(db, collectionName, NULL, mode, resultSet));
184 }
185 GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()};
186 return TransferGrdErrno(GRD_KVScan(db, collectionName, &innerKey, mode, resultSet));
187 }
188
RdKVRangeScan(GRD_DB * db,const char * collectionName,const Key & beginKey,const Key & endKey,GRD_ResultSet ** resultSet)189 int RdKVRangeScan(GRD_DB *db, const char *collectionName, const Key &beginKey, const Key &endKey,
190 GRD_ResultSet **resultSet)
191 {
192 if (db == nullptr) {
193 LOGE("[rdUtils][RdKVScan] invalid db");
194 return -E_INVALID_DB;
195 }
196 GRD_KVItemT beginInnerKey{(void *)&beginKey[0], (uint32_t)beginKey.size()};
197 GRD_KVItemT endInnerKey{(void *)&endKey[0], (uint32_t)endKey.size()};
198 GRD_FilterOption filterOpt{KV_SCAN_RANGE, beginInnerKey, endInnerKey};
199 return TransferGrdErrno(GRD_KVFilter(db, collectionName, &filterOpt, resultSet));
200 }
201
RdKvFetch(GRD_ResultSet * resultSet,Key & key,Value & value)202 int RdKvFetch(GRD_ResultSet *resultSet, Key &key, Value &value)
203 {
204 uint32_t keyLen;
205 uint32_t valueLen;
206 int errCode = TransferGrdErrno(GRD_KVGetSize(resultSet, &keyLen, &valueLen));
207 if (errCode != E_OK && errCode != -E_NOT_FOUND) {
208 LOGE("[rdUtils][RdKvFetch] Can not Get value lens size from resultSet");
209 return errCode;
210 }
211 key.resize(keyLen);
212 value.resize(valueLen);
213 return TransferGrdErrno(GRD_GetItem(resultSet, key.data(), value.data()));
214 }
215
RdDBClose(GRD_DB * db,uint32_t flags)216 int RdDBClose(GRD_DB *db, uint32_t flags)
217 {
218 int ret = TransferGrdErrno(GRD_DBClose(db, flags));
219 if (ret != E_OK) {
220 LOGE("Can not close db %d", ret);
221 }
222 return ret;
223 }
224
RdFreeResultSet(GRD_ResultSet * resultSet)225 int RdFreeResultSet(GRD_ResultSet *resultSet)
226 {
227 return TransferGrdErrno(GRD_FreeResultSet(resultSet));
228 }
229
RdKVBatchPrepare(uint16_t itemNum,GRD_KVBatchT ** batch)230 int RdKVBatchPrepare(uint16_t itemNum, GRD_KVBatchT **batch)
231 {
232 return TransferGrdErrno(GRD_KVBatchPrepare(itemNum, batch));
233 }
234
RdKVBatchPushback(GRD_KVBatchT * batch,const Key & key,const Value & value)235 int RdKVBatchPushback(GRD_KVBatchT *batch, const Key &key, const Value &value)
236 {
237 GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()};
238 GRD_KVItemT innerVal{(void *)&value[0], (uint32_t)value.size()};
239 int ret = TransferGrdErrno(
240 GRD_KVBatchPushback(innerKey.data, innerKey.dataLen, innerVal.data, innerVal.dataLen, batch));
241 if (ret != E_OK) {
242 LOGE("[rdUtils][BatchSaveEntries] Can not push back entries to KVBatch structure");
243 }
244 return ret;
245 }
246
RdKVBatchPut(GRD_DB * db,const char * kvTableName,GRD_KVBatchT * batch)247 int RdKVBatchPut(GRD_DB *db, const char *kvTableName, GRD_KVBatchT *batch)
248 {
249 if (db == nullptr) {
250 LOGE("[rdUtils][RdKVBatchPut] invalid db");
251 return -E_INVALID_DB;
252 }
253 return TransferGrdErrno(GRD_KVBatchPut(db, kvTableName, batch));
254 }
255
RdFlush(GRD_DB * db,uint32_t flags)256 int RdFlush(GRD_DB *db, uint32_t flags)
257 {
258 if (db == nullptr) {
259 LOGE("[rdUtils][ForceCheckPoint] invalid db");
260 return -E_INVALID_DB;
261 }
262 // flags means options, input 0 in current version.
263 return TransferGrdErrno(GRD_Flush(db, flags));
264 }
265
RdKVBatchDel(GRD_DB * db,const char * kvTableName,GRD_KVBatchT * batch)266 int RdKVBatchDel(GRD_DB *db, const char *kvTableName, GRD_KVBatchT *batch)
267 {
268 if (db == nullptr) {
269 LOGE("[rdUtils][RdKVBatchDel] invalid db");
270 return -E_INVALID_DB;
271 }
272 return TransferGrdErrno(GRD_KVBatchDel(db, kvTableName, batch));
273 }
274
RdKVBatchDestroy(GRD_KVBatchT * batch)275 int RdKVBatchDestroy(GRD_KVBatchT *batch)
276 {
277 return TransferGrdErrno(GRD_KVBatchDestroy(batch));
278 }
279
RdDbOpen(const char * dbPath,const char * configStr,uint32_t flags,GRD_DB * & db)280 int RdDbOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB *&db)
281 {
282 return TransferGrdErrno(GRD_DBOpen(dbPath, configStr, flags, &db));
283 }
284
RdIndexPreload(GRD_DB * & db,const char * collectionName)285 int RdIndexPreload(GRD_DB *&db, const char *collectionName)
286 {
287 if (db == nullptr) {
288 LOGE("[rdUtils][RdIndexPreload] db is null");
289 return -E_INVALID_DB;
290 }
291 return TransferGrdErrno(GRD_IndexPreload(db, collectionName));
292 }
293
RdCreateCollection(GRD_DB * db,const char * collectionName,const char * optionStr,uint32_t flags)294 int RdCreateCollection(GRD_DB *db, const char *collectionName, const char *optionStr, uint32_t flags)
295 {
296 return TransferGrdErrno(GRD_CreateCollection(db, collectionName, optionStr, flags));
297 }
298
CheckParaOption(const KvStoreNbDelegate::Option & option,const std::function<void (DBStatus,KvStoreNbDelegate *)> & callback)299 bool CheckParaOption(const KvStoreNbDelegate::Option &option,
300 const std::function<void(DBStatus, KvStoreNbDelegate *)> &callback)
301 {
302 if (option.storageEngineType == SQLITE) {
303 if ((option.rdconfig.pageSize < SQLITE_PAGE_SIZE_MIN) ||
304 (option.rdconfig.pageSize > SQLITE_PAGE_SIZE_MAX)) {
305 callback(INVALID_ARGS, nullptr);
306 LOGE("Invalid config pageSize:%" PRIu32, option.rdconfig.pageSize);
307 return false;
308 }
309 if ((option.rdconfig.cacheSize % option.rdconfig.pageSize != 0) ||
310 ((option.rdconfig.pageSize & (option.rdconfig.pageSize - 1)) != 0) ||
311 (option.rdconfig.cacheSize / SQLITE_CACHE_SIZE_PAGE > option.rdconfig.pageSize)) {
312 callback(INVALID_ARGS, nullptr);
313 LOGE("Invalid config pageSize:%" PRIu32 "and cacheSize:%" PRIu32, option.rdconfig.pageSize,
314 option.rdconfig.cacheSize);
315 return false;
316 }
317 }
318 if (option.storageEngineType != GAUSSDB_RD && option.storageEngineType != SQLITE) {
319 callback(INVALID_ARGS, nullptr);
320 return false;
321 }
322 if (option.rdconfig.readOnly && option.isNeedRmCorruptedDb) {
323 callback(INVALID_ARGS, nullptr);
324 return false;
325 }
326 if (!CheckOption(option)) {
327 callback(NOT_SUPPORT, nullptr);
328 return false;
329 }
330 return true;
331 }
332 } // namespace DistributedDB