• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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