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