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