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