1 /*
2  * Copyright (c) 2022-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 
16 #include "sqlite3_utils.h"
17 
18 #include <securec.h>
19 #include <string.h>
20 #include <sys/stat.h>
21 
22 #include "comm_log.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_errcode.h"
25 
26 #define SQL_DEFAULT_LEN 256
27 
28 /* The index of database context state */
29 #define DB_STATE_QUERYING    (0x1)
30 #define DB_STATE_TRANSACTION (0x1 << 1)
31 
32 typedef int32_t (*BindParaCb)(DbContext *ctx, int32_t paraNum, uint8_t *data);
33 typedef int32_t (*QueryDataCb)(DbContext *ctx, uint8_t *data, int32_t idx);
34 
35 typedef struct {
36     const char *tableName;
37     const char *sqlForCreate;
38     const char *sqlForInsert;
39     const char *sqlForSearchByKey;
40     const char *sqlForRemoveByKey;
41     BindParaCb insertCb;
42     BindParaCb searchCb;
43     BindParaCb removeCb;
44     QueryDataCb queryDataCb;
45 } SqliteManager;
46 
47 /* The default SQL statement */
48 #define SQL_DROP_TABLE            "DROP TABLE "
49 #define SQL_REMOVE_ALL_RECORD     "DELETE FROM "
50 #define SQL_BEGIN_TRANSACTION     "BEGIN TRANSACTION"
51 #define SQL_COMMIT_TRANSACTION    "COMMIT TRANSACTION"
52 #define SQL_ROLLBACK_TRANSACTION  "ROLLBACK TRANSACTION"
53 #define SQL_SEARCH_IF_TABLE_EXIST "SELECT * FROM sqlite_master WHERE type ='table' AND name = '%s'"
54 
55 /**
56  * @brief The SQL statement of TrustedDeviceInfo table.
57  *
58  * This table is used to store the trusted relationship, and its name is TrustedDeviceInfo in {@link DATABASE_NAME}.
59  * After each networking, record the udid value according to the device account.
60  */
61 #define TABLE_NAME_OF_TRUSTED_DEV_INFO "TrustedDeviceInfo"
62 #define SQL_CREATE_TRUSTED_DEV_INFO_TABLE "CREATE TABLE IF NOT EXISTS "TABLE_NAME_OF_TRUSTED_DEV_INFO" \
63     (accountHash TEXT NOT NULL, \
64     udid TEXT NOT NULL, \
65     primary key(accountHash, udid));"
66 #define SQL_INSERT_TRUSTED_DEV_INFO "INSERT INTO "TABLE_NAME_OF_TRUSTED_DEV_INFO" \
67     (accountHash, udid) VALUES (?, ?)"
68 #define SQL_SEARCH_TRUSTED_DEV_INFO_BY_ID "SELECT udid FROM "TABLE_NAME_OF_TRUSTED_DEV_INFO" \
69     WHERE accountHash = ?"
70 #define SQL_REMOVE_TRUSTED_DEV_INFO_BY_ID "DELETE FROM "TABLE_NAME_OF_TRUSTED_DEV_INFO" \
71     WHERE accountHash = ? AND udid = ?"
72 
73 static int32_t BindInsertTrustedDevInfoCb(DbContext *ctx, int32_t paraNum, uint8_t *data);
74 static int32_t BindSelectTrustedDevInfoCb(DbContext *ctx, int32_t paraNum, uint8_t *data);
75 static int32_t GetTrustedDevInfoByIdCb(DbContext *ctx, uint8_t *data, int32_t idx);
76 
77 static SqliteManager g_sqliteMgr[TABLE_NAME_ID_MAX] = {
78     [TABLE_TRUSTED_DEV_INFO] = {
79         .tableName = TABLE_NAME_OF_TRUSTED_DEV_INFO,
80         .sqlForCreate = SQL_CREATE_TRUSTED_DEV_INFO_TABLE,
81         .sqlForInsert = SQL_INSERT_TRUSTED_DEV_INFO,
82         .sqlForSearchByKey = SQL_SEARCH_TRUSTED_DEV_INFO_BY_ID,
83         .sqlForRemoveByKey = SQL_REMOVE_TRUSTED_DEV_INFO_BY_ID,
84         .insertCb = BindInsertTrustedDevInfoCb,
85         .searchCb = BindSelectTrustedDevInfoCb,
86         .removeCb = BindInsertTrustedDevInfoCb,
87         .queryDataCb = GetTrustedDevInfoByIdCb,
88     },
89 };
90 
GetTrustedDevInfoByIdCb(DbContext * ctx,uint8_t * data,int32_t idx)91 static int32_t GetTrustedDevInfoByIdCb(DbContext *ctx, uint8_t *data, int32_t idx)
92 {
93     int32_t i = 0;
94     char *info = (char *)data + idx * UDID_BUF_LEN;
95 
96     if (GetQueryResultColText(ctx, i, info, UDID_BUF_LEN) != SOFTBUS_OK) {
97         COMM_LOGE(COMM_UTILS, "get query result failed");
98         return SOFTBUS_ERR;
99     }
100     return SOFTBUS_OK;
101 }
102 
BindInsertTrustedDevInfoCb(DbContext * ctx,int32_t paraNum,uint8_t * data)103 static int32_t BindInsertTrustedDevInfoCb(DbContext *ctx, int32_t paraNum, uint8_t *data)
104 {
105     int32_t rc;
106     int32_t idx = 1;
107 
108     if (data == NULL) {
109         return SQLITE_ERROR;
110     }
111     const TrustedDevInfoRecord *record = (TrustedDevInfoRecord *)data;
112     rc = BindParaText(ctx, idx, record->accountHexHash, strlen(record->accountHexHash));
113     if (rc != SQLITE_OK) {
114         return rc;
115     }
116     return BindParaText(ctx, ++idx, record->udid, strlen(record->udid));
117 }
118 
BindSelectTrustedDevInfoCb(DbContext * ctx,int32_t paraNum,uint8_t * data)119 static int32_t BindSelectTrustedDevInfoCb(DbContext *ctx, int32_t paraNum, uint8_t *data)
120 {
121     int32_t idx = 1;
122 
123     if (data == NULL) {
124         COMM_LOGE(COMM_UTILS, "invalid param");
125         return SQLITE_ERROR;
126     }
127     return BindParaText(ctx, idx, (char *)data, strlen((char *)data));
128 }
129 
ExecuteSql(DbContext * ctx,const char * sql,uint32_t len,BindParaCb cb,uint8_t * data)130 static int32_t ExecuteSql(DbContext *ctx, const char *sql, uint32_t len, BindParaCb cb, uint8_t *data)
131 {
132     int32_t paraNum;
133     int32_t rc;
134 
135     if (sql == NULL || sql[0] == '\0') {
136         COMM_LOGE(COMM_UTILS, "execute sql get invalid param");
137         return SQLITE_ERROR;
138     }
139     rc = sqlite3_prepare_v2(ctx->db, sql, len, &ctx->stmt, NULL);
140     if (rc != SQLITE_OK || ctx->stmt == NULL) {
141         COMM_LOGE(COMM_UTILS, "sqlite3_prepare_v2 failed, errmsg=%{public}s", sqlite3_errmsg(ctx->db));
142         return sqlite3_errcode(ctx->db);
143     }
144     paraNum = sqlite3_bind_parameter_count(ctx->stmt);
145     if (paraNum <= 0) {
146         rc = sqlite3_step(ctx->stmt);
147         if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
148             COMM_LOGE(COMM_UTILS, "sqlite3_step <= 0 failed, errmsg=%{public}s", sqlite3_errmsg(ctx->db));
149         }
150         return rc;
151     }
152     if (cb == NULL) {
153         COMM_LOGE(COMM_UTILS, "need cd for binding parameter");
154         (void)sqlite3_finalize(ctx->stmt);
155         ctx->stmt = NULL;
156         return SQLITE_ERROR;
157     }
158     rc = cb(ctx, paraNum, data);
159     if (rc != SQLITE_OK) {
160         COMM_LOGE(COMM_UTILS, "binding parameter cd fail");
161         (void)sqlite3_finalize(ctx->stmt);
162         ctx->stmt = NULL;
163         return sqlite3_errcode(ctx->db);
164     }
165     rc = sqlite3_step(ctx->stmt);
166     if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
167         COMM_LOGE(COMM_UTILS, "sqlite3_step > 0 failed, errmsg=%{public}s", sqlite3_errmsg(ctx->db));
168     }
169     return rc;
170 }
171 
QueryData(DbContext * ctx,const char * sql,uint32_t len,BindParaCb cb,uint8_t * data)172 static int32_t QueryData(DbContext *ctx, const char *sql, uint32_t len, BindParaCb cb, uint8_t *data)
173 {
174     int32_t rc;
175 
176     rc = ExecuteSql(ctx, sql, len, cb, data);
177     if (rc != SQLITE_ROW) {
178         (void)sqlite3_finalize(ctx->stmt);
179         ctx->stmt = NULL;
180     } else {
181         ctx->state |= DB_STATE_QUERYING;
182     }
183     COMM_LOGD(COMM_UTILS, "QueryData done, state=%{public}d", ctx->state);
184     return rc;
185 }
186 
QueryDataNext(DbContext * ctx)187 static int32_t QueryDataNext(DbContext *ctx)
188 {
189     int32_t rc;
190 
191     rc = sqlite3_step(ctx->stmt);
192     if (rc != SQLITE_ROW) {
193         ctx->state &= ~DB_STATE_QUERYING;
194         (void)sqlite3_finalize(ctx->stmt);
195         ctx->stmt = NULL;
196     }
197     COMM_LOGD(COMM_UTILS, "QueryDataNext done, state=%{public}d", ctx->state);
198     return rc;
199 }
200 
CheckDbContextParam(const DbContext * ctx)201 static bool CheckDbContextParam(const DbContext *ctx)
202 {
203     if (ctx == NULL) {
204         COMM_LOGE(COMM_UTILS, "invalid parameters");
205         return false;
206     }
207     if (ctx->db == NULL || ctx->stmt != NULL) {
208         COMM_LOGE(COMM_UTILS, "invalid db context state");
209         return false;
210     }
211     return true;
212 }
213 
CheckBindOrQueryParam(const DbContext * ctx)214 static bool CheckBindOrQueryParam(const DbContext *ctx)
215 {
216     if (ctx == NULL) {
217         COMM_LOGE(COMM_UTILS, "invalid db context parameters");
218         return false;
219     }
220     if (ctx->db == NULL || ctx->stmt == NULL) {
221         COMM_LOGE(COMM_UTILS, "invalid db context state");
222         return false;
223     }
224     return true;
225 }
226 
OpenDatabase(DbContext ** ctx)227 int32_t OpenDatabase(DbContext **ctx)
228 {
229     int32_t rc;
230     sqlite3 *sqlite = NULL;
231 
232     if (ctx == NULL) {
233         COMM_LOGE(COMM_UTILS, "invalid parameters");
234         return SOFTBUS_INVALID_PARAM;
235     }
236     mode_t mode = S_IRUSR | S_IWUSR;
237     rc =
238         sqlite3_open_v2(DATABASE_NAME, &sqlite, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, NULL);
239     if (rc != SQLITE_OK || sqlite == NULL || chmod(DATABASE_NAME, mode) != SOFTBUS_OK) {
240         COMM_LOGE(COMM_UTILS, "sqlite3_open_v2 fail: errmsg=%{public}s", sqlite3_errmsg(sqlite));
241         (void)sqlite3_close_v2(sqlite);
242         return SOFTBUS_ERR;
243     }
244     *ctx = (DbContext *)SoftBusCalloc(sizeof(DbContext));
245     if (*ctx == NULL) {
246         COMM_LOGE(COMM_UTILS, "malloc DbContext fail");
247         (void)sqlite3_close_v2(sqlite);
248         return SOFTBUS_MALLOC_ERR;
249     } else {
250         (*ctx)->db = sqlite;
251     }
252     return SOFTBUS_OK;
253 }
254 
CloseDatabase(DbContext * ctx)255 int32_t CloseDatabase(DbContext *ctx)
256 {
257     if (!CheckDbContextParam(ctx)) {
258         COMM_LOGE(COMM_UTILS, "invalid parameters");
259         return SOFTBUS_INVALID_PARAM;
260     }
261     (void)sqlite3_close_v2(ctx->db);
262     SoftBusFree(ctx);
263     return SOFTBUS_OK;
264 }
265 
CreateTable(DbContext * ctx,TableNameID id)266 int32_t CreateTable(DbContext *ctx, TableNameID id)
267 {
268     int32_t rc;
269     char *errMsg = NULL;
270 
271     if (!CheckDbContextParam(ctx)) {
272         COMM_LOGE(COMM_UTILS, "invalid parameters");
273         return SOFTBUS_INVALID_PARAM;
274     }
275     const char *sql = g_sqliteMgr[id].sqlForCreate;
276     if (sql == NULL || sql[0] == '\0') {
277         COMM_LOGE(COMM_UTILS, "createsql is not impl");
278         return SOFTBUS_ERR;
279     }
280     rc = sqlite3_exec(ctx->db, sql, NULL, NULL, &errMsg);
281     if (rc != SQLITE_OK && errMsg != NULL) {
282         COMM_LOGE(COMM_UTILS, "sqlite_exec fail: errmsg=%{public}s", errMsg);
283         sqlite3_free(errMsg);
284     }
285     return rc == SQLITE_OK ? SOFTBUS_OK : SOFTBUS_ERR;
286 }
287 
DeleteTable(DbContext * ctx,TableNameID id)288 int32_t DeleteTable(DbContext *ctx, TableNameID id)
289 {
290     int32_t rc;
291     char sql[SQL_DEFAULT_LEN] = { 0 };
292 
293     if (!CheckDbContextParam(ctx)) {
294         COMM_LOGE(COMM_UTILS, "invalid parameters");
295         return SOFTBUS_INVALID_PARAM;
296     }
297     rc = sprintf_s(sql, SQL_DEFAULT_LEN, "%s%s", SQL_DROP_TABLE, g_sqliteMgr[id].tableName);
298     if (rc < 0) {
299         COMM_LOGE(COMM_UTILS, "sprintf_s sql fail");
300         return SOFTBUS_ERR;
301     }
302     rc = ExecuteSql(ctx, sql, strlen(sql), NULL, NULL);
303     if (rc != SQLITE_DONE) {
304         COMM_LOGE(COMM_UTILS, "delete table fail");
305         rc = SOFTBUS_ERR;
306     } else {
307         rc = SOFTBUS_OK;
308     }
309     (void)sqlite3_finalize(ctx->stmt);
310     ctx->stmt = NULL;
311     return rc;
312 }
313 
CheckTableExist(DbContext * ctx,TableNameID id,bool * isExist)314 int32_t CheckTableExist(DbContext *ctx, TableNameID id, bool *isExist)
315 {
316     int32_t rc;
317     char sql[SQL_DEFAULT_LEN] = { 0 };
318 
319     if (!CheckDbContextParam(ctx) || isExist == NULL) {
320         COMM_LOGE(COMM_UTILS, "invalid parameters");
321         return SOFTBUS_INVALID_PARAM;
322     }
323     rc = sprintf_s(sql, SQL_DEFAULT_LEN, SQL_SEARCH_IF_TABLE_EXIST, g_sqliteMgr[id].tableName);
324     if (rc < 0) {
325         COMM_LOGE(COMM_UTILS, "sprintf_s sql fail");
326         return SOFTBUS_ERR;
327     }
328     *isExist = false;
329     rc = ExecuteSql(ctx, sql, strlen(sql), NULL, NULL);
330     if (rc == SQLITE_ROW && sqlite3_column_count(ctx->stmt) != 0) {
331         *isExist = true;
332     }
333     (void)sqlite3_finalize(ctx->stmt);
334     ctx->stmt = NULL;
335     return SOFTBUS_OK;
336 }
337 
InsertRecord(DbContext * ctx,TableNameID id,uint8_t * data)338 int32_t InsertRecord(DbContext *ctx, TableNameID id, uint8_t *data)
339 {
340     int32_t rc;
341 
342     if (!CheckDbContextParam(ctx) || data == NULL) {
343         COMM_LOGE(COMM_UTILS, "invalid parameters");
344         return SOFTBUS_INVALID_PARAM;
345     }
346     rc = ExecuteSql(
347         ctx, g_sqliteMgr[id].sqlForInsert, strlen(g_sqliteMgr[id].sqlForInsert), g_sqliteMgr[id].insertCb, data);
348     if (rc != SQLITE_DONE) {
349         COMM_LOGE(COMM_UTILS, "insert data failed");
350         rc = SOFTBUS_ERR;
351     } else {
352         rc = SOFTBUS_OK;
353     }
354     (void)sqlite3_finalize(ctx->stmt);
355     ctx->stmt = NULL;
356     COMM_LOGD(COMM_UTILS, "insert data done");
357     return rc;
358 }
359 
RemoveRecordByKey(DbContext * ctx,TableNameID id,uint8_t * data)360 int32_t RemoveRecordByKey(DbContext *ctx, TableNameID id, uint8_t *data)
361 {
362     int32_t rc;
363 
364     if (!CheckDbContextParam(ctx) || data == NULL) {
365         COMM_LOGE(COMM_UTILS, "invalid parameters");
366         return SOFTBUS_INVALID_PARAM;
367     }
368     rc = ExecuteSql(ctx, g_sqliteMgr[id].sqlForRemoveByKey, strlen(g_sqliteMgr[id].sqlForRemoveByKey),
369         g_sqliteMgr[id].removeCb, data);
370     if (rc != SQLITE_DONE) {
371         COMM_LOGE(COMM_UTILS, "remove data failed");
372         rc = SOFTBUS_ERR;
373     } else {
374         rc = SOFTBUS_OK;
375     }
376     (void)sqlite3_finalize(ctx->stmt);
377     ctx->stmt = NULL;
378     COMM_LOGD(COMM_UTILS, "remove data done");
379     return rc;
380 }
381 
RemoveAllRecord(DbContext * ctx,TableNameID id)382 int32_t RemoveAllRecord(DbContext *ctx, TableNameID id)
383 {
384     int32_t rc;
385     char sql[SQL_DEFAULT_LEN] = { 0 };
386 
387     if (!CheckDbContextParam(ctx)) {
388         COMM_LOGE(COMM_UTILS, "invalid parameters");
389         return SOFTBUS_INVALID_PARAM;
390     }
391     rc = sprintf_s(sql, SQL_DEFAULT_LEN, "%s%s", SQL_REMOVE_ALL_RECORD, g_sqliteMgr[id].tableName);
392     if (rc < 0) {
393         COMM_LOGE(COMM_UTILS, "sprintf_s sql fail");
394         return SOFTBUS_ERR;
395     }
396     rc = ExecuteSql(ctx, sql, strlen(sql), NULL, NULL);
397     if (rc != SQLITE_DONE) {
398         COMM_LOGE(COMM_UTILS, "remove data failed");
399         rc = SOFTBUS_ERR;
400     } else {
401         rc = SOFTBUS_OK;
402     }
403     (void)sqlite3_finalize(ctx->stmt);
404     ctx->stmt = NULL;
405     COMM_LOGD(COMM_UTILS, "remove data done");
406     return rc;
407 }
408 
GetRecordNumByKey(DbContext * ctx,TableNameID id,uint8_t * data)409 int32_t GetRecordNumByKey(DbContext *ctx, TableNameID id, uint8_t *data)
410 {
411     int32_t rc;
412     int32_t num = 0;
413 
414     if (!CheckDbContextParam(ctx) || data == NULL) {
415         COMM_LOGE(COMM_UTILS, "invalid parameters");
416         return 0;
417     }
418     rc = QueryData(ctx, g_sqliteMgr[id].sqlForSearchByKey, strlen(g_sqliteMgr[id].sqlForSearchByKey),
419         g_sqliteMgr[id].searchCb, data);
420     if (rc != SQLITE_ROW) {
421         COMM_LOGE(COMM_UTILS, "find no match data");
422         return 0;
423     }
424     do {
425         num++;
426         rc = QueryDataNext(ctx);
427     } while (rc == SQLITE_ROW);
428     if (rc != SQLITE_DONE) {
429         COMM_LOGE(COMM_UTILS, "GetQueryDataNum failed");
430         return 0;
431     }
432     return num;
433 }
434 
QueryRecordByKey(DbContext * ctx,TableNameID id,uint8_t * data,uint8_t ** replyInfo,int32_t infoNum)435 int32_t QueryRecordByKey(DbContext *ctx, TableNameID id, uint8_t *data,
436     uint8_t **replyInfo, int32_t infoNum)
437 {
438     int32_t rc;
439     int32_t num = 0;
440 
441     if (!CheckDbContextParam(ctx) || replyInfo == NULL || data == NULL) {
442         COMM_LOGE(COMM_UTILS, "invalid parameters");
443         return SOFTBUS_INVALID_PARAM;
444     }
445     rc = QueryData(ctx, g_sqliteMgr[id].sqlForSearchByKey, strlen(g_sqliteMgr[id].sqlForSearchByKey),
446         g_sqliteMgr[id].searchCb, data);
447     if (rc != SQLITE_ROW) {
448         return SOFTBUS_ERR;
449     }
450     do {
451         if (g_sqliteMgr[id].queryDataCb != NULL) {
452             g_sqliteMgr[id].queryDataCb(ctx, *replyInfo, num);
453         }
454         rc = QueryDataNext(ctx);
455         num++;
456     } while (rc == SQLITE_ROW && num < infoNum);
457     if (rc != SQLITE_DONE) {
458         if (rc == SQLITE_ROW) {
459             ctx->state &= ~DB_STATE_QUERYING;
460             (void)sqlite3_finalize(ctx->stmt);
461             ctx->stmt = NULL;
462         }
463         COMM_LOGE(COMM_UTILS, "QueryData failed");
464         return SOFTBUS_ERR;
465     }
466     return SOFTBUS_OK;
467 }
468 
OpenTransaction(DbContext * ctx)469 int32_t OpenTransaction(DbContext *ctx)
470 {
471     int32_t rc;
472 
473     if (!CheckDbContextParam(ctx)) {
474         COMM_LOGE(COMM_UTILS, "invalid parameters");
475         return SOFTBUS_INVALID_PARAM;
476     }
477     if ((ctx->state & DB_STATE_TRANSACTION) != 0) {
478         COMM_LOGE(COMM_UTILS, "already open the transaction: state=%{public}d", ctx->state);
479         return SOFTBUS_OK;
480     }
481     rc = ExecuteSql(ctx, SQL_BEGIN_TRANSACTION, strlen(SQL_BEGIN_TRANSACTION), NULL, NULL);
482     if (rc != SQLITE_DONE) {
483         COMM_LOGE(COMM_UTILS, "open transaction failed");
484         rc = SOFTBUS_ERR;
485     } else {
486         ctx->state |= DB_STATE_TRANSACTION;
487         rc = SOFTBUS_OK;
488     }
489     (void)sqlite3_finalize(ctx->stmt);
490     ctx->stmt = NULL;
491     return rc;
492 }
493 
CloseTransaction(DbContext * ctx,CloseTransactionType type)494 int32_t CloseTransaction(DbContext *ctx, CloseTransactionType type)
495 {
496     int32_t rc;
497     const char *sql = SQL_COMMIT_TRANSACTION;
498 
499     if (!CheckDbContextParam(ctx)) {
500         COMM_LOGE(COMM_UTILS, "invalid parameters");
501         return SOFTBUS_INVALID_PARAM;
502     }
503     if ((ctx->state & DB_STATE_TRANSACTION) == 0) {
504         COMM_LOGE(COMM_UTILS, "the transaction already closed: state=%{public}d", ctx->state);
505         return SOFTBUS_OK;
506     }
507     if (type == CLOSE_TRANS_ROLLBACK) {
508         sql = SQL_ROLLBACK_TRANSACTION;
509     }
510     rc = ExecuteSql(ctx, sql, strlen(sql), NULL, NULL);
511     if (rc != SQLITE_DONE) {
512         COMM_LOGE(COMM_UTILS, "close transaction failed");
513         rc = SOFTBUS_ERR;
514     } else {
515         rc = SOFTBUS_OK;
516     }
517     ctx->state &= ~DB_STATE_TRANSACTION;
518     (void)sqlite3_finalize(ctx->stmt);
519     ctx->stmt = NULL;
520     return rc;
521 }
522 
EncryptedDb(DbContext * ctx,const uint8_t * password,uint32_t len)523 int32_t EncryptedDb(DbContext *ctx, const uint8_t *password, uint32_t len)
524 {
525     int32_t rc;
526 
527     if (!CheckDbContextParam(ctx) || password == NULL) {
528         COMM_LOGE(COMM_UTILS, "invalid parameters");
529         return SOFTBUS_INVALID_PARAM;
530     }
531     rc = sqlite3_key(ctx->db, password, len);
532     if (rc != SQLITE_OK) {
533         COMM_LOGE(COMM_UTILS, "config key failed: errmsg=%{public}s", sqlite3_errmsg(ctx->db));
534         return SOFTBUS_ERR;
535     }
536     return SOFTBUS_OK;
537 }
538 
UpdateDbPassword(DbContext * ctx,const uint8_t * password,uint32_t len)539 int32_t UpdateDbPassword(DbContext *ctx, const uint8_t *password, uint32_t len)
540 {
541     int32_t rc;
542 
543     if (!CheckDbContextParam(ctx) || password == NULL) {
544         COMM_LOGE(COMM_UTILS, "invalid parameters");
545         return SOFTBUS_INVALID_PARAM;
546     }
547     rc = sqlite3_rekey(ctx->db, password, len);
548     if (rc != SQLITE_OK) {
549         COMM_LOGE(COMM_UTILS, "update key failed: errmsg=%{public}s", sqlite3_errmsg(ctx->db));
550         return SOFTBUS_ERR;
551     }
552     return SOFTBUS_OK;
553 }
554 
BindParaInt(DbContext * ctx,int32_t idx,int32_t value)555 int32_t BindParaInt(DbContext *ctx, int32_t idx, int32_t value)
556 {
557     int32_t rc;
558 
559     if (!CheckBindOrQueryParam(ctx) || idx <= 0) {
560         COMM_LOGE(COMM_UTILS, "invalid parameters");
561         return SQLITE_ERROR;
562     }
563     rc = sqlite3_bind_int(ctx->stmt, idx, value);
564     if (rc != SQLITE_OK) {
565         COMM_LOGE(COMM_UTILS, "sqlite3_bind_int failed: errmsg=%{public}s", sqlite3_errmsg(ctx->db));
566     }
567     return rc;
568 }
569 
BindParaInt64(DbContext * ctx,int32_t idx,int64_t value)570 int32_t BindParaInt64(DbContext *ctx, int32_t idx, int64_t value)
571 {
572     int32_t rc;
573 
574     if (!CheckBindOrQueryParam(ctx) || idx <= 0) {
575         COMM_LOGE(COMM_UTILS, "invalid parameters");
576         return SQLITE_ERROR;
577     }
578     rc = sqlite3_bind_int64(ctx->stmt, idx, value);
579     if (rc != SQLITE_OK) {
580         COMM_LOGE(COMM_UTILS, "sqlite3_bind_int64 failed: errmsg=%{public}s", sqlite3_errmsg(ctx->db));
581     }
582     return rc;
583 }
584 
BindParaText(DbContext * ctx,int32_t idx,const char * value,uint32_t valueLen)585 int32_t BindParaText(DbContext *ctx, int32_t idx, const char *value, uint32_t valueLen)
586 {
587     int32_t rc;
588 
589     if (!CheckBindOrQueryParam(ctx) || idx <= 0 || value == NULL || value[0] == '\0' || strlen(value) != valueLen) {
590         COMM_LOGE(COMM_UTILS, "invalid parameters");
591         return SQLITE_ERROR;
592     }
593     rc = sqlite3_bind_text(ctx->stmt, idx, value, valueLen, SQLITE_STATIC);
594     if (rc != SQLITE_OK) {
595         COMM_LOGE(COMM_UTILS, "sqlite3_bind_text failed: errmsg=%{public}s", sqlite3_errmsg(ctx->db));
596     }
597     return rc;
598 }
599 
BindParaDouble(DbContext * ctx,int32_t idx,double value)600 int32_t BindParaDouble(DbContext *ctx, int32_t idx, double value)
601 {
602     int32_t rc;
603 
604     if (!CheckBindOrQueryParam(ctx) || idx <= 0) {
605         COMM_LOGE(COMM_UTILS, "invalid parameters");
606         return SQLITE_ERROR;
607     }
608     rc = sqlite3_bind_double(ctx->stmt, idx, value);
609     if (rc != SQLITE_OK) {
610         COMM_LOGE(COMM_UTILS, "sqlite3_bind_double failed: errmsg=%{public}s", sqlite3_errmsg(ctx->db));
611     }
612     return rc;
613 }
614 
GetQueryResultColCount(DbContext * ctx,int32_t * count)615 int32_t GetQueryResultColCount(DbContext *ctx, int32_t *count)
616 {
617     if (!CheckBindOrQueryParam(ctx)) {
618         COMM_LOGE(COMM_UTILS, "invalid parameters");
619         return SOFTBUS_INVALID_PARAM;
620     }
621     if ((ctx->state & DB_STATE_QUERYING) == 0) {
622         COMM_LOGE(COMM_UTILS, "the query already closed: state=%{public}d", ctx->state);
623         return SOFTBUS_ERR;
624     }
625     *count = sqlite3_column_count(ctx->stmt);
626     return SOFTBUS_OK;
627 }
628 
GetQueryResultColText(DbContext * ctx,int32_t iCol,char * text,uint32_t len)629 int32_t GetQueryResultColText(DbContext *ctx, int32_t iCol, char *text, uint32_t len)
630 {
631     const unsigned char *result;
632 
633     if (!CheckBindOrQueryParam(ctx) || iCol < 0 || text == NULL) {
634         COMM_LOGE(COMM_UTILS, "invalid parameters");
635         return SOFTBUS_INVALID_PARAM;
636     }
637     if ((ctx->state & DB_STATE_QUERYING) == 0) {
638         COMM_LOGE(COMM_UTILS, "the query already closed: state=%{public}d", ctx->state);
639         return SOFTBUS_ERR;
640     }
641     if (sqlite3_column_type(ctx->stmt, iCol) != SQLITE_TEXT) {
642         COMM_LOGE(COMM_UTILS, "column type not match");
643         return SOFTBUS_ERR;
644     }
645     result = sqlite3_column_text(ctx->stmt, iCol);
646     if (strcpy_s(text, len, (const char *)result) != EOK) {
647         COMM_LOGE(COMM_UTILS, "strcpy_s fail");
648         return SOFTBUS_ERR;
649     }
650     return SOFTBUS_OK;
651 }
652 
GetQueryResultColInt(DbContext * ctx,int32_t iCol,int32_t * value)653 int32_t GetQueryResultColInt(DbContext *ctx, int32_t iCol, int32_t *value)
654 {
655     if (!CheckBindOrQueryParam(ctx) || iCol < 0 || value == NULL) {
656         COMM_LOGE(COMM_UTILS, "invalid parameters");
657         return SOFTBUS_INVALID_PARAM;
658     }
659     if ((ctx->state & DB_STATE_QUERYING) == 0) {
660         COMM_LOGE(COMM_UTILS, "the query already closed: state=%{public}d", ctx->state);
661         return SOFTBUS_ERR;
662     }
663     if (sqlite3_column_type(ctx->stmt, iCol) != SQLITE_INTEGER) {
664         COMM_LOGE(COMM_UTILS, "column type not match");
665         return SOFTBUS_ERR;
666     }
667     *value = sqlite3_column_int(ctx->stmt, iCol);
668     return SOFTBUS_OK;
669 }
670 
GetQueryResultColInt64(DbContext * ctx,int32_t iCol,int64_t * value)671 int32_t GetQueryResultColInt64(DbContext *ctx, int32_t iCol, int64_t *value)
672 {
673     if (!CheckBindOrQueryParam(ctx) || iCol < 0 || value == NULL) {
674         COMM_LOGE(COMM_UTILS, "invalid parameters");
675         return SOFTBUS_INVALID_PARAM;
676     }
677     if ((ctx->state & DB_STATE_QUERYING) == 0) {
678         COMM_LOGE(COMM_UTILS, "the query already closed: state=%{public}d", ctx->state);
679         return SOFTBUS_ERR;
680     }
681     if (sqlite3_column_type(ctx->stmt, iCol) != SQLITE_INTEGER) {
682         COMM_LOGE(COMM_UTILS, "column type not match");
683         return SOFTBUS_ERR;
684     }
685     *value = sqlite3_column_int64(ctx->stmt, iCol);
686     return SOFTBUS_OK;
687 }
688 
GetQueryResultColDouble(DbContext * ctx,int32_t iCol,double * value)689 int32_t GetQueryResultColDouble(DbContext *ctx, int32_t iCol, double *value)
690 {
691     if (!CheckBindOrQueryParam(ctx) || iCol < 0 || value == NULL) {
692         COMM_LOGE(COMM_UTILS, "invalid parameters");
693         return SOFTBUS_INVALID_PARAM;
694     }
695     if ((ctx->state & DB_STATE_QUERYING) == 0) {
696         COMM_LOGE(COMM_UTILS, "the query already closed: state=%{public}d", ctx->state);
697         return SOFTBUS_ERR;
698     }
699     if (sqlite3_column_type(ctx->stmt, iCol) != SQLITE_FLOAT) {
700         COMM_LOGE(COMM_UTILS, "column type not match");
701         return SOFTBUS_ERR;
702     }
703     *value = sqlite3_column_double(ctx->stmt, iCol);
704     return SOFTBUS_OK;
705 }
706