1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "sqlite_storage_engine.h"
17
18 #include "db_errno.h"
19 #include "log_print.h"
20 #include "sqlite_storage_executor.h"
21 #include "sqlite_utils.h"
22 #include "runtime_context.h"
23
24 namespace DistributedDB {
SQLiteStorageEngine()25 SQLiteStorageEngine::SQLiteStorageEngine()
26 {}
27
~SQLiteStorageEngine()28 SQLiteStorageEngine::~SQLiteStorageEngine()
29 {}
30
InitSQLiteStorageEngine(const StorageEngineAttr & poolSize,const OpenDbProperties & option,const std::string & identifier)31 int SQLiteStorageEngine::InitSQLiteStorageEngine(const StorageEngineAttr &poolSize, const OpenDbProperties &option,
32 const std::string &identifier)
33 {
34 if (StorageEngine::CheckEngineAttr(poolSize)) {
35 LOGE("Invalid storage engine attributes!");
36 return -E_INVALID_ARGS;
37 }
38 engineAttr_ = poolSize;
39 option_ = option;
40 identifier_ = identifier;
41 if (GetEngineState() == EngineState::CACHEDB) {
42 LOGI("Is alive! not need to create executor, only fix option.");
43 return E_OK;
44 }
45 int errCode = Init();
46 if (errCode != E_OK) {
47 LOGI("Storage engine init fail! errCode = [%d]", errCode);
48 }
49 return errCode;
50 }
51
NewSQLiteStorageExecutor(sqlite3 * dbHandle,bool isWrite,bool isMemDb)52 StorageExecutor *SQLiteStorageEngine::NewSQLiteStorageExecutor(sqlite3 *dbHandle, bool isWrite, bool isMemDb)
53 {
54 return new (std::nothrow) SQLiteStorageExecutor(dbHandle, isWrite, isMemDb);
55 }
56
Upgrade(sqlite3 * db)57 int SQLiteStorageEngine::Upgrade(sqlite3 *db)
58 {
59 // SQLiteSingleVerStorageEngine override this function to do table structure and even content upgrade
60 // SQLiteLocalStorageEngine is used by SQLiteLocalKvDB, and SQLiteLocalKvDB is used as LocalStore, CommitStorage,
61 // ValueSliceStorage, MetaDataStorage, all of them will not change the table structure,
62 // so the version of these dbFile only represent for the content version.
63 // SQLiteLocalStorageEngine do not override this function so content upgrade can only be done by the Storage
64 // who use the SQLiteLocalKvDB.
65 // MultiVerStorageEngine do not inherit SQLiteStorageEngine.
66 return E_OK;
67 }
68
CreateNewExecutor(bool isWrite,StorageExecutor * & handle)69 int SQLiteStorageEngine::CreateNewExecutor(bool isWrite, StorageExecutor *&handle)
70 {
71 sqlite3 *dbHandle = nullptr;
72 int errCode = SQLiteUtils::OpenDatabase(option_, dbHandle);
73 if (errCode != E_OK) {
74 return errCode;
75 }
76 bool isMemDb = option_.isMemDb;
77 if (!isUpdated_) {
78 errCode = Upgrade(dbHandle);
79 if (errCode != E_OK) {
80 (void)sqlite3_close_v2(dbHandle);
81 dbHandle = nullptr;
82 return errCode;
83 }
84 SQLiteUtils::ExecuteCheckPoint(dbHandle);
85 isUpdated_ = true;
86 }
87
88 handle = NewSQLiteStorageExecutor(dbHandle, isWrite, isMemDb);
89 if (handle == nullptr) {
90 LOGE("New SQLiteStorageExecutor[%d] for the pool failed.", isWrite);
91 (void)sqlite3_close_v2(dbHandle);
92 dbHandle = nullptr;
93 return -E_OUT_OF_MEMORY;
94 }
95 return E_OK;
96 }
97
ReInit()98 int SQLiteStorageEngine::ReInit()
99 {
100 return E_OK;
101 }
102
IsNeedTobeReleased() const103 bool SQLiteStorageEngine::IsNeedTobeReleased() const
104 {
105 EngineState engineState = GetEngineState();
106 return ((engineState == EngineState::MAINDB) || (engineState == EngineState::INVALID));
107 }
108
GetIdentifier() const109 const std::string &SQLiteStorageEngine::GetIdentifier() const
110 {
111 return identifier_;
112 }
113
GetEngineState() const114 EngineState SQLiteStorageEngine::GetEngineState() const
115 {
116 return engineState_;
117 }
118
SetEngineState(EngineState state)119 void SQLiteStorageEngine::SetEngineState(EngineState state)
120 {
121 LOGD("[SQLiteStorageEngine::SetEngineState] Engine State : [%d]", state);
122 engineState_ = state; // Current usage logically can guarante no concurrency
123 }
124
GetOpenOption() const125 const OpenDbProperties &SQLiteStorageEngine::GetOpenOption() const
126 {
127 return option_;
128 }
129
IsNeedMigrate() const130 bool SQLiteStorageEngine::IsNeedMigrate() const
131 {
132 return false;
133 }
134
ExecuteMigrate()135 int SQLiteStorageEngine::ExecuteMigrate()
136 {
137 return -E_NOT_SUPPORT;
138 }
139
IncreaseCacheRecordVersion()140 void SQLiteStorageEngine::IncreaseCacheRecordVersion()
141 {
142 return;
143 }
144
GetCacheRecordVersion() const145 uint64_t SQLiteStorageEngine::GetCacheRecordVersion() const
146 {
147 return 0;
148 }
149
GetAndIncreaseCacheRecordVersion()150 uint64_t SQLiteStorageEngine::GetAndIncreaseCacheRecordVersion()
151 {
152 return 0;
153 }
154
IsEngineCorrupted() const155 bool SQLiteStorageEngine::IsEngineCorrupted() const
156 {
157 return false;
158 }
159
ClearEnginePasswd()160 void SQLiteStorageEngine::ClearEnginePasswd()
161 {
162 option_.passwd.Clear();
163 }
164
CheckEngineOption(const KvDBProperties & kvDBProp) const165 int SQLiteStorageEngine::CheckEngineOption(const KvDBProperties &kvDBProp) const
166 {
167 SecurityOption securityOpt;
168 if (RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()) {
169 securityOpt.securityLabel = kvDBProp.GetSecLabel();
170 securityOpt.securityFlag = kvDBProp.GetSecFlag();
171 }
172
173 int conflictReslovePolicy = kvDBProp.GetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, DEFAULT_LAST_WIN);
174 bool createDirByStoreIdOnly = kvDBProp.GetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, false);
175
176 if (kvDBProp.GetSchemaConstRef().IsSchemaValid() == option_.schema.empty()) {
177 // If both true, newSchema not empty, oriEngineSchema empty, not same
178 // If both false, newSchema empty, oriEngineSchema not empty, not same
179 LOGE("Engine and kvdb schema only one not empty! kvdb schema is [%d]", option_.schema.empty());
180 return -E_SCHEMA_MISMATCH;
181 }
182 // Here both schema empty or not empty, be the same
183 if (kvDBProp.GetSchemaConstRef().IsSchemaValid()) {
184 int errCode = kvDBProp.GetSchemaConstRef().CompareAgainstSchemaString(option_.schema);
185 if (errCode != -E_SCHEMA_EQUAL_EXACTLY) {
186 LOGE("Engine and kvdb schema mismatch!");
187 return -E_SCHEMA_MISMATCH;
188 }
189 }
190
191 bool isMemDb = kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false);
192 // Here both schema empty or "not empty and equal exactly", this is ok as required
193 if (isMemDb == false &&
194 option_.createDirByStoreIdOnly == createDirByStoreIdOnly &&
195 option_.securityOpt == securityOpt &&
196 option_.conflictReslovePolicy == conflictReslovePolicy) {
197 return E_OK;
198 }
199 return -E_INVALID_ARGS;
200 }
201 }
202