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