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