• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef RELATIONAL_STORE
16 #include "sqlite_single_relational_storage_engine.h"
17 
18 #include "db_common.h"
19 #include "db_errno.h"
20 #include "res_finalizer.h"
21 #include "sqlite_relational_database_upgrader.h"
22 #include "sqlite_single_ver_relational_storage_executor.h"
23 
24 
25 namespace DistributedDB {
SQLiteSingleRelationalStorageEngine(RelationalDBProperties properties)26 SQLiteSingleRelationalStorageEngine::SQLiteSingleRelationalStorageEngine(RelationalDBProperties properties)
27     : properties_(properties)
28 {}
29 
~SQLiteSingleRelationalStorageEngine()30 SQLiteSingleRelationalStorageEngine::~SQLiteSingleRelationalStorageEngine()
31 {}
32 
NewSQLiteStorageExecutor(sqlite3 * dbHandle,bool isWrite,bool isMemDb)33 StorageExecutor *SQLiteSingleRelationalStorageEngine::NewSQLiteStorageExecutor(sqlite3 *dbHandle, bool isWrite,
34     bool isMemDb)
35 {
36     auto mode = static_cast<DistributedTableMode>(properties_.GetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE,
37         DistributedTableMode::SPLIT_BY_DEVICE));
38     return new (std::nothrow) SQLiteSingleVerRelationalStorageExecutor(dbHandle, isWrite, mode);
39 }
40 
Upgrade(sqlite3 * db)41 int SQLiteSingleRelationalStorageEngine::Upgrade(sqlite3 *db)
42 {
43     int errCode = SQLiteUtils::CreateRelationalMetaTable(db);
44     if (errCode != E_OK) {
45         LOGE("Create relational store meta table failed. err=%d", errCode);
46         return errCode;
47     }
48     LOGD("[RelationalEngine][Upgrade] upgrade relational store.");
49     auto upgrader = std::make_unique<SqliteRelationalDatabaseUpgrader>(db);
50     return upgrader->Upgrade();
51 }
52 
RegisterFunction(sqlite3 * db) const53 int SQLiteSingleRelationalStorageEngine::RegisterFunction(sqlite3 *db) const
54 {
55     int errCode = SQLiteUtils::RegisterCalcHash(db);
56     if (errCode != E_OK) {
57         LOGE("[engine] register calculate hash failed!");
58         return errCode;
59     }
60 
61     errCode = SQLiteUtils::RegisterGetSysTime(db);
62     if (errCode != E_OK) {
63         LOGE("[engine] register get sys time failed!");
64     }
65     return E_OK;
66 }
67 
CreateNewExecutor(bool isWrite,StorageExecutor * & handle)68 int SQLiteSingleRelationalStorageEngine::CreateNewExecutor(bool isWrite, StorageExecutor *&handle)
69 {
70     sqlite3 *db = nullptr;
71     int errCode = SQLiteUtils::OpenDatabase(option_, db, false);
72     if (errCode != E_OK) {
73         return errCode;
74     }
75     do {
76         errCode = Upgrade(db); // create meta_data table.
77         if (errCode != E_OK) {
78             break;
79         }
80 
81         errCode = RegisterFunction(db);
82         if (errCode != E_OK) {
83             break;
84         }
85 
86         handle = NewSQLiteStorageExecutor(db, isWrite, false);
87         if (handle == nullptr) {
88             LOGE("[Relational] New SQLiteStorageExecutor[%d] for the pool failed.", isWrite);
89             errCode = -E_OUT_OF_MEMORY;
90             break;
91         }
92         return E_OK;
93     } while (false);
94 
95     (void)sqlite3_close_v2(db);
96     db = nullptr;
97     return errCode;
98 }
99 
ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor * & handle)100 int SQLiteSingleRelationalStorageEngine::ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor *&handle)
101 {
102     if (handle == nullptr) {
103         return E_OK;
104     }
105     StorageExecutor *databaseHandle = handle;
106     Recycle(databaseHandle);
107     handle = nullptr;
108     return E_OK;
109 }
110 
SetSchema(const RelationalSchemaObject & schema)111 void SQLiteSingleRelationalStorageEngine::SetSchema(const RelationalSchemaObject &schema)
112 {
113     std::lock_guard lock(schemaMutex_);
114     schema_ = schema;
115 }
116 
GetSchema() const117 RelationalSchemaObject SQLiteSingleRelationalStorageEngine::GetSchema() const
118 {
119     std::lock_guard lock(schemaMutex_);
120     return schema_;
121 }
122 
123 namespace {
SaveSchemaToMetaTable(SQLiteSingleVerRelationalStorageExecutor * handle,const RelationalSchemaObject & schema)124 int SaveSchemaToMetaTable(SQLiteSingleVerRelationalStorageExecutor *handle, const RelationalSchemaObject &schema)
125 {
126     const Key schemaKey(DBConstant::RELATIONAL_SCHEMA_KEY.begin(), DBConstant::RELATIONAL_SCHEMA_KEY.end());
127     Value schemaVal;
128     DBCommon::StringToVector(schema.ToSchemaString(), schemaVal);
129     int errCode = handle->PutKvData(schemaKey, schemaVal); // save schema to meta_data
130     if (errCode != E_OK) {
131         LOGE("Save schema to meta table failed. %d", errCode);
132     }
133     return errCode;
134 }
135 }
136 
CreateDistributedTable(const std::string & tableName,const std::string & identity,bool & schemaChanged)137 int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName,
138     const std::string &identity, bool &schemaChanged)
139 {
140     std::lock_guard lock(schemaMutex_);
141     RelationalSchemaObject schema = schema_;
142     bool isUpgraded = false;
143     if (schema.GetTable(tableName).GetTableName() == tableName) {
144         LOGI("distributed table bas been created.");
145         isUpgraded = true;
146         int errCode = UpgradeDistributedTable(tableName, schemaChanged);
147         if (errCode != E_OK) {
148             LOGE("Upgrade distributed table failed. %d", errCode);
149             return errCode;
150         }
151         // Triggers may need to be rebuilt, no return directly
152     } else if (schema.GetTables().size() >= DBConstant::MAX_DISTRIBUTED_TABLE_COUNT) {
153         LOGE("The number of distributed tables is exceeds limit.");
154         return -E_MAX_LIMITS;
155     } else {
156         schemaChanged = true;
157     }
158 
159     return CreateDistributedTable(tableName, isUpgraded, identity, schema);
160 }
161 
CreateDistributedTable(const std::string & tableName,bool isUpgraded,const std::string & identity,RelationalSchemaObject & schema)162 int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName, bool isUpgraded,
163     const std::string &identity, RelationalSchemaObject &schema)
164 {
165     LOGD("Create distributed table.");
166     int errCode = E_OK;
167     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
168         errCode));
169     if (handle == nullptr) {
170         return errCode;
171     }
172     ResFinalizer finalizer([&handle, this] { this->ReleaseExecutor(handle); });
173 
174     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
175     if (errCode != E_OK) {
176         return errCode;
177     }
178 
179     auto mode = static_cast<DistributedTableMode>(properties_.GetIntProp(
180         RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE));
181     TableInfo table;
182     errCode = handle->CreateDistributedTable(tableName, mode, isUpgraded, identity, table);
183     if (errCode != E_OK) {
184         LOGE("create distributed table failed. %d", errCode);
185         (void)handle->Rollback();
186         return errCode;
187     }
188 
189     schema.SetTableMode(mode);
190     schema.AddRelationalTable(table);
191     errCode = SaveSchemaToMetaTable(handle, schema);
192     if (errCode != E_OK) {
193         LOGE("Save schema to meta table for create distributed table failed. %d", errCode);
194         (void)handle->Rollback();
195         return errCode;
196     }
197 
198     errCode = handle->Commit();
199     if (errCode == E_OK) {
200         schema_ = schema;
201     }
202     return errCode;
203 }
204 
UpgradeDistributedTable(const std::string & tableName,bool & schemaChanged)205 int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::string &tableName, bool &schemaChanged)
206 {
207     LOGD("Upgrade distributed table.");
208     RelationalSchemaObject schema = schema_;
209     int errCode = E_OK;
210     auto *handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
211         errCode));
212     if (handle == nullptr) {
213         return errCode;
214     }
215 
216     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
217     if (errCode != E_OK) {
218         ReleaseExecutor(handle);
219         return errCode;
220     }
221 
222     auto mode = static_cast<DistributedTableMode>(properties_.GetIntProp(
223         RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE));
224     errCode = handle->UpgradeDistributedTable(tableName, mode, schemaChanged, schema);
225     if (errCode != E_OK) {
226         LOGE("Upgrade distributed table failed. %d", errCode);
227         (void)handle->Rollback();
228         ReleaseExecutor(handle);
229         return errCode;
230     }
231 
232     errCode = SaveSchemaToMetaTable(handle, schema);
233         if (errCode != E_OK) {
234         LOGE("Save schema to meta table for upgrade distributed table failed. %d", errCode);
235         (void)handle->Rollback();
236         ReleaseExecutor(handle);
237         return errCode;
238     }
239 
240     errCode = handle->Commit();
241     if (errCode == E_OK) {
242         schema_ = schema;
243     }
244     ReleaseExecutor(handle);
245     return errCode;
246 }
247 
CleanDistributedDeviceTable(std::vector<std::string> & missingTables)248 int SQLiteSingleRelationalStorageEngine::CleanDistributedDeviceTable(std::vector<std::string> &missingTables)
249 {
250     int errCode = E_OK;
251     auto handle = static_cast<SQLiteSingleVerRelationalStorageExecutor *>(FindExecutor(true, OperatePerm::NORMAL_PERM,
252         errCode));
253     if (handle == nullptr) {
254         return errCode;
255     }
256 
257     std::lock_guard lock(schemaMutex_);
258     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
259     if (errCode != E_OK) {
260         ReleaseExecutor(handle);
261         return errCode;
262     }
263 
264     errCode = handle->CheckAndCleanDistributedTable(schema_.GetTableNames(), missingTables);
265     if (errCode == E_OK) {
266         errCode = handle->Commit();
267         if (errCode == E_OK) {
268             // Remove non-existent tables from the schema
269             for (const auto &tableName : missingTables) {
270                 schema_.RemoveRelationalTable(tableName);
271             }
272             SaveSchemaToMetaTable(handle, schema_); // save schema to meta_data
273         }
274     } else {
275         LOGE("Check distributed table failed. %d", errCode);
276         (void)handle->Rollback();
277     }
278 
279     ReleaseExecutor(handle);
280     return errCode;
281 }
282 
GetProperties() const283 const RelationalDBProperties &SQLiteSingleRelationalStorageEngine::GetProperties() const
284 {
285     return properties_;
286 }
287 
SetProperties(const RelationalDBProperties & properties)288 void SQLiteSingleRelationalStorageEngine::SetProperties(const RelationalDBProperties &properties)
289 {
290     properties_ = properties;
291 }
292 }
293 #endif