1 /*
2  * Copyright (c) 2024 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 #define LOG_TAG "RdUtils"
17 #include "rd_utils.h"
18 
19 #include <securec.h>
20 
21 #include "grd_error.h"
22 #include "grd_api_manager.h"
23 #include "logger.h"
24 #include "remote_result_set.h"
25 
26 namespace OHOS {
27 namespace NativeRdb {
28 using namespace OHOS::Rdb;
29 
30 static GRD_APIInfo GRD_KVApiInfo;
31 
32 struct GrdErrnoPair {
33     int32_t grdCode;
34     int kvDbCode;
35 };
36 
37 const GrdErrnoPair GRD_ERRNO_MAP[] = {
38     { GRD_OK, E_OK },
39     { GRD_NO_DATA, E_NO_MORE_ROWS },
40     { GRD_INNER_ERR, E_ERROR },
41     { GRD_DATA_CORRUPTED, E_SQLITE_CORRUPT },
42     { GRD_INVALID_FILE_FORMAT, E_SQLITE_CORRUPT },
43 };
44 
TransferGrdErrno(int err)45 int RdUtils::TransferGrdErrno(int err)
46 {
47     if (err > 0) {
48         return err;
49     }
50     for (const auto &item : GRD_ERRNO_MAP) {
51         if (item.grdCode == err) {
52             return item.kvDbCode;
53         }
54     }
55     return E_ERROR;
56 }
57 
TransferGrdTypeToColType(int grdColType)58 ColumnType RdUtils::TransferGrdTypeToColType(int grdColType)
59 {
60     switch (grdColType) {
61         case GRD_DB_DATATYPE_INTEGER:
62             return ColumnType::TYPE_INTEGER;
63         case GRD_DB_DATATYPE_FLOAT:
64             return ColumnType::TYPE_FLOAT;
65         case GRD_DB_DATATYPE_TEXT:
66             return ColumnType::TYPE_STRING;
67         case GRD_DB_DATATYPE_BLOB:
68             return ColumnType::TYPE_BLOB;
69         case GRD_DB_DATATYPE_FLOATVECTOR:
70             return ColumnType::TYPE_FLOAT32_ARRAY;
71         default:
72             break;
73     }
74     return ColumnType::TYPE_NULL;
75 }
76 
RdDbOpen(const char * dbPath,const char * configStr,uint32_t flags,GRD_DB ** db)77 int RdUtils::RdDbOpen(const char *dbPath, const char *configStr, uint32_t flags, GRD_DB **db)
78 {
79     if (GRD_KVApiInfo.DBOpenApi == nullptr) {
80         GRD_KVApiInfo = GetApiInfoInstance();
81     }
82     if (GRD_KVApiInfo.DBOpenApi == nullptr) {
83         return E_NOT_SUPPORT;
84     }
85     return TransferGrdErrno(GRD_KVApiInfo.DBOpenApi(dbPath, configStr, flags, db));
86 }
87 
RdDbClose(GRD_DB * db,uint32_t flags)88 int RdUtils::RdDbClose(GRD_DB *db, uint32_t flags)
89 {
90     LOG_DEBUG("[RdUtils::RdDbClose]");
91     if (GRD_KVApiInfo.DBCloseApi == nullptr) {
92         GRD_KVApiInfo = GetApiInfoInstance();
93     }
94     if (GRD_KVApiInfo.DBCloseApi == nullptr) {
95         return E_NOT_SUPPORT;
96     }
97     return TransferGrdErrno(GRD_KVApiInfo.DBCloseApi(db, flags));
98 }
99 
RdDbRepair(const char * dbPath,const char * configStr)100 int RdUtils::RdDbRepair(const char *dbPath, const char *configStr)
101 {
102     if (GRD_KVApiInfo.DBRepairApi == nullptr) {
103         GRD_KVApiInfo = GetApiInfoInstance();
104     }
105     if (GRD_KVApiInfo.DBRepairApi == nullptr) {
106         return E_NOT_SUPPORT;
107     }
108     return TransferGrdErrno(GRD_KVApiInfo.DBRepairApi(dbPath, configStr));
109 }
110 
RdSqlPrepare(GRD_DB * db,const char * str,uint32_t strLen,GRD_SqlStmt ** stmt,const char ** unusedStr)111 int RdUtils::RdSqlPrepare(GRD_DB *db, const char *str, uint32_t strLen, GRD_SqlStmt **stmt, const char **unusedStr)
112 {
113     if (GRD_KVApiInfo.DBSqlPrepare == nullptr) {
114         GRD_KVApiInfo = GetApiInfoInstance();
115     }
116     if (GRD_KVApiInfo.DBSqlPrepare == nullptr) {
117         return E_NOT_SUPPORT;
118     }
119     return TransferGrdErrno(GRD_KVApiInfo.DBSqlPrepare(db, str, strLen, stmt, unusedStr));
120 }
121 
RdSqlReset(GRD_SqlStmt * stmt)122 int RdUtils::RdSqlReset(GRD_SqlStmt *stmt)
123 {
124     if (GRD_KVApiInfo.DBSqlReset == nullptr) {
125         GRD_KVApiInfo = GetApiInfoInstance();
126     }
127     if (GRD_KVApiInfo.DBSqlReset == nullptr) {
128         return E_NOT_SUPPORT;
129     }
130     return TransferGrdErrno(GRD_KVApiInfo.DBSqlReset(stmt));
131 }
132 
RdSqlFinalize(GRD_SqlStmt * stmt)133 int RdUtils::RdSqlFinalize(GRD_SqlStmt *stmt)
134 {
135     if (GRD_KVApiInfo.DBSqlFinalize == nullptr) {
136         GRD_KVApiInfo = GetApiInfoInstance();
137     }
138     if (GRD_KVApiInfo.DBSqlFinalize == nullptr) {
139         return E_NOT_SUPPORT;
140     }
141     return TransferGrdErrno(GRD_KVApiInfo.DBSqlFinalize(stmt));
142 }
143 
RdSqlFreeBlob(void * blobElementSize)144 void RdSqlFreeBlob(void *blobElementSize)
145 {
146     delete[] ((uint8_t *)blobElementSize);
147 }
148 
RdSqlBindBlob(GRD_SqlStmt * stmt,uint32_t idx,const void * val,int32_t len,void (* freeFunc)(void *))149 int RdUtils::RdSqlBindBlob(GRD_SqlStmt *stmt, uint32_t idx, const void *val, int32_t len, void (*freeFunc)(void *))
150 {
151     if (GRD_KVApiInfo.DBSqlBindBlob == nullptr) {
152         GRD_KVApiInfo = GetApiInfoInstance();
153     }
154     if (GRD_KVApiInfo.DBSqlBindBlob == nullptr) {
155         return E_NOT_SUPPORT;
156     }
157     if (len <= 0) {
158         LOG_ERROR("Invalid len %{public}d", len);
159         return E_INVALID_ARGS;
160     }
161     uint8_t *tmpVal = new uint8_t[len]();
162     if (tmpVal == nullptr) {
163         return E_ERROR;
164     }
165     errno_t err = memcpy_s(tmpVal, len * sizeof(uint8_t), val, len * sizeof(uint8_t));
166     if (err < 0) {
167         delete[] tmpVal;
168         LOG_ERROR("BindBlob failed due to memcpy %{public}d, len is %{public}d", err, len);
169         return TransferGrdErrno(GRD_INNER_ERR);
170     }
171     if (freeFunc == nullptr) {
172         freeFunc = RdSqlFreeBlob;
173     }
174     return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindBlob(stmt, idx, tmpVal, len, freeFunc));
175 }
176 
RdSqlFreeCharStr(void * charStr)177 void RdSqlFreeCharStr(void *charStr)
178 {
179     delete[] ((char *)charStr);
180 }
181 
RdSqlBindText(GRD_SqlStmt * stmt,uint32_t idx,const void * val,int32_t len,void (* freeFunc)(void *))182 int RdUtils::RdSqlBindText(GRD_SqlStmt *stmt, uint32_t idx, const void *val, int32_t len, void (*freeFunc)(void *))
183 {
184     if (GRD_KVApiInfo.DBSqlBindText == nullptr) {
185         GRD_KVApiInfo = GetApiInfoInstance();
186     }
187     if (GRD_KVApiInfo.DBSqlBindText == nullptr) {
188         return E_NOT_SUPPORT;
189     }
190     if (len <= 0) {
191         LOG_ERROR("Invalid len %{public}d", len);
192         return E_INVALID_ARGS;
193     }
194     char *tmpVal = new char[len + 1]();
195     if (tmpVal == nullptr) {
196         return E_ERROR;
197     }
198     errno_t err = strcpy_s(tmpVal, len + 1, (const char *)val);
199     if (err < 0) {
200         LOG_ERROR("BindText failed due to strycpy %{public}d, len is %{public}d", err, len + 1);
201         delete[] tmpVal;
202         return TransferGrdErrno(GRD_INNER_ERR);
203     }
204     if (freeFunc == nullptr) {
205         freeFunc = RdSqlFreeCharStr;
206     }
207     return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindText(stmt, idx, tmpVal, len, freeFunc));
208 }
209 
RdSqlBindInt(GRD_SqlStmt * stmt,uint32_t idx,int32_t val)210 int RdUtils::RdSqlBindInt(GRD_SqlStmt *stmt, uint32_t idx, int32_t val)
211 {
212     if (GRD_KVApiInfo.DBSqlBindInt == nullptr) {
213         GRD_KVApiInfo = GetApiInfoInstance();
214     }
215     if (GRD_KVApiInfo.DBSqlBindInt == nullptr) {
216         return E_NOT_SUPPORT;
217     }
218     return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindInt(stmt, idx, val));
219 }
220 
RdSqlBindInt64(GRD_SqlStmt * stmt,uint32_t idx,int64_t val)221 int RdUtils::RdSqlBindInt64(GRD_SqlStmt *stmt, uint32_t idx, int64_t val)
222 {
223     if (GRD_KVApiInfo.DBSqlBindInt64 == nullptr) {
224         GRD_KVApiInfo = GetApiInfoInstance();
225     }
226     if (GRD_KVApiInfo.DBSqlBindInt64 == nullptr) {
227         return E_NOT_SUPPORT;
228     }
229     return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindInt64(stmt, idx, val));
230 }
231 
RdSqlBindDouble(GRD_SqlStmt * stmt,uint32_t idx,double val)232 int RdUtils::RdSqlBindDouble(GRD_SqlStmt *stmt, uint32_t idx, double val)
233 {
234     if (GRD_KVApiInfo.DBSqlBindDouble == nullptr) {
235         GRD_KVApiInfo = GetApiInfoInstance();
236     }
237     if (GRD_KVApiInfo.DBSqlBindDouble == nullptr) {
238         return E_NOT_SUPPORT;
239     }
240     return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindDouble(stmt, idx, val));
241 }
242 
RdSqlBindNull(GRD_SqlStmt * stmt,uint32_t idx)243 int RdUtils::RdSqlBindNull(GRD_SqlStmt *stmt, uint32_t idx)
244 {
245     if (GRD_KVApiInfo.DBSqlBindNull == nullptr) {
246         GRD_KVApiInfo = GetApiInfoInstance();
247     }
248     if (GRD_KVApiInfo.DBSqlBindNull == nullptr) {
249         return E_NOT_SUPPORT;
250     }
251     return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindNull(stmt, idx));
252 }
253 
RdSqlFreeFloatArr(void * floatElement)254 void RdSqlFreeFloatArr(void *floatElement)
255 {
256     delete[] ((float *)floatElement);
257 }
258 
RdSqlBindFloatVector(GRD_SqlStmt * stmt,uint32_t idx,float * val,uint32_t dim,void (* freeFunc)(void *))259 int RdUtils::RdSqlBindFloatVector(GRD_SqlStmt *stmt, uint32_t idx, float *val,
260     uint32_t dim, void (*freeFunc)(void *))
261 {
262     if (GRD_KVApiInfo.DBSqlBindFloatVector == nullptr) {
263         GRD_KVApiInfo = GetApiInfoInstance();
264     }
265     if (GRD_KVApiInfo.DBSqlBindFloatVector == nullptr) {
266         return E_NOT_SUPPORT;
267     }
268     if (dim <= 0) {
269         LOG_ERROR("Invalid dim %{public}d", dim);
270         return E_INVALID_ARGS;
271     }
272     float *tmpVal = new float[dim]();
273     if (tmpVal == nullptr) {
274         return E_ERROR;
275     }
276     errno_t err = memcpy_s(tmpVal, dim * sizeof(float), val, dim * sizeof(float));
277     if (err < 0) {
278         delete[] tmpVal;
279         LOG_ERROR("BindFloat failed due to memcpy %{public}d, dim is %{public}d", err, dim);
280         return TransferGrdErrno(GRD_INNER_ERR);
281     }
282     if (freeFunc == nullptr) {
283         freeFunc = RdSqlFreeFloatArr;
284     }
285     return TransferGrdErrno(GRD_KVApiInfo.DBSqlBindFloatVector(stmt, idx, tmpVal, dim, freeFunc));
286 }
287 
RdSqlStep(GRD_SqlStmt * stmt)288 int RdUtils::RdSqlStep(GRD_SqlStmt *stmt)
289 {
290     if (GRD_KVApiInfo.DBSqlStep == nullptr) {
291         GRD_KVApiInfo = GetApiInfoInstance();
292     }
293     if (GRD_KVApiInfo.DBSqlStep == nullptr) {
294         return E_NOT_SUPPORT;
295     }
296     return TransferGrdErrno(GRD_KVApiInfo.DBSqlStep(stmt));
297 }
298 
RdSqlColCnt(GRD_SqlStmt * stmt)299 int RdUtils::RdSqlColCnt(GRD_SqlStmt *stmt)
300 {
301     if (GRD_KVApiInfo.DBSqlColCnt == nullptr) {
302         GRD_KVApiInfo = GetApiInfoInstance();
303     }
304     if (GRD_KVApiInfo.DBSqlColCnt == nullptr) {
305         return E_NOT_SUPPORT;
306     }
307     return TransferGrdErrno(GRD_KVApiInfo.DBSqlColCnt(stmt));
308 }
309 
RdSqlColType(GRD_SqlStmt * stmt,uint32_t idx)310 ColumnType RdUtils::RdSqlColType(GRD_SqlStmt *stmt, uint32_t idx)
311 {
312     if (GRD_KVApiInfo.DBSqlColType == nullptr) {
313         GetApiInfoInstance();
314     }
315     if (GRD_KVApiInfo.DBSqlColType == nullptr) {
316         return TransferGrdTypeToColType(0); // for invalid
317     }
318     return TransferGrdTypeToColType(GRD_KVApiInfo.DBSqlColType(stmt, idx));
319 }
320 
RdSqlColBytes(GRD_SqlStmt * stmt,uint32_t idx)321 int RdUtils::RdSqlColBytes(GRD_SqlStmt *stmt, uint32_t idx)
322 {
323     if (GRD_KVApiInfo.DBSqlColBytes == nullptr) {
324         GRD_KVApiInfo = GetApiInfoInstance();
325     }
326     if (GRD_KVApiInfo.DBSqlColBytes == nullptr) {
327         return E_NOT_SUPPORT;
328     }
329     return TransferGrdErrno(GRD_KVApiInfo.DBSqlColBytes(stmt, idx));
330 }
331 
RdSqlColName(GRD_SqlStmt * stmt,uint32_t idx)332 char *RdUtils::RdSqlColName(GRD_SqlStmt *stmt, uint32_t idx)
333 {
334     if (GRD_KVApiInfo.DBSqlColName == nullptr) {
335         GRD_KVApiInfo = GetApiInfoInstance();
336     }
337     if (GRD_KVApiInfo.DBSqlColName == nullptr) {
338         return nullptr;
339     }
340     return GRD_KVApiInfo.DBSqlColName(stmt, idx);
341 }
342 
RdSqlColValue(GRD_SqlStmt * stmt,uint32_t idx)343 GRD_DbValueT RdUtils::RdSqlColValue(GRD_SqlStmt *stmt, uint32_t idx)
344 {
345     if (GRD_KVApiInfo.DBSqlColValue == nullptr) {
346         GRD_KVApiInfo = GetApiInfoInstance();
347     }
348     if (GRD_KVApiInfo.DBSqlColValue == nullptr) {
349         return {};
350     }
351     return GRD_KVApiInfo.DBSqlColValue(stmt, idx);
352 }
353 
RdSqlColBlob(GRD_SqlStmt * stmt,uint32_t idx)354 uint8_t *RdUtils::RdSqlColBlob(GRD_SqlStmt *stmt, uint32_t idx)
355 {
356     if (GRD_KVApiInfo.DBSqlColBlob == nullptr) {
357         GRD_KVApiInfo = GetApiInfoInstance();
358     }
359     if (GRD_KVApiInfo.DBSqlColBlob == nullptr) {
360         return nullptr;
361     }
362     return GRD_KVApiInfo.DBSqlColBlob(stmt, idx);
363 }
364 
RdSqlColText(GRD_SqlStmt * stmt,uint32_t idx)365 char *RdUtils::RdSqlColText(GRD_SqlStmt *stmt, uint32_t idx)
366 {
367     if (GRD_KVApiInfo.DBSqlColText == nullptr) {
368         GRD_KVApiInfo = GetApiInfoInstance();
369     }
370     if (GRD_KVApiInfo.DBSqlColText == nullptr) {
371         return nullptr;
372     }
373     return GRD_KVApiInfo.DBSqlColText(stmt, idx);
374 }
375 
RdSqlColInt(GRD_SqlStmt * stmt,uint32_t idx)376 int RdUtils::RdSqlColInt(GRD_SqlStmt *stmt, uint32_t idx)
377 {
378     if (GRD_KVApiInfo.DBSqlColInt == nullptr) {
379         GRD_KVApiInfo = GetApiInfoInstance();
380     }
381     if (GRD_KVApiInfo.DBSqlColInt == nullptr) {
382         return 0;
383     }
384     return GRD_KVApiInfo.DBSqlColInt(stmt, idx);
385 }
386 
RdSqlColInt64(GRD_SqlStmt * stmt,uint32_t idx)387 uint64_t RdUtils::RdSqlColInt64(GRD_SqlStmt *stmt, uint32_t idx)
388 {
389     if (GRD_KVApiInfo.DBSqlColInt64 == nullptr) {
390         GRD_KVApiInfo = GetApiInfoInstance();
391     }
392     if (GRD_KVApiInfo.DBSqlColInt64 == nullptr) {
393         return 0;
394     }
395     return GRD_KVApiInfo.DBSqlColInt64(stmt, idx);
396 }
397 
RdSqlColDouble(GRD_SqlStmt * stmt,uint32_t idx)398 double RdUtils::RdSqlColDouble(GRD_SqlStmt *stmt, uint32_t idx)
399 {
400     if (GRD_KVApiInfo.DBSqlColDouble == nullptr) {
401         GRD_KVApiInfo = GetApiInfoInstance();
402     }
403     if (GRD_KVApiInfo.DBSqlColDouble == nullptr) {
404         return 0;
405     }
406     return GRD_KVApiInfo.DBSqlColDouble(stmt, idx);
407 }
408 
RdSqlColumnFloatVector(GRD_SqlStmt * stmt,uint32_t idx,uint32_t * dim)409 const float *RdUtils::RdSqlColumnFloatVector(GRD_SqlStmt *stmt, uint32_t idx, uint32_t *dim)
410 {
411     if (GRD_KVApiInfo.DBSqlColumnFloatVector == nullptr) {
412         GRD_KVApiInfo = GetApiInfoInstance();
413     }
414     if (GRD_KVApiInfo.DBSqlColumnFloatVector == nullptr) {
415         return nullptr;
416     }
417     return GRD_KVApiInfo.DBSqlColumnFloatVector(stmt, idx, dim);
418 }
419 
RdDbBackup(GRD_DB * db,const char * backupDbFile,uint8_t * encryptedKey,uint32_t encryptedKeyLen)420 int RdUtils::RdDbBackup(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen)
421 {
422     if (GRD_KVApiInfo.DBBackupApi == nullptr) {
423         GRD_KVApiInfo = GetApiInfoInstance();
424     }
425     if (GRD_KVApiInfo.DBBackupApi == nullptr) {
426         return E_NOT_SUPPORT;
427     }
428     return TransferGrdErrno(GRD_KVApiInfo.DBBackupApi(db, backupDbFile, encryptedKey, encryptedKeyLen));
429 }
430 
RdDbRestore(GRD_DB * db,const char * backupDbFile,uint8_t * encryptedKey,uint32_t encryptedKeyLen)431 int RdUtils::RdDbRestore(GRD_DB *db, const char *backupDbFile, uint8_t *encryptedKey, uint32_t encryptedKeyLen)
432 {
433     if (GRD_KVApiInfo.DBRestoreApi == nullptr) {
434         GRD_KVApiInfo = GetApiInfoInstance();
435     }
436     if (GRD_KVApiInfo.DBRestoreApi == nullptr) {
437         return E_NOT_SUPPORT;
438     }
439     return TransferGrdErrno(GRD_KVApiInfo.DBRestoreApi(db, backupDbFile, encryptedKey, encryptedKeyLen));
440 }
441 
RdDbGetVersion(GRD_DB * db,GRD_ConfigTypeE type,int & version)442 int RdUtils::RdDbGetVersion(GRD_DB *db, GRD_ConfigTypeE type, int &version)
443 {
444     if (GRD_KVApiInfo.DBGetConfigApi == nullptr) {
445         GRD_KVApiInfo = GetApiInfoInstance();
446     }
447     if (GRD_KVApiInfo.DBGetConfigApi == nullptr) {
448         return E_NOT_SUPPORT;
449     }
450     GRD_DbValueT value = GRD_KVApiInfo.DBGetConfigApi(db, type);
451     version = value.value.longValue;
452     return E_OK;
453 }
454 
RdDbSetVersion(GRD_DB * db,GRD_ConfigTypeE type,int version)455 int RdUtils::RdDbSetVersion(GRD_DB *db, GRD_ConfigTypeE type, int version)
456 {
457     if (GRD_KVApiInfo.DBSetConfigApi == nullptr) {
458         GRD_KVApiInfo = GetApiInfoInstance();
459     }
460     if (GRD_KVApiInfo.DBSetConfigApi == nullptr) {
461         return E_NOT_SUPPORT;
462     }
463     GRD_DbValueT value;
464     value.type = GRD_DB_DATATYPE_INTEGER;
465     value.value.longValue = version;
466     return TransferGrdErrno(GRD_KVApiInfo.DBSetConfigApi(db, type, value));
467 }
468 
469 } // namespace NativeRdb
470 } // namespace OHOS
471