• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static inline 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 
197     GRD_FilterOptionT filterOpt = {};
198     filterOpt.mode = KV_SCAN_RANGE;
199     if (!beginKey.empty()) {
200         filterOpt.begin = {(void *)&beginKey[0], (uint32_t)beginKey.size()};
201     }
202     if (!endKey.empty()) {
203         filterOpt.end = {(void *)&endKey[0], (uint32_t)endKey.size()};
204     }
205 
206     return TransferGrdErrno(GRD_KVFilter(db, collectionName, &filterOpt, resultSet));
207 }
208 
RdKvFetch(GRD_ResultSet * resultSet,Key & key,Value & value)209 int RdKvFetch(GRD_ResultSet *resultSet, Key &key, Value &value)
210 {
211     uint32_t keyLen;
212     uint32_t valueLen;
213     int errCode = TransferGrdErrno(GRD_KVGetSize(resultSet, &keyLen, &valueLen));
214     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
215         LOGE("[rdUtils][RdKvFetch] Can not Get value lens size from resultSet");
216         return errCode;
217     }
218     key.resize(keyLen);
219     value.resize(valueLen);
220     return TransferGrdErrno(GRD_GetItem(resultSet, key.data(), value.data()));
221 }
222 
RdDBClose(GRD_DB * db,uint32_t flags)223 int RdDBClose(GRD_DB *db, uint32_t flags)
224 {
225     int ret = TransferGrdErrno(GRD_DBClose(db, flags));
226     if (ret != E_OK) {
227         LOGE("Can not close db %d", ret);
228     }
229     return ret;
230 }
231 
RdFreeResultSet(GRD_ResultSet * resultSet)232 int RdFreeResultSet(GRD_ResultSet *resultSet)
233 {
234     return TransferGrdErrno(GRD_FreeResultSet(resultSet));
235 }
236 
RdKVBatchPrepare(uint16_t itemNum,GRD_KVBatchT ** batch)237 int RdKVBatchPrepare(uint16_t itemNum, GRD_KVBatchT **batch)
238 {
239     return TransferGrdErrno(GRD_KVBatchPrepare(itemNum, batch));
240 }
241 
RdKVBatchPushback(GRD_KVBatchT * batch,const Key & key,const Value & value)242 int RdKVBatchPushback(GRD_KVBatchT *batch, const Key &key, const Value &value)
243 {
244     GRD_KVItemT innerKey{(void *)&key[0], (uint32_t)key.size()};
245     GRD_KVItemT innerVal{nullptr, 0};
246 
247     if (!value.empty()) {
248         innerVal.data = (void *)&value[0];
249         innerVal.dataLen = (uint32_t)value.size();
250     }
251     int ret = TransferGrdErrno(
252         GRD_KVBatchPushback(innerKey.data, innerKey.dataLen, innerVal.data, innerVal.dataLen, batch));
253     if (ret != E_OK) {
254         LOGE("[rdUtils][BatchSaveEntries] Can not push back entries to KVBatch structure");
255     }
256     return ret;
257 }
258 
RdKVBatchPut(GRD_DB * db,const char * kvTableName,GRD_KVBatchT * batch)259 int RdKVBatchPut(GRD_DB *db, const char *kvTableName, GRD_KVBatchT *batch)
260 {
261     if (db == nullptr) {
262         LOGE("[rdUtils][RdKVBatchPut] invalid db");
263         return -E_INVALID_DB;
264     }
265     return TransferGrdErrno(GRD_KVBatchPut(db, kvTableName, batch));
266 }
267 
RdFlush(GRD_DB * db,uint32_t flags)268 int RdFlush(GRD_DB *db, uint32_t flags)
269 {
270     if (db == nullptr) {
271         LOGE("[rdUtils][ForceCheckPoint] invalid db");
272         return -E_INVALID_DB;
273     }
274     // flags means options, input 0 in current version.
275     return TransferGrdErrno(GRD_Flush(db, flags));
276 }
277 
RdKVBatchDel(GRD_DB * db,const char * kvTableName,GRD_KVBatchT * batch)278 int RdKVBatchDel(GRD_DB *db, const char *kvTableName, GRD_KVBatchT *batch)
279 {
280     if (db == nullptr) {
281         LOGE("[rdUtils][RdKVBatchDel] invalid db");
282         return -E_INVALID_DB;
283     }
284     return TransferGrdErrno(GRD_KVBatchDel(db, kvTableName, batch));
285 }
286 
RdKVBatchDestroy(GRD_KVBatchT * batch)287 int RdKVBatchDestroy(GRD_KVBatchT *batch)
288 {
289     return TransferGrdErrno(GRD_KVBatchDestroy(batch));
290 }
291 
RdDbOpen(const char * dbPath,const char * configStr,uint32_t flags,GRD_DB * & db)292 int RdDbOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB *&db)
293 {
294     return TransferGrdErrno(GRD_DBOpen(dbPath, configStr, flags, &db));
295 }
296 
RdIndexPreload(GRD_DB * & db,const char * collectionName)297 int RdIndexPreload(GRD_DB *&db, const char *collectionName)
298 {
299     if (db == nullptr) {
300         LOGE("[rdUtils][RdIndexPreload] db is null");
301         return -E_INVALID_DB;
302     }
303     return TransferGrdErrno(GRD_IndexPreload(db, collectionName));
304 }
305 
RdCreateCollection(GRD_DB * db,const char * collectionName,const char * optionStr,uint32_t flags)306 int RdCreateCollection(GRD_DB *db, const char *collectionName, const char *optionStr, uint32_t flags)
307 {
308     return TransferGrdErrno(GRD_CreateCollection(db, collectionName, optionStr, flags));
309 }
310 
CheckParaOption(const KvStoreNbDelegate::Option & option,const std::function<void (DBStatus,KvStoreNbDelegate *)> & callback)311 bool CheckParaOption(const KvStoreNbDelegate::Option &option,
312     const std::function<void(DBStatus, KvStoreNbDelegate *)> &callback)
313 {
314     if (option.storageEngineType == SQLITE) {
315         if ((option.rdconfig.pageSize < SQLITE_PAGE_SIZE_MIN) ||
316             (option.rdconfig.pageSize > SQLITE_PAGE_SIZE_MAX)) {
317             callback(INVALID_ARGS, nullptr);
318             LOGE("Invalid config pageSize:%" PRIu32, option.rdconfig.pageSize);
319             return false;
320         }
321         if ((option.rdconfig.cacheSize % option.rdconfig.pageSize != 0) ||
322             ((option.rdconfig.pageSize & (option.rdconfig.pageSize - 1)) != 0) ||
323             (option.rdconfig.cacheSize / SQLITE_CACHE_SIZE_PAGE > option.rdconfig.pageSize)) {
324             callback(INVALID_ARGS, nullptr);
325             LOGE("Invalid config pageSize:%" PRIu32 "and cacheSize:%" PRIu32, option.rdconfig.pageSize,
326                 option.rdconfig.cacheSize);
327             return false;
328         }
329     }
330     if (option.storageEngineType != GAUSSDB_RD && option.storageEngineType != SQLITE) {
331         callback(INVALID_ARGS, nullptr);
332         return false;
333     }
334     if (option.rdconfig.readOnly && option.isNeedRmCorruptedDb) {
335         callback(INVALID_ARGS, nullptr);
336         return false;
337     }
338     if (!CheckOption(option)) {
339         callback(NOT_SUPPORT, nullptr);
340         return false;
341     }
342     return true;
343 }
344 } // namespace DistributedDB