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 int32_t count = INVALID_COUNT;
259 int32_t status = E_OK;
260 int32_t retry = 0;
261 do {
262 status = Step();
263 if (status == E_SQLITE_BUSY || status == E_SQLITE_LOCKED) {
264 retry++;
265 usleep(RETRY_INTERVAL);
266 continue;
267 }
268 count++;
269 } while (status == E_OK || ((status == E_SQLITE_BUSY || status == E_SQLITE_LOCKED) && retry < MAX_RETRY_TIMES));
270 if (status != E_NO_MORE_ROWS) {
271 Reset();
272 return { status, INVALID_COUNT };
273 }
274 if (retry > 0) {
275 LOG_WARN("locked, retry=%{public}d, sql=%{public}s", retry, sql_.c_str());
276 }
277 Reset();
278 return { E_OK, count };
279 }
280
Step()281 int SqliteStatement::Step()
282 {
283 int ret = InnerStep();
284 if (ret != E_OK) {
285 return ret;
286 }
287 if (slave_) {
288 ret = slave_->Step();
289 if (ret != E_OK) {
290 LOG_WARN("slave step error:%{public}d", ret);
291 }
292 }
293 return E_OK;
294 }
295
InnerStep()296 int SqliteStatement::InnerStep()
297 {
298 SqlStatistic sqlStatistic("", SqlStatistic::Step::STEP_EXECUTE, seqId_);
299 auto errCode = sqlite3_step(stmt_);
300 int ret = SQLiteError::ErrNo(errCode);
301 if (config_ != nullptr && (errCode == SQLITE_CORRUPT || (errCode == SQLITE_NOTADB && config_->GetIter() != 0))) {
302 Reportor::ReportFault(Reportor::Create(*config_, ret));
303 }
304 PrintInfoForDbError(ret, sql_);
305 return ret;
306 }
307
Reset()308 int SqliteStatement::Reset()
309 {
310 if (stmt_ == nullptr) {
311 return E_OK;
312 }
313
314 int errCode = sqlite3_reset(stmt_);
315 if (errCode != SQLITE_OK) {
316 LOG_ERROR("reset ret is %{public}d, errno is %{public}d", errCode, errno);
317 return SQLiteError::ErrNo(errCode);
318 }
319 if (slave_) {
320 errCode = slave_->Reset();
321 if (errCode != E_OK) {
322 LOG_WARN("slave reset error:%{public}d", errCode);
323 }
324 }
325 return E_OK;
326 }
327
Finalize()328 int SqliteStatement::Finalize()
329 {
330 int errCode = InnerFinalize();
331 if (errCode != E_OK) {
332 return errCode;
333 }
334
335 if (slave_) {
336 errCode = slave_->Finalize();
337 if (errCode != E_OK) {
338 LOG_WARN("slave finalize error:%{public}d", errCode);
339 }
340 }
341 return E_OK;
342 }
343
Execute(const std::vector<ValueObject> & args)344 int SqliteStatement::Execute(const std::vector<ValueObject> &args)
345 {
346 std::vector<std::reference_wrapper<ValueObject>> refArgs;
347 for (auto &object : args) {
348 refArgs.emplace_back(std::ref(const_cast<ValueObject&>(object)));
349 }
350 return Execute(refArgs);
351 }
352
Execute(const std::vector<std::reference_wrapper<ValueObject>> & args)353 int32_t SqliteStatement::Execute(const std::vector<std::reference_wrapper<ValueObject>> &args)
354 {
355 int count = static_cast<int>(args.size());
356 if (count != numParameters_) {
357 LOG_ERROR("bind args count(%{public}d) > numParameters(%{public}d)", count, numParameters_);
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