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