• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #define LOG_TAG "SqliteStatement"
16 #include "sqlite_statement.h"
17 
18 #include <cstdint>
19 #include <iomanip>
20 #include <memory>
21 #include <sstream>
22 #include <utility>
23 
24 #include "connection_pool.h"
25 #include "logger.h"
26 #include "raw_data_parser.h"
27 #include "rdb_errno.h"
28 #include "rdb_fault_hiview_reporter.h"
29 #include "rdb_sql_log.h"
30 #include "rdb_sql_statistic.h"
31 #include "rdb_perfStat.h"
32 #include "rdb_types.h"
33 #include "relational_store_client.h"
34 #include "remote_result_set.h"
35 #include "share_block.h"
36 #include "shared_block_serializer_info.h"
37 #include "sqlite3.h"
38 #include "sqlite3ext.h"
39 #include "sqlite_connection.h"
40 #include "sqlite_errno.h"
41 #include "sqlite_global_config.h"
42 #include "sqlite_utils.h"
43 #include "string_utils.h"
44 namespace OHOS {
45 namespace NativeRdb {
46 using namespace OHOS::Rdb;
47 using namespace std::chrono;
48 using SqlStatistic = DistributedRdb::SqlStatistic;
49 using PerfStat = DistributedRdb::PerfStat;
50 using Reportor = RdbFaultHiViewReporter;
51 // Setting Data Precision
52 constexpr SqliteStatement::Action SqliteStatement::ACTIONS[ValueObject::TYPE_MAX];
53 static constexpr int ERR_MSG_SIZE = 2;
54 static constexpr const char *ERR_MSG[] = {
55     "no such table:",
56     "no such column:",
57     "has no column named"
58 };
59 
SqliteStatement(const RdbStoreConfig * config)60 SqliteStatement::SqliteStatement(const RdbStoreConfig *config)
61     : readOnly_(false), columnCount_(0), numParameters_(0), stmt_(nullptr), sql_(""), config_(config)
62 {
63     seqId_ = PerfStat::GenerateId();
64     SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL_REF, seqId_);
65     PerfStat perfStat((config_ != nullptr) ? config_->GetPath() : "", "", SqlStatistic::Step::STEP_TOTAL_REF, seqId_);
66 }
67 
~SqliteStatement()68 SqliteStatement::~SqliteStatement()
69 {
70     SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_TOTAL_RES, seqId_);
71     PerfStat perfStat((config_ != nullptr) ? config_->GetPath() : "", "", PerfStat::Step::STEP_TOTAL_RES, seqId_);
72     Finalize();
73     slave_ = nullptr;
74     conn_ = nullptr;
75     config_ = nullptr;
76 }
77 
TableReport(const std::string & errMsg,const std::string & bundleName,ErrMsgState state)78 void SqliteStatement::TableReport(const std::string &errMsg, const std::string &bundleName, ErrMsgState state)
79 {
80     std::string custLog;
81     if (!state.isCreated) {
82         custLog = "table is not created " + errMsg;
83         Reportor::ReportFault(RdbFaultEvent(FT_CURD, E_DFX_IS_NOT_CREATE, bundleName, custLog));
84     } else if (state.isDeleted) {
85         custLog = "table is deleted " + errMsg;
86         Reportor::ReportFault(RdbFaultEvent(FT_CURD, E_DFX_IS_DELETE, bundleName, custLog));
87     } else if (state.isRenamed) {
88         custLog = "table is renamed " + errMsg;
89         Reportor::ReportFault(RdbFaultEvent(FT_CURD, E_DFX_IS_RENAME, bundleName, custLog));
90     } else {
91         custLog = errMsg;
92         Reportor::ReportFault(RdbFaultEvent(FT_CURD, E_DFX_IS_NOT_EXIST, bundleName, custLog));
93     }
94 }
95 
ColumnReport(const std::string & errMsg,const std::string & bundleName,ErrMsgState state)96 void SqliteStatement::ColumnReport(const std::string &errMsg, const std::string &bundleName, ErrMsgState state)
97 {
98     std::string custLog;
99     if (!state.isCreated) {
100         custLog = "column is not created " + errMsg;
101         Reportor::ReportFault(RdbFaultEvent(FT_CURD, E_DFX_IS_NOT_CREATE, bundleName, custLog));
102     } else if (state.isDeleted) {
103         custLog = "column is deleted " + errMsg;
104         Reportor::ReportFault(RdbFaultEvent(FT_CURD, E_DFX_IS_DELETE, bundleName, custLog));
105     } else if (state.isRenamed) {
106         custLog = "column is renamed " + errMsg;
107         Reportor::ReportFault(RdbFaultEvent(FT_CURD, E_DFX_IS_RENAME, bundleName, custLog));
108     } else {
109         custLog = errMsg;
110         Reportor::ReportFault(RdbFaultEvent(FT_CURD, E_DFX_IS_NOT_EXIST, bundleName, custLog));
111     }
112 }
113 
HandleErrMsg(const std::string & errMsg,const std::string & dbPath,const std::string & bundleName)114 void SqliteStatement::HandleErrMsg(const std::string &errMsg, const std::string &dbPath, const std::string &bundleName)
115 {
116     for (auto err: ERR_MSG) {
117         if (errMsg.find(err) == std::string::npos) {
118             continue;
119         }
120         if (err == ERR_MSG[0]) {
121             std::string tableName = SqliteUtils::GetErrInfoFromMsg(errMsg, err);
122             ErrMsgState state = SqliteUtils::CompareTableFileContent(dbPath, bundleName, tableName);
123             TableReport(errMsg, bundleName, state);
124         }
125         if (err == ERR_MSG[1] || err == ERR_MSG[ERR_MSG_SIZE]) {
126             std::string columnName = SqliteUtils::GetErrInfoFromMsg(errMsg, err);
127             ErrMsgState state = SqliteUtils::CompareColumnFileContent(dbPath, bundleName, columnName);
128             ColumnReport(errMsg, bundleName, state);
129         }
130     }
131 }
132 
TryNotifyErrorLog(const int & errCode,sqlite3 * dbHandle,const std::string & sql)133 void SqliteStatement::TryNotifyErrorLog(const int &errCode, sqlite3 *dbHandle, const std::string &sql)
134 {
135     if (errCode == SQLITE_ROW || errCode == SQLITE_DONE || errCode == SQLITE_OK) {
136         return ;
137     }
138     std::string errMsg(sqlite3_errmsg(dbHandle));
139     DistributedRdb::SqlErrorObserver::ExceptionMessage exceMessage;
140     exceMessage.code = errCode;
141     exceMessage.message = std::move(errMsg);
142     exceMessage.sql = sql;
143     NativeRdb::SqlLog::Notify(config_->GetPath(), exceMessage);
144 }
145 
Prepare(sqlite3 * dbHandle,const std::string & newSql)146 int SqliteStatement::Prepare(sqlite3 *dbHandle, const std::string &newSql)
147 {
148     if (sql_.compare(newSql) == 0) {
149         return E_OK;
150     }
151     // prepare the new sqlite3_stmt
152     sqlite3_stmt *stmt = nullptr;
153     SqlStatistic sqlStatistic(newSql, SqlStatistic::Step::STEP_PREPARE, seqId_);
154     PerfStat perfStat((config_ != nullptr) ? config_->GetPath() : "", newSql, PerfStat::Step::STEP_PREPARE, seqId_);
155     int errCode = sqlite3_prepare_v2(dbHandle, newSql.c_str(), newSql.length(), &stmt, nullptr);
156     if (errCode != SQLITE_OK) {
157         std::string errMsg(sqlite3_errmsg(dbHandle));
158         TryNotifyErrorLog(errCode, dbHandle, newSql);
159         if (errMsg.size() != 0) {
160             HandleErrMsg(errMsg, config_->GetPath(), config_->GetBundleName());
161         }
162         if (stmt != nullptr) {
163             sqlite3_finalize(stmt);
164         }
165         if (errCode == SQLITE_NOTADB) {
166             ReadFile2Buffer();
167         }
168         int ret = SQLiteError::ErrNo(errCode);
169         if (config_ != nullptr &&
170             (errCode == SQLITE_CORRUPT || (errCode == SQLITE_NOTADB && config_->GetIter() != 0))) {
171             Reportor::ReportCorruptedOnce(Reportor::Create(*config_, ret,
172                 (errCode == SQLITE_CORRUPT ? SqliteGlobalConfig::GetLastCorruptionMsg() : "SqliteStatement::Prepare")));
173         }
174         if (config_ != nullptr) {
175             Reportor::ReportFault(RdbFaultDbFileEvent(FT_CURD,
176                 (errCode == SQLITE_NOTADB ? E_SQLITE_NOT_DB : ret), *config_, "sqlite3_prepare_v2", true));
177         }
178         PrintInfoForDbError(ret, newSql);
179         return ret;
180     }
181     InnerFinalize(); // finalize the old
182     sql_ = newSql;
183     stmt_ = stmt;
184     readOnly_ = (sqlite3_stmt_readonly(stmt_) != 0);
185     columnCount_ = sqlite3_column_count(stmt_);
186     types_ = std::vector<int32_t>(columnCount_, COLUMN_TYPE_INVALID);
187     numParameters_ = sqlite3_bind_parameter_count(stmt_);
188     return E_OK;
189 }
190 
PrintInfoForDbError(int errCode,const std::string & sql)191 void SqliteStatement::PrintInfoForDbError(int errCode, const std::string &sql)
192 {
193     if (config_ == nullptr) {
194         return;
195     }
196 
197     if (errCode == E_SQLITE_ERROR && sql == std::string(GlobalExpr::PRAGMA_VERSION) + "=?") {
198         return;
199     }
200 
201     if (errCode == E_SQLITE_ERROR || errCode == E_SQLITE_BUSY || errCode == E_SQLITE_LOCKED ||
202         errCode == E_SQLITE_IOERR || errCode == E_SQLITE_CANTOPEN) {
203         LOG_ERROR("DbError errCode:%{public}d errno:%{public}d DbName: %{public}s ", errCode, errno,
204             SqliteUtils::Anonymous(config_->GetName()).c_str());
205     }
206 }
207 
ReadFile2Buffer()208 void SqliteStatement::ReadFile2Buffer()
209 {
210     if (config_ == nullptr) {
211         return;
212     }
213     std::string fileName;
214     if (SqliteGlobalConfig::GetDbPath(*config_, fileName) != E_OK || access(fileName.c_str(), F_OK) != 0) {
215         return;
216     }
217     uint64_t buffer[BUFFER_LEN] = { 0x0 };
218     FILE *file = fopen(fileName.c_str(), "r");
219     if (file == nullptr) {
220         LOG_ERROR(
221             "Open db file failed: %{public}s, errno is %{public}d", SqliteUtils::Anonymous(fileName).c_str(), errno);
222         return;
223     }
224     size_t readSize = fread(buffer, sizeof(uint64_t), BUFFER_LEN, file);
225     if (readSize != BUFFER_LEN) {
226         LOG_ERROR("read db file size: %{public}zu, errno is %{public}d", readSize, errno);
227         (void)fclose(file);
228         return;
229     }
230     constexpr int bufferSize = 4;
231     for (uint32_t i = 0; i < BUFFER_LEN; i += bufferSize) {
232         LOG_WARN("line%{public}d: %{public}" PRIx64 "%{public}" PRIx64 "%{public}" PRIx64 "%{public}" PRIx64, i >> 2,
233             buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3]);
234     }
235     (void)fclose(file);
236 }
237 
BindArgs(const std::vector<ValueObject> & bindArgs)238 int SqliteStatement::BindArgs(const std::vector<ValueObject> &bindArgs)
239 {
240     std::vector<std::reference_wrapper<ValueObject>> refBindArgs;
241     for (auto &object : bindArgs) {
242         refBindArgs.emplace_back(std::ref(const_cast<ValueObject &>(object)));
243     }
244     return BindArgs(refBindArgs);
245 }
246 
BindArgs(const std::vector<std::reference_wrapper<ValueObject>> & bindArgs)247 int SqliteStatement::BindArgs(const std::vector<std::reference_wrapper<ValueObject>> &bindArgs)
248 {
249     SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_PREPARE, seqId_);
250     PerfStat perfStat((config_ != nullptr) ? config_->GetPath() : "", "", PerfStat::Step::STEP_PREPARE, seqId_);
251     if (bound_) {
252         sqlite3_reset(stmt_);
253         sqlite3_clear_bindings(stmt_);
254     }
255     bound_ = true;
256     int index = 1;
257     for (auto &arg : bindArgs) {
258         auto action = ACTIONS[arg.get().value.index()];
259         if (action == nullptr) {
260             LOG_ERROR("not support the type %{public}zu", arg.get().value.index());
261             return E_INVALID_ARGS;
262         }
263         auto errCode = action(stmt_, index, arg.get().value);
264         if (errCode != SQLITE_OK) {
265             LOG_ERROR("Bind has error: %{public}d, sql: %{public}s, errno %{public}d",
266                 errCode, SqliteUtils::SqlAnonymous(sql_).c_str(), errno);
267             return SQLiteError::ErrNo(errCode);
268         }
269         index++;
270     }
271 
272     return E_OK;
273 }
274 
IsValid(int index) const275 int SqliteStatement::IsValid(int index) const
276 {
277     if (stmt_ == nullptr) {
278         LOG_ERROR("statement already close.");
279         return E_ALREADY_CLOSED;
280     }
281 
282     if (index >= columnCount_ || index < 0) {
283         LOG_ERROR("index (%{public}d) is out of range [0, %{public}d]", index, columnCount_ - 1);
284         return E_COLUMN_OUT_RANGE;
285     }
286     return E_OK;
287 }
288 
Prepare(const std::string & sql)289 int SqliteStatement::Prepare(const std::string &sql)
290 {
291     if (stmt_ == nullptr) {
292         return E_ERROR;
293     }
294     auto db = sqlite3_db_handle(stmt_);
295     int errCode = Prepare(db, sql);
296     if (errCode != E_OK) {
297         return errCode;
298     }
299 
300     if (slave_) {
301         int errCode = slave_->Prepare(sql);
302         if (errCode != E_OK) {
303             LOG_WARN("slave prepare Error:%{public}d", errCode);
304             SqliteUtils::SetSlaveInvalid(config_->GetPath());
305         }
306     }
307     return E_OK;
308 }
309 
Bind(const std::vector<ValueObject> & args)310 int SqliteStatement::Bind(const std::vector<ValueObject> &args)
311 {
312     int count = static_cast<int>(args.size());
313     std::vector<ValueObject> abindArgs;
314 
315     if (count == 0) {
316         return E_OK;
317     }
318     // Obtains the bound parameter set.
319     if ((numParameters_ != 0) && (count <= numParameters_)) {
320         for (const auto &i : args) {
321             abindArgs.push_back(i);
322         }
323 
324         for (int i = count; i < numParameters_; i++) { // TD: when count <> numParameters
325             ValueObject val;
326             abindArgs.push_back(val);
327         }
328     }
329 
330     if (count > numParameters_) {
331         LOG_ERROR("bind args count(%{public}d) > numParameters(%{public}d), sql: %{public}s", count, numParameters_,
332             SqliteUtils::SqlAnonymous(sql_).c_str());
333         return E_INVALID_BIND_ARGS_COUNT;
334     }
335 
336     int errCode = BindArgs(abindArgs);
337     if (errCode != E_OK) {
338         return errCode;
339     }
340 
341     if (slave_) {
342         int errCode = slave_->Bind(args);
343         if (errCode != E_OK) {
344             LOG_ERROR("slave bind error:%{public}d", errCode);
345             SqliteUtils::SetSlaveInvalid(config_->GetPath());
346         }
347     }
348     return E_OK;
349 }
350 
Count()351 std::pair<int32_t, int32_t> SqliteStatement::Count()
352 {
353     SharedBlockInfo info(nullptr);
354     info.isCountAllRows = true;
355     info.isFull = true;
356     info.totalRows = -1;
357     auto errCode = FillBlockInfo(&info);
358     if (errCode != E_OK) {
359         return { errCode, INVALID_COUNT };
360     }
361     return { errCode, info.totalRows };
362 }
363 
Step()364 int SqliteStatement::Step()
365 {
366     int ret = InnerStep();
367     if (ret != E_OK) {
368         return ret;
369     }
370     if (slave_) {
371         ret = slave_->Step();
372         if (ret != E_OK) {
373             LOG_WARN("slave step error:%{public}d", ret);
374         }
375     }
376     return E_OK;
377 }
378 
InnerStep()379 int SqliteStatement::InnerStep()
380 {
381     SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_EXECUTE, seqId_);
382     PerfStat perfStat((config_ != nullptr) ? config_->GetPath() : "", "", PerfStat::Step::STEP_EXECUTE, seqId_);
383     auto errCode = sqlite3_step(stmt_);
384     auto db = sqlite3_db_handle(stmt_);
385     TryNotifyErrorLog(errCode, db, sql_);
386     int ret = SQLiteError::ErrNo(errCode);
387     if (config_ != nullptr && (errCode == SQLITE_CORRUPT || (errCode == SQLITE_NOTADB && config_->GetIter() != 0))) {
388         Reportor::ReportCorruptedOnce(Reportor::Create(*config_, ret,
389             (errCode == SQLITE_CORRUPT ? SqliteGlobalConfig::GetLastCorruptionMsg() : "SqliteStatement::InnerStep")));
390     }
391     if (config_ != nullptr && ret != E_OK && !config_->GetBundleName().empty()) {
392         Reportor::ReportFault(RdbFaultDbFileEvent(FT_CURD, ret, *config_, "sqlite3_step", true));
393     }
394     PrintInfoForDbError(ret, sql_);
395     return ret;
396 }
397 
Reset()398 int SqliteStatement::Reset()
399 {
400     if (stmt_ == nullptr) {
401         return E_OK;
402     }
403 
404     int errCode = sqlite3_reset(stmt_);
405     if (errCode != SQLITE_OK) {
406         LOG_ERROR("reset ret is %{public}d, errno is %{public}d", errCode, errno);
407         return SQLiteError::ErrNo(errCode);
408     }
409     if (slave_) {
410         errCode = slave_->Reset();
411         if (errCode != E_OK) {
412             LOG_WARN("slave reset error:%{public}d", errCode);
413         }
414     }
415     return E_OK;
416 }
417 
Finalize()418 int SqliteStatement::Finalize()
419 {
420     int errCode = InnerFinalize();
421     if (errCode != E_OK) {
422         return errCode;
423     }
424 
425     if (slave_) {
426         errCode = slave_->Finalize();
427         if (errCode != E_OK) {
428             LOG_WARN("slave finalize error:%{public}d", errCode);
429         }
430     }
431     return E_OK;
432 }
433 
Execute(const std::vector<ValueObject> & args)434 int SqliteStatement::Execute(const std::vector<ValueObject> &args)
435 {
436     std::vector<std::reference_wrapper<ValueObject>> refArgs;
437     for (auto &object : args) {
438         refArgs.emplace_back(std::ref(const_cast<ValueObject &>(object)));
439     }
440     return Execute(refArgs);
441 }
442 
Execute(const std::vector<std::reference_wrapper<ValueObject>> & args)443 int32_t SqliteStatement::Execute(const std::vector<std::reference_wrapper<ValueObject>> &args)
444 {
445     int count = static_cast<int>(args.size());
446     if (count != numParameters_) {
447         LOG_ERROR("bind args count(%{public}d) > numParameters(%{public}d), sql is %{public}s", count, numParameters_,
448             SqliteUtils::SqlAnonymous(sql_).c_str());
449         return E_INVALID_BIND_ARGS_COUNT;
450     }
451 
452     if (conn_ != nullptr) {
453         if (!conn_->IsWriter() && !ReadOnly()) {
454             return E_EXECUTE_WRITE_IN_READ_CONNECTION;
455         }
456         auto errCode = E_OK;
457         int sqlType = SqliteUtils::GetSqlStatementType(sql_);
458         if (sqlType != SqliteUtils::STATEMENT_COMMIT && sqlType != SqliteUtils::STATEMENT_ROLLBACK) {
459             errCode = conn_->LimitWalSize();
460         }
461         if (errCode != E_OK) {
462             return errCode;
463         }
464     }
465 
466     auto errCode = BindArgs(args);
467     if (errCode != E_OK) {
468         return errCode;
469     }
470     errCode = InnerStep();
471     if (errCode != E_NO_MORE_ROWS && errCode != E_OK) {
472         LOG_ERROR("sqlite3_step failed %{public}d, sql is %{public}s, errno %{public}d",
473             errCode, SqliteUtils::SqlAnonymous(sql_).c_str(), errno);
474         auto db = sqlite3_db_handle(stmt_);
475         // errno: 28 No space left on device
476         return (errCode == E_SQLITE_IOERR && sqlite3_system_errno(db) == 28) ? E_SQLITE_IOERR_FULL : errCode;
477     }
478 
479     if (slave_) {
480         int errCode = slave_->Execute(args);
481         if (errCode != E_OK) {
482             LOG_ERROR("slave execute error:%{public}d, sql is %{public}s, errno %{public}d",
483                 errCode, SqliteUtils::SqlAnonymous(sql_).c_str(), errno);
484             SqliteUtils::SetSlaveInvalid(config_->GetPath());
485         }
486     }
487     return E_OK;
488 }
489 
ExecuteForValue(const std::vector<ValueObject> & args)490 std::pair<int, ValueObject> SqliteStatement::ExecuteForValue(const std::vector<ValueObject> &args)
491 {
492     auto errCode = Execute(args);
493     if (errCode == E_OK) {
494         return GetColumn(0);
495     }
496     return { errCode, ValueObject() };
497 }
498 
Changes() const499 int SqliteStatement::Changes() const
500 {
501     if (stmt_ == nullptr) {
502         return -1;
503     }
504     auto db = sqlite3_db_handle(stmt_);
505     return sqlite3_changes(db);
506 }
507 
LastInsertRowId() const508 int64_t SqliteStatement::LastInsertRowId() const
509 {
510     if (stmt_ == nullptr) {
511         return -1;
512     }
513     auto db = sqlite3_db_handle(stmt_);
514     return sqlite3_last_insert_rowid(db);
515 }
516 
GetColumnCount() const517 int32_t SqliteStatement::GetColumnCount() const
518 {
519     return columnCount_;
520 }
521 
GetColumnName(int index) const522 std::pair<int32_t, std::string> SqliteStatement::GetColumnName(int index) const
523 {
524     int ret = IsValid(index);
525     if (ret != E_OK) {
526         return { ret, "" };
527     }
528 
529     const char *name = sqlite3_column_name(stmt_, index);
530     if (name == nullptr) {
531         LOG_ERROR("column_name is null.");
532         return { E_ERROR, "" };
533     }
534     return { E_OK, std::string(name) };
535 }
536 
Convert2ColumnType(int32_t type)537 static int32_t Convert2ColumnType(int32_t type)
538 {
539     switch (type) {
540         case SQLITE_INTEGER:
541             return int32_t(ColumnType::TYPE_INTEGER);
542         case SQLITE_FLOAT:
543             return int32_t(ColumnType::TYPE_FLOAT);
544         case SQLITE_BLOB:
545             return int32_t(ColumnType::TYPE_BLOB);
546         case SQLITE_TEXT:
547             return int32_t(ColumnType::TYPE_STRING);
548         default:
549             break;
550     }
551     return int32_t(ColumnType::TYPE_NULL);
552 }
553 
GetColumnType(int index) const554 std::pair<int32_t, int32_t> SqliteStatement::GetColumnType(int index) const
555 {
556     int ret = IsValid(index);
557     if (ret != E_OK) {
558         return { ret, int32_t(ColumnType::TYPE_NULL) };
559     }
560 
561     int type = sqlite3_column_type(stmt_, index);
562     if (type != SQLITE_BLOB) {
563         return { E_OK, Convert2ColumnType(type) };
564     }
565 
566     if (types_[index] != COLUMN_TYPE_INVALID) {
567         return { E_OK, types_[index] };
568     }
569 
570     const char *decl = sqlite3_column_decltype(stmt_, index);
571     if (decl == nullptr) {
572         LOG_ERROR("invalid type %{public}d, errno %{public}d.", type, errno);
573         return { E_ERROR, int32_t(ColumnType::TYPE_NULL) };
574     }
575 
576     auto declType = StringUtils::TruncateAfterFirstParen(SqliteUtils::StrToUpper(decl));
577     if (declType == ValueObject::DeclType<ValueObject::Asset>()) {
578         types_[index] = int32_t(ColumnType::TYPE_ASSET);
579     } else if (declType == ValueObject::DeclType<ValueObject::Assets>()) {
580         types_[index] = int32_t(ColumnType::TYPE_ASSETS);
581     } else if (declType == ValueObject::DeclType<ValueObject::FloatVector>()) {
582         types_[index] = int32_t(ColumnType::TYPE_FLOAT32_ARRAY);
583     } else if (declType == ValueObject::DeclType<ValueObject::BigInt>()) {
584         types_[index] = int32_t(ColumnType::TYPE_BIGINT);
585     } else {
586         types_[index] = int32_t(ColumnType::TYPE_BLOB);
587     }
588 
589     return { E_OK, types_[index] };
590 }
591 
GetSize(int index) const592 std::pair<int32_t, size_t> SqliteStatement::GetSize(int index) const
593 {
594     auto [errCode, type] = GetColumnType(index);
595     if (errCode != E_OK) {
596         return { errCode, 0 };
597     }
598 
599     if (type == static_cast<int32_t>(ColumnType::TYPE_BLOB) || type == static_cast<int32_t>(ColumnType::TYPE_NULL)) {
600         auto size = static_cast<size_t>(sqlite3_column_bytes(stmt_, index));
601         return { E_OK, size };
602     } else if (type == static_cast<int32_t>(ColumnType::TYPE_STRING)) {
603         // Add 1 to size for the string terminator (null character).
604         auto size = static_cast<size_t>(sqlite3_column_bytes(stmt_, index) + 1);
605         return { E_OK, size };
606     }
607     return { E_INVALID_COLUMN_TYPE, 0 };
608 }
609 
GetColumn(int index) const610 std::pair<int32_t, ValueObject> SqliteStatement::GetColumn(int index) const
611 {
612     auto [errCode, type] = GetColumnType(index);
613     if (errCode != E_OK) {
614         return { errCode, ValueObject() };
615     }
616 
617     switch (static_cast<ColumnType>(type)) {
618         case ColumnType::TYPE_FLOAT:
619             return { E_OK, ValueObject(sqlite3_column_double(stmt_, index)) };
620         case ColumnType::TYPE_INTEGER:
621             return { E_OK, ValueObject(static_cast<int64_t>(sqlite3_column_int64(stmt_, index))) };
622         case ColumnType::TYPE_STRING: {
623             int size = sqlite3_column_bytes(stmt_, index);
624             auto text = reinterpret_cast<const char *>(sqlite3_column_text(stmt_, index));
625             return { E_OK, ValueObject(text == nullptr ? std::string("") : std::string(text, size)) };
626         }
627         case ColumnType::TYPE_NULL:
628             return { E_OK, ValueObject() };
629         default:
630             break;
631     }
632     return { E_OK, GetValueFromBlob(index, type) };
633 }
634 
GetRows(uint32_t maxCount)635 std::pair<int32_t, std::vector<ValuesBucket>> SqliteStatement::GetRows(uint32_t maxCount)
636 {
637     auto colCount = GetColumnCount();
638     if (colCount <= 0) {
639         return { E_OK, {} };
640     }
641     std::vector<ValuesBucket> valuesBuckets;
642     std::vector<std::string> colNames;
643     colNames.reserve(colCount);
644     for (int i = 0; i < colCount; i++) {
645         auto [code, colName] = GetColumnName(i);
646         if (code != E_OK) {
647             LOG_ERROR("GetColumnName ret %{public}d", code);
648             return { code, {} };
649         }
650         colNames.push_back(std::move(colName));
651     }
652     int32_t status = 0;
653     do {
654         if (valuesBuckets.size() >= maxCount) {
655             break;
656         }
657         ValuesBucket value;
658         for (int32_t i = 0; i < colCount; i++) {
659             auto [code, val] = GetColumn(i);
660             if (code != E_OK) {
661                 LOG_WARN("GetColumn failed, errCode:%{public}d", code);
662                 continue;
663             }
664             value.Put(colNames[i], std::move(val));
665         }
666         valuesBuckets.push_back(std::move(value));
667         status = InnerStep();
668     } while (status == E_OK);
669     return { status, valuesBuckets };
670 }
671 
GetValueFromBlob(int32_t index,int32_t type) const672 ValueObject SqliteStatement::GetValueFromBlob(int32_t index, int32_t type) const
673 {
674     int size = sqlite3_column_bytes(stmt_, index);
675     auto blob = static_cast<const uint8_t *>(sqlite3_column_blob(stmt_, index));
676     if (blob == nullptr || size <= 0) {
677         return ValueObject();
678     }
679     switch (static_cast<ColumnType>(type)) {
680         case ColumnType::TYPE_ASSET: {
681             Asset asset;
682             RawDataParser::ParserRawData(blob, size, asset);
683             return ValueObject(std::move(asset));
684         }
685         case ColumnType::TYPE_ASSETS: {
686             Assets assets;
687             RawDataParser::ParserRawData(blob, size, assets);
688             return ValueObject(std::move(assets));
689         }
690         case ColumnType::TYPE_FLOAT32_ARRAY: {
691             Floats floats;
692             RawDataParser::ParserRawData(blob, size, floats);
693             return ValueObject(std::move(floats));
694         }
695         case ColumnType::TYPE_BIGINT: {
696             BigInt bigint;
697             RawDataParser::ParserRawData(blob, size, bigint);
698             return ValueObject(std::move(bigint));
699         }
700         default:
701             break;
702     }
703     return ValueObject(std::vector<uint8_t>(blob, blob + size));
704 }
705 
ReadOnly() const706 bool SqliteStatement::ReadOnly() const
707 {
708     return readOnly_;
709 }
710 
SupportBlockInfo() const711 bool SqliteStatement::SupportBlockInfo() const
712 {
713     auto db = sqlite3_db_handle(stmt_);
714     return (sqlite3_db_config(db, SQLITE_USE_SHAREDBLOCK) == SQLITE_OK);
715 }
716 
FillBlockInfo(SharedBlockInfo * info) const717 int32_t SqliteStatement::FillBlockInfo(SharedBlockInfo *info) const
718 {
719     SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_EXECUTE, seqId_);
720     PerfStat perfStat((config_ != nullptr) ? config_->GetPath() : "", "", PerfStat::Step::STEP_EXECUTE, seqId_);
721     if (info == nullptr) {
722         return E_INVALID_ARGS;
723     }
724     int32_t errCode = E_OK;
725     if (SupportBlockInfo()) {
726         errCode = FillSharedBlockOpt(info, stmt_);
727     } else {
728         errCode = FillSharedBlock(info, stmt_);
729     }
730     if (errCode != E_OK) {
731         if (config_ != nullptr) {
732             Reportor::ReportFault(RdbFaultDbFileEvent(FT_CURD, errCode, *config_,
733                 "FillBlockInfo", true));
734         }
735         auto ret = (config_ != nullptr && errCode == E_SQLITE_CORRUPT);
736         if (ret) {
737             Reportor::ReportCorruptedOnce(Reportor::Create(*config_, errCode,
738                 "FillBlockInfo: " + SqliteGlobalConfig::GetLastCorruptionMsg()));
739         }
740         return errCode;
741     }
742     if (!ResetStatement(info, stmt_)) {
743         LOG_ERROR("ResetStatement Failed.");
744         return E_ERROR;
745     }
746     return E_OK;
747 }
748 
BindNil(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)749 int32_t SqliteStatement::BindNil(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
750 {
751     return sqlite3_bind_null(stat, index);
752 }
753 
BindInteger(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)754 int32_t SqliteStatement::BindInteger(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
755 {
756     auto val = std::get_if<int64_t>(&arg);
757     if (val == nullptr) {
758         return SQLITE_MISMATCH;
759     }
760     return sqlite3_bind_int64(stat, index, *val);
761 }
762 
BindDouble(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)763 int32_t SqliteStatement::BindDouble(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
764 {
765     auto val = std::get_if<double>(&arg);
766     if (val == nullptr) {
767         return SQLITE_MISMATCH;
768     }
769     return sqlite3_bind_double(stat, index, *val);
770 }
771 
BindText(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)772 int32_t SqliteStatement::BindText(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
773 {
774     auto val = std::get_if<std::string>(&arg);
775     if (val == nullptr) {
776         return SQLITE_MISMATCH;
777     }
778     return sqlite3_bind_text(stat, index, val->c_str(), val->length(), SQLITE_TRANSIENT);
779 }
780 
BindBool(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)781 int32_t SqliteStatement::BindBool(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
782 {
783     auto val = std::get_if<bool>(&arg);
784     if (val == nullptr) {
785         return SQLITE_MISMATCH;
786     }
787     return sqlite3_bind_int64(stat, index, *val ? 1 : 0);
788 }
789 
BindBlob(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)790 int32_t SqliteStatement::BindBlob(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
791 {
792     auto val = std::get_if<std::vector<uint8_t>>(&arg);
793     if (val == nullptr) {
794         return SQLITE_MISMATCH;
795     }
796 
797     if (val->empty()) {
798         return sqlite3_bind_zeroblob(stat, index, 0);
799     }
800     return sqlite3_bind_blob(stat, index, static_cast<const void *>((*val).data()), (*val).size(), SQLITE_TRANSIENT);
801 }
802 
BindAsset(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)803 int32_t SqliteStatement::BindAsset(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
804 {
805     auto val = std::get_if<Asset>(&arg);
806     if (val == nullptr) {
807         return SQLITE_MISMATCH;
808     }
809     auto rawData = RawDataParser::PackageRawData(*val);
810     return sqlite3_bind_blob(stat, index, static_cast<const void *>(rawData.data()), rawData.size(), SQLITE_TRANSIENT);
811 }
812 
BindAssets(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)813 int32_t SqliteStatement::BindAssets(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
814 {
815     auto val = std::get_if<Assets>(&arg);
816     if (val == nullptr) {
817         return SQLITE_MISMATCH;
818     }
819     auto rawData = RawDataParser::PackageRawData(*val);
820     return sqlite3_bind_blob(stat, index, static_cast<const void *>(rawData.data()), rawData.size(), SQLITE_TRANSIENT);
821 }
822 
BindFloats(sqlite3_stmt * stat,int index,const ValueObject::Type & object)823 int32_t SqliteStatement::BindFloats(sqlite3_stmt *stat, int index, const ValueObject::Type &object)
824 {
825     auto val = std::get_if<Floats>(&object);
826     if (val == nullptr) {
827         return SQLITE_MISMATCH;
828     }
829     auto rawData = RawDataParser::PackageRawData(*val);
830     return sqlite3_bind_blob(stat, index, static_cast<const void *>(rawData.data()), rawData.size(), SQLITE_TRANSIENT);
831 }
832 
BindBigInt(sqlite3_stmt * stat,int index,const ValueObject::Type & arg)833 int32_t SqliteStatement::BindBigInt(sqlite3_stmt *stat, int index, const ValueObject::Type &arg)
834 {
835     auto val = std::get_if<BigInt>(&arg);
836     if (val == nullptr) {
837         return SQLITE_MISMATCH;
838     }
839     auto rawData = RawDataParser::PackageRawData(*val);
840     return sqlite3_bind_blob(stat, index, static_cast<const void *>(rawData.data()), rawData.size(), SQLITE_TRANSIENT);
841 }
842 
ModifyLockStatus(const std::string & table,const std::vector<std::vector<uint8_t>> & hashKeys,bool isLock)843 int SqliteStatement::ModifyLockStatus(
844     const std::string &table, const std::vector<std::vector<uint8_t>> &hashKeys, bool isLock)
845 {
846     ::DistributedDB::DBStatus ret;
847     auto db = sqlite3_db_handle(stmt_);
848     if (db == nullptr) {
849         return E_ERROR;
850     }
851     if (isLock) {
852         ret = Lock(table, hashKeys, db);
853     } else {
854         ret = UnLock(table, hashKeys, db);
855     }
856     if (ret == ::DistributedDB::DBStatus::OK) {
857         return E_OK;
858     }
859     if (ret == ::DistributedDB::DBStatus::WAIT_COMPENSATED_SYNC) {
860         return E_WAIT_COMPENSATED_SYNC;
861     }
862     if (ret == ::DistributedDB::DBStatus::NOT_FOUND) {
863         return E_NO_ROW_IN_QUERY;
864     }
865     LOG_ERROR("Lock/Unlock failed, err is %{public}d.", ret);
866     return E_ERROR;
867 }
868 
InnerFinalize()869 int SqliteStatement::InnerFinalize()
870 {
871     if (stmt_ == nullptr) {
872         return E_OK;
873     }
874 
875     auto db = sqlite3_db_handle(stmt_);
876     int errCode = sqlite3_finalize(stmt_);
877     TryNotifyErrorLog(errCode, db, sql_);
878     stmt_ = nullptr;
879     sql_ = "";
880     readOnly_ = false;
881     columnCount_ = -1;
882     numParameters_ = 0;
883     types_ = std::vector<int32_t>();
884     if (errCode != SQLITE_OK) {
885         LOG_ERROR("finalize ret is %{public}d, errno is %{public}d", errCode, errno);
886         return SQLiteError::ErrNo(errCode);
887     }
888     return E_OK;
889 }
890 } // namespace NativeRdb
891 } // namespace OHOS
892