1 /*
2 * Copyright (c) 2022 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
16 #include "sqlite_connection.h"
17
18 #include <memory>
19 #include <securec.h>
20 #include <sqlite3sym.h>
21 #include <sys/stat.h>
22 #include <unicode/ucol.h>
23 #include <unistd.h>
24
25 #include <cerrno>
26
27 #include "logger.h"
28 #include "rdb_errno.h"
29 #include "share_block.h"
30 #include "shared_block_serializer_info.h"
31 #include "sqlite_errno.h"
32 #include "sqlite_global_config.h"
33 #include "sqlite_utils.h"
34 #include "relational/relational_store_sqlite_ext.h"
35
36 namespace OHOS {
37 namespace NativeRdb {
38 // error status
39 const int ERROR_STATUS = -1;
40
Open(const SqliteConfig & config,bool isWriteConnection,int & errCode)41 SqliteConnection *SqliteConnection::Open(const SqliteConfig &config, bool isWriteConnection, int &errCode)
42 {
43 auto connection = new SqliteConnection(isWriteConnection);
44 errCode = connection->InnerOpen(config);
45 if (errCode != E_OK) {
46 delete connection;
47 return nullptr;
48 }
49 return connection;
50 }
51
SqliteConnection(bool isWriteConnection)52 SqliteConnection::SqliteConnection(bool isWriteConnection)
53 : dbHandle(nullptr),
54 isWriteConnection(isWriteConnection),
55 isReadOnly(false),
56 statement(),
57 stepStatement(nullptr),
58 filePath(""),
59 openFlags(0)
60 {
61 }
62
InnerOpen(const SqliteConfig & config)63 int SqliteConnection::InnerOpen(const SqliteConfig &config)
64 {
65 std::string dbPath;
66 if (config.GetStorageMode() == StorageMode::MODE_MEMORY) {
67 dbPath = SqliteGlobalConfig::GetMemoryDbPath();
68 } else if (config.GetPath().empty()) {
69 LOG_ERROR("SqliteConnection InnerOpen input empty database path");
70 return E_EMPTY_FILE_NAME;
71 } else if (config.GetPath().front() != '/') { // change this to starts_with() after c++20
72 LOG_ERROR("SqliteConnection InnerOpen input relative path");
73 return E_RELATIVE_PATH;
74 } else {
75 dbPath = config.GetPath();
76 }
77
78 stepStatement = std::make_shared<SqliteStatement>();
79 if (stepStatement == nullptr) {
80 return E_STEP_STATEMENT_NOT_INIT;
81 }
82
83 isReadOnly = !isWriteConnection || config.IsReadOnly();
84 int openFileFlags = config.IsReadOnly() ? SQLITE_OPEN_READONLY : (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
85 int errCode = sqlite3_open_v2(dbPath.c_str(), &dbHandle, openFileFlags, nullptr);
86 if (errCode != SQLITE_OK) {
87 LOG_ERROR("SqliteConnection InnerOpen fail to open database err = %{public}d", errCode);
88 return SQLiteError::ErrNo(errCode);
89 }
90
91 SetPersistWal();
92 SetBusyTimeout(DEFAULT_BUSY_TIMEOUT_MS);
93 LimitPermission(dbPath);
94
95 errCode = Config(config);
96 if (errCode != E_OK) {
97 return errCode;
98 }
99
100 filePath = dbPath;
101 openFlags = openFileFlags;
102
103 return E_OK;
104 }
105
Config(const SqliteConfig & config)106 int SqliteConnection::Config(const SqliteConfig &config)
107 {
108 if (config.GetStorageMode() == StorageMode::MODE_MEMORY) {
109 return E_OK;
110 }
111
112 int errCode = SetPageSize();
113 if (errCode != E_OK) {
114 return errCode;
115 }
116
117 std::vector<uint8_t> encryptKey = config.GetEncryptKey();
118 errCode = SetEncryptKey(encryptKey);
119 std::fill(encryptKey.begin(), encryptKey.end(), 0);
120 if (errCode != E_OK) {
121 return errCode;
122 }
123
124 errCode = SetJournalMode(config.GetJournalMode(), config.GetSyncMode());
125 if (errCode != E_OK) {
126 return errCode;
127 }
128
129 errCode = SetJournalSizeLimit();
130 if (errCode != E_OK) {
131 return errCode;
132 }
133
134 errCode = SetAutoCheckpoint();
135 if (errCode != E_OK) {
136 return errCode;
137 }
138
139 return E_OK;
140 }
141
~SqliteConnection()142 SqliteConnection::~SqliteConnection()
143 {
144 if (dbHandle != nullptr) {
145 statement.Finalize();
146 if (stepStatement != nullptr) {
147 stepStatement->Finalize();
148 }
149 int errCode = sqlite3_close(dbHandle);
150 if (errCode != SQLITE_OK) {
151 LOG_ERROR("SqliteConnection ~SqliteConnection: could not close database err = %{public}d", errCode);
152 }
153 }
154 }
155
SetPageSize()156 int SqliteConnection::SetPageSize()
157 {
158 if (isReadOnly) {
159 return E_OK;
160 }
161
162 int targetValue = SqliteGlobalConfig::GetPageSize();
163 int64_t value;
164 int errCode = ExecuteGetLong(value, "PRAGMA page_size");
165 if (errCode != E_OK) {
166 LOG_ERROR("SqliteConnection SetPageSize fail to get page size : %{public}d", errCode);
167 return errCode;
168 }
169
170 if (value == targetValue) {
171 return E_OK;
172 }
173
174 errCode = ExecuteSql("PRAGMA page_size=" + std::to_string(targetValue));
175 if (errCode != E_OK) {
176 LOG_ERROR("SqliteConnection SetPageSize fail to set page size : %{public}d", errCode);
177 }
178 return errCode;
179 }
180
SetEncryptKey(const std::vector<uint8_t> & encryptKey)181 int SqliteConnection::SetEncryptKey(const std::vector<uint8_t> &encryptKey)
182 {
183 if (encryptKey.empty()) {
184 return E_OK;
185 }
186
187 int errCode = sqlite3_key(dbHandle, static_cast<const void *>(encryptKey.data()), encryptKey.size());
188 if (errCode != SQLITE_OK) {
189 LOG_ERROR("SqliteConnection SetEncryptKey fail, err = %{public}d", errCode);
190 return SQLiteError::ErrNo(errCode);
191 }
192
193 return E_OK;
194 }
195
SetPersistWal()196 int SqliteConnection::SetPersistWal()
197 {
198 int opcode = 1;
199 int errCode = sqlite3_file_control(dbHandle, "main", SQLITE_FCNTL_PERSIST_WAL, &opcode);
200 if (errCode != SQLITE_OK) {
201 LOG_ERROR("failed");
202 return E_SET_PERSIST_WAL;
203 }
204 LOG_INFO("success");
205 return E_OK;
206 }
207
SetBusyTimeout(int timeout)208 int SqliteConnection::SetBusyTimeout(int timeout)
209 {
210 auto errCode = sqlite3_busy_timeout(dbHandle, timeout);
211 if (errCode != SQLITE_OK) {
212 LOG_ERROR("set buys timeout failed, errCode=%{public}d", errCode);
213 return errCode;
214 }
215 LOG_INFO("success");
216 return E_OK;
217 }
218
SetJournalMode(const std::string & journalMode,const std::string & synclMode)219 int SqliteConnection::SetJournalMode(const std::string &journalMode, const std::string &synclMode)
220 {
221 if (isReadOnly) {
222 return E_OK;
223 }
224
225 std::string currentMode;
226 int errCode = ExecuteGetString(currentMode, "PRAGMA journal_mode");
227 if (errCode != E_OK) {
228 LOG_ERROR("SqliteConnection SetJournalMode fail to get journal mode : %{public}d", errCode);
229 return errCode;
230 }
231
232 currentMode = SqliteUtils::StrToUpper(currentMode);
233 if (currentMode != journalMode) {
234 std::string result;
235 int errorCode = ExecuteGetString(result, "PRAGMA journal_mode=" + journalMode);
236 if (errorCode != E_OK) {
237 LOG_ERROR("SqliteConnection SetJournalMode: fail to set journal mode err=%{public}d", errorCode);
238 return errorCode;
239 }
240
241 if (SqliteUtils::StrToUpper(result) != journalMode) {
242 LOG_ERROR("SqliteConnection SetJournalMode: result incorrect");
243 return E_EXECUTE_RESULT_INCORRECT;
244 }
245 }
246
247 if (journalMode == "WAL") {
248 errCode = SetWalSyncMode(synclMode);
249 }
250
251 return errCode;
252 }
253
SetJournalSizeLimit()254 int SqliteConnection::SetJournalSizeLimit()
255 {
256 if (isReadOnly) {
257 return E_OK;
258 }
259
260 int targetValue = SqliteGlobalConfig::GetJournalFileSize();
261 int64_t currentValue;
262 int errCode = ExecuteGetLong(currentValue, "PRAGMA journal_size_limit");
263 if (errCode != E_OK) {
264 LOG_ERROR("SqliteConnection SetJournalSizeLimit fail to get journal_size_limit : %{public}d", errCode);
265 return errCode;
266 }
267
268 if (currentValue == targetValue) {
269 return E_OK;
270 }
271
272 int64_t result;
273 errCode = ExecuteGetLong(result, "PRAGMA journal_size_limit=" + std::to_string(targetValue));
274 if (errCode != E_OK) {
275 LOG_ERROR("SqliteConnection SetJournalSizeLimit fail to set journal_size_limit : %{public}d", errCode);
276 }
277 return errCode;
278 }
279
SetAutoCheckpoint()280 int SqliteConnection::SetAutoCheckpoint()
281 {
282 if (isReadOnly) {
283 return E_OK;
284 }
285
286 int targetValue = SqliteGlobalConfig::GetWalAutoCheckpoint();
287 int64_t value;
288 int errCode = ExecuteGetLong(value, "PRAGMA wal_autocheckpoint");
289 if (errCode != E_OK) {
290 LOG_ERROR("SqliteConnection SetAutoCheckpoint fail to get wal_autocheckpoint : %{public}d", errCode);
291 return errCode;
292 }
293
294 if (value == targetValue) {
295 return E_OK;
296 }
297
298 int64_t result;
299 errCode = ExecuteGetLong(result, "PRAGMA wal_autocheckpoint=" + std::to_string(targetValue));
300 if (errCode != E_OK) {
301 LOG_ERROR("SqliteConnection SetAutoCheckpoint fail to set wal_autocheckpoint : %{public}d", errCode);
302 }
303 return errCode;
304 }
305
SetWalSyncMode(const std::string & syncMode)306 int SqliteConnection::SetWalSyncMode(const std::string &syncMode)
307 {
308 std::string targetValue = SqliteGlobalConfig::GetWalSyncMode();
309 if (syncMode.length() != 0) {
310 targetValue = syncMode;
311 }
312
313 std::string value;
314 int errCode = ExecuteGetString(value, "PRAGMA synchronous");
315 if (errCode != E_OK) {
316 LOG_ERROR("SqliteConnection setWalSyncMode fail to get synchronous mode : %{public}d", errCode);
317 return errCode;
318 }
319
320 value = SqliteUtils::StrToUpper(value);
321 if (value == targetValue) {
322 return E_OK;
323 }
324
325 errCode = ExecuteSql("PRAGMA synchronous=" + targetValue);
326 if (errCode != E_OK) {
327 LOG_ERROR("SqliteConnection setWalSyncMode fail to set synchronous mode : %{public}d", errCode);
328 }
329 return errCode;
330 }
331
IsWriteConnection() const332 bool SqliteConnection::IsWriteConnection() const
333 {
334 return isWriteConnection;
335 }
336
Prepare(const std::string & sql,bool & outIsReadOnly)337 int SqliteConnection::Prepare(const std::string &sql, bool &outIsReadOnly)
338 {
339 int errCode = statement.Prepare(dbHandle, sql);
340 if (errCode != E_OK) {
341 return errCode;
342 }
343 outIsReadOnly = statement.IsReadOnly();
344 return E_OK;
345 }
346
PrepareAndGetInfo(const std::string & sql,bool & outIsReadOnly,int & numParameters,std::vector<std::string> & columnNames)347 int SqliteConnection::PrepareAndGetInfo(const std::string &sql, bool &outIsReadOnly, int &numParameters,
348 std::vector<std::string> &columnNames)
349 {
350 int errCode = statement.Prepare(dbHandle, sql);
351 if (errCode != E_OK) {
352 return errCode;
353 }
354
355 errCode = statement.GetColumnCount(numParameters);
356 if (errCode != E_OK) {
357 return errCode;
358 }
359
360 int columnCount;
361 errCode = statement.GetColumnCount(columnCount);
362 if (errCode != E_OK) {
363 return errCode;
364 }
365 for (int i = 0; i < columnCount; i++) {
366 std::string name;
367 statement.GetColumnName(i, name);
368 columnNames.push_back(name);
369 }
370 outIsReadOnly = statement.IsReadOnly();
371
372 errCode = statement.GetNumParameters(numParameters);
373 if (errCode != E_OK) {
374 return errCode;
375 }
376
377 return E_OK;
378 }
379
PrepareAndBind(const std::string & sql,const std::vector<ValueObject> & bindArgs)380 int SqliteConnection::PrepareAndBind(const std::string &sql, const std::vector<ValueObject> &bindArgs)
381 {
382 if (dbHandle == nullptr) {
383 LOG_ERROR("SqliteConnection dbHandle is nullptr");
384 }
385 int errCode = statement.Prepare(dbHandle, sql);
386 if (errCode != E_OK) {
387 return errCode;
388 }
389
390 if (!isWriteConnection && !statement.IsReadOnly()) {
391 return E_EXECUTE_WRITE_IN_READ_CONNECTION;
392 }
393
394 errCode = statement.BindArguments(bindArgs);
395 return errCode;
396 }
397
ExecuteSql(const std::string & sql,const std::vector<ValueObject> & bindArgs)398 int SqliteConnection::ExecuteSql(const std::string &sql, const std::vector<ValueObject> &bindArgs)
399 {
400 int errCode = PrepareAndBind(sql, bindArgs);
401 if (errCode != E_OK) {
402 return errCode;
403 }
404
405 errCode = statement.Step();
406 if (errCode == SQLITE_ROW) {
407 LOG_ERROR("SqliteConnection Execute : Queries can be performed using query or QuerySql methods only");
408 statement.ResetStatementAndClearBindings();
409 return E_QUERY_IN_EXECUTE;
410 } else if (errCode != SQLITE_DONE) {
411 LOG_ERROR("SqliteConnection Execute : err %{public}d", errCode);
412 statement.ResetStatementAndClearBindings();
413 return SQLiteError::ErrNo(errCode);
414 }
415
416 errCode = statement.ResetStatementAndClearBindings();
417 return errCode;
418 }
419
ExecuteForChangedRowCount(int & changedRows,const std::string & sql,const std::vector<ValueObject> & bindArgs)420 int SqliteConnection::ExecuteForChangedRowCount(
421 int &changedRows, const std::string &sql, const std::vector<ValueObject> &bindArgs)
422 {
423 int errCode = PrepareAndBind(sql, bindArgs);
424 if (errCode != E_OK) {
425 return errCode;
426 }
427
428 errCode = statement.Step();
429 if (errCode == SQLITE_ROW) {
430 LOG_ERROR("SqliteConnection ExecuteForChangedRowCount : Queries can be performed using query or QuerySql "
431 "methods only");
432 statement.ResetStatementAndClearBindings();
433 return E_QUERY_IN_EXECUTE;
434 } else if (errCode != SQLITE_DONE) {
435 LOG_ERROR("SqliteConnection ExecuteForChangedRowCount : failed %{public}d", errCode);
436 statement.ResetStatementAndClearBindings();
437 return SQLiteError::ErrNo(errCode);
438 }
439
440 changedRows = sqlite3_changes(dbHandle);
441 errCode = statement.ResetStatementAndClearBindings();
442 return errCode;
443 }
444
ExecuteForLastInsertedRowId(int64_t & outRowId,const std::string & sql,const std::vector<ValueObject> & bindArgs)445 int SqliteConnection::ExecuteForLastInsertedRowId(
446 int64_t &outRowId, const std::string &sql, const std::vector<ValueObject> &bindArgs)
447 {
448 int errCode = PrepareAndBind(sql, bindArgs);
449 if (errCode != E_OK) {
450 return errCode;
451 }
452
453 errCode = statement.Step();
454 if (errCode == SQLITE_ROW) {
455 LOG_ERROR("SqliteConnection ExecuteForLastInsertedRowId : Queries can be performed using query or QuerySql "
456 "methods only");
457 statement.ResetStatementAndClearBindings();
458 return E_QUERY_IN_EXECUTE;
459 } else if (errCode != SQLITE_DONE) {
460 LOG_ERROR("SqliteConnection ExecuteForLastInsertedRowId : failed %{public}d", errCode);
461 statement.ResetStatementAndClearBindings();
462 return SQLiteError::ErrNo(errCode);
463 }
464
465 outRowId = (sqlite3_changes(dbHandle) > 0) ? sqlite3_last_insert_rowid(dbHandle) : -1;
466 errCode = statement.ResetStatementAndClearBindings();
467 return errCode;
468 }
469
ExecuteGetLong(int64_t & outValue,const std::string & sql,const std::vector<ValueObject> & bindArgs)470 int SqliteConnection::ExecuteGetLong(
471 int64_t &outValue, const std::string &sql, const std::vector<ValueObject> &bindArgs)
472 {
473 int errCode = PrepareAndBind(sql, bindArgs);
474 if (errCode != E_OK) {
475 return errCode;
476 }
477
478 errCode = statement.Step();
479 if (errCode != SQLITE_ROW) {
480 statement.ResetStatementAndClearBindings();
481 return E_NO_ROW_IN_QUERY;
482 }
483
484 errCode = statement.GetColumnLong(0, outValue);
485 if (errCode != E_OK) {
486 statement.ResetStatementAndClearBindings();
487 return errCode;
488 }
489
490 errCode = statement.ResetStatementAndClearBindings();
491 return errCode;
492 }
493
ExecuteGetString(std::string & outValue,const std::string & sql,const std::vector<ValueObject> & bindArgs)494 int SqliteConnection::ExecuteGetString(
495 std::string &outValue, const std::string &sql, const std::vector<ValueObject> &bindArgs)
496 {
497 int errCode = PrepareAndBind(sql, bindArgs);
498 if (errCode != E_OK) {
499 return errCode;
500 }
501
502 errCode = statement.Step();
503 if (errCode != SQLITE_ROW) {
504 statement.ResetStatementAndClearBindings();
505 return E_NO_ROW_IN_QUERY;
506 }
507
508 errCode = statement.GetColumnString(0, outValue);
509 if (errCode != E_OK) {
510 statement.ResetStatementAndClearBindings();
511 return errCode;
512 }
513
514 errCode = statement.ResetStatementAndClearBindings();
515 return errCode;
516 }
517
BeginStepQuery(int & errCode,const std::string & sql,const std::vector<std::string> & selectionArgs) const518 std::shared_ptr<SqliteStatement> SqliteConnection::BeginStepQuery(
519 int &errCode, const std::string &sql, const std::vector<std::string> &selectionArgs) const
520 {
521 errCode = stepStatement->Prepare(dbHandle, sql);
522 if (errCode != E_OK) {
523 return nullptr;
524 }
525
526 std::vector<ValueObject> bindArgs;
527 for (auto item : selectionArgs) {
528 bindArgs.push_back(ValueObject(item));
529 }
530
531 errCode = stepStatement->BindArguments(bindArgs);
532 if (errCode != E_OK) {
533 return nullptr;
534 }
535
536 return stepStatement;
537 }
538
EndStepQuery()539 int SqliteConnection::EndStepQuery()
540 {
541 return stepStatement->ResetStatementAndClearBindings();
542 }
543
ChangeEncryptKey(const std::vector<uint8_t> & newKey)544 int SqliteConnection::ChangeEncryptKey(const std::vector<uint8_t> &newKey)
545 {
546 int errCode = sqlite3_rekey(dbHandle, static_cast<const void *>(newKey.data()), newKey.size());
547 if (errCode != SQLITE_OK) {
548 LOG_ERROR("SqliteConnection ChangeEncryptKey fail, err = %{public}d", errCode);
549 return SQLiteError::ErrNo(errCode);
550 }
551
552 errCode = statement.Finalize();
553 if (errCode != SQLITE_OK) {
554 return errCode;
555 }
556
557 errCode = stepStatement->Finalize();
558 if (errCode != SQLITE_OK) {
559 return errCode;
560 }
561
562 return E_OK;
563 }
564
LimitPermission(const std::string & dbPath) const565 void SqliteConnection::LimitPermission(const std::string &dbPath) const
566 {
567 struct stat st = { 0 };
568 if (stat(dbPath.c_str(), &st) == 0) {
569 if ((st.st_mode & (S_IXUSR | S_IXGRP | S_IRWXO)) != 0) {
570 int ret = chmod(dbPath.c_str(), st.st_mode & (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
571 if (ret != 0) {
572 LOG_ERROR("SqliteConnection LimitPermission chmod fail, err = %{public}d", errno);
573 }
574 }
575 } else {
576 LOG_ERROR("SqliteConnection LimitPermission stat fail, err = %{public}d", errno);
577 }
578 }
579
Collate8Compare(void * p,int n1,const void * v1,int n2,const void * v2)580 int Collate8Compare(void *p, int n1, const void *v1, int n2, const void *v2)
581 {
582 UCollator *coll = reinterpret_cast<UCollator *>(p);
583 UCharIterator i1, i2;
584 UErrorCode status = U_ZERO_ERROR;
585
586 uiter_setUTF8(&i1, (const char *)v1, n1);
587 uiter_setUTF8(&i2, (const char *)v2, n2);
588
589 UCollationResult result = ucol_strcollIter(coll, &i1, &i2, &status);
590
591 if (U_FAILURE(status)) {
592 LOG_ERROR("Ucol strcoll error.");
593 }
594
595 if (result == UCOL_LESS) {
596 return -1;
597 } else if (result == UCOL_GREATER) {
598 return 1;
599 }
600 return 0;
601 }
602
LocalizedCollatorDestroy(UCollator * collator)603 void LocalizedCollatorDestroy(UCollator *collator)
604 {
605 ucol_close(collator);
606 }
607
608 /**
609 * The database locale.
610 */
ConfigLocale(const std::string localeStr)611 int SqliteConnection::ConfigLocale(const std::string localeStr)
612 {
613 std::unique_lock<std::mutex> lock(rdbMutex);
614 UErrorCode status = U_ZERO_ERROR;
615 UCollator *collator = ucol_open(localeStr.c_str(), &status);
616 if (U_FAILURE(status)) {
617 LOG_ERROR("Can not open collator.");
618 return E_ERROR;
619 }
620 ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status);
621 if (U_FAILURE(status)) {
622 LOG_ERROR("Set attribute of collator failed.");
623 return E_ERROR;
624 }
625
626 int err = sqlite3_create_collation_v2(dbHandle, "LOCALES", SQLITE_UTF8, collator, Collate8Compare,
627 (void (*)(void *))LocalizedCollatorDestroy);
628 if (err != SQLITE_OK) {
629 LOG_ERROR("SCreate collator in sqlite3 failed.");
630 return err;
631 }
632
633 return E_OK;
634 }
635
636 /**
637 * Executes a statement and populates the specified with a range of results.
638 */
ExecuteForSharedBlock(int & rowNum,std::string sql,const std::vector<ValueObject> & bindArgs,AppDataFwk::SharedBlock * sharedBlock,int startPos,int requiredPos,bool isCountAllRows)639 int SqliteConnection::ExecuteForSharedBlock(int &rowNum, std::string sql, const std::vector<ValueObject> &bindArgs,
640 AppDataFwk::SharedBlock *sharedBlock, int startPos, int requiredPos, bool isCountAllRows)
641 {
642 if (sharedBlock == nullptr) {
643 LOG_ERROR("ExecuteForSharedBlock:sharedBlock is null.");
644 return E_ERROR;
645 }
646
647 SqliteConnectionS connection(this->dbHandle, this->openFlags, this->filePath);
648 int errCode = PrepareAndBind(sql, bindArgs);
649 if (errCode != E_OK) {
650 LOG_ERROR("ExecuteForSharedBlock:sharedBlock is null. SqliteConnectionS connection");
651 return errCode;
652 }
653
654 if (ClearSharedBlock(sharedBlock) == ERROR_STATUS) {
655 LOG_ERROR("ExecuteForSharedBlock:sharedBlock is null.");
656 return E_ERROR;
657 }
658
659 sqlite3_stmt *tempSqlite3St = statement.GetSql3Stmt();
660 int columnNum = sqlite3_column_count(tempSqlite3St);
661 if (SharedBlockSetColumnNum(sharedBlock, columnNum) == ERROR_STATUS) {
662 LOG_ERROR("ExecuteForSharedBlock:sharedBlock is null.");
663 return E_ERROR;
664 }
665
666 SharedBlockInfo sharedBlockInfo(&connection, sharedBlock, tempSqlite3St);
667 sharedBlockInfo.requiredPos = requiredPos;
668 sharedBlockInfo.columnNum = columnNum;
669 sharedBlockInfo.isCountAllRows = isCountAllRows;
670 sharedBlockInfo.startPos = startPos;
671
672 int rc = sqlite3_db_config(connection.db, SQLITE_DBCONFIG_USE_SHAREDBLOCK);
673 if (rc == SQLITE_OK) {
674 FillSharedBlockOpt(&sharedBlockInfo);
675 } else {
676 FillSharedBlock(&sharedBlockInfo);
677 }
678
679 if (!ResetStatement(&sharedBlockInfo)) {
680 return E_ERROR;
681 }
682 rowNum = static_cast<int>(GetCombinedData(sharedBlockInfo.startPos, sharedBlockInfo.totalRows));
683 errCode = statement.ResetStatementAndClearBindings();
684 return errCode;
685 }
686 } // namespace NativeRdb
687 } // namespace OHOS
688