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