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