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 #include "distributed_rdb_tools.h"
16 #include <dirent.h>
17 #include <string>
18 #include <sys/stat.h>
19 #include <random>
20 #include <algorithm>
21 #include <chrono>
22 #include <cmath>
23 #include <cstdio>
24 #include <cstring>
25 #ifndef USE_SQLITE_SYMBOLS
26 #include "sqlite3.h"
27 #else
28 #include "sqlite3sym.h"
29 #endif
30 #include "distributeddb_data_generator.h"
31 #include "distributed_test_sysinfo.h"
32 #include "platform_specific.h"
33 #include "securec.h"
34
35 using namespace std;
36 using namespace DistributedDB;
37 using namespace DistributedDBDataGenerator;
38
39 namespace {
40 const int MAX_DISTRIBUTED_TABLE_COUNT = 32;
41 std::string gtableNameList[MAX_DISTRIBUTED_TABLE_COUNT + 1];
42 const char *SQL_CREATE_NORMAL_TABLE = "CREATE TABLE IF NOT EXISTS NORMAL_RDB(" \
43 "id INT NOT NULL PRIMARY KEY AUTO_INCREMENT," \
44 "name VARCHAR(100) NOT NULL DEFAULT \"rdb\");";
45
46 const char *SQL_CREATE_CONSTRAINT_TABLE = "CREATE TABLE IF NOT EXISTS CONSTRAINT_RDB(" \
47 "id INT NOT NULL PRIMARY KEY AUTO_INCREMENT," \
48 "f_id INT," \
49 "age INT NOT NULL UNIQUE," \
50 "name VARCHAR(100) NOT NULL DEFAULT \"rdb\"," \
51 "address CHAR(50) COLLATE NOCASE," \
52 "identity INT NOT NULL, CHECK(identity > 10000) PRIMARY KEY(id, identity)," \
53 "FOREGIN key(f_id) references NORMAL_RDB(id));";
54
55 const char *SQL_CREATE_TRIGGER = "CREATE TRIGGER IF NOT EXISTS insertTrigger " \
56 "AFTER INSERT ON CONSTRAINT_RDB " \
57 "FOR EACH ROW " \
58 "BEGIN " \
59 "update NORMAL_RDB set name = \"name_001\" " \
60 "END";
61
62 const char *SQL_INSERT_NORMAL_TABLE = "INSERT INTO NORMAL_RDB (id,name)" \
63 "VALUES (1, \'rdb_001\'), (2, \'rdb_002\'), (3, \'rdb_003\'), (4, \'rdb_004\'), (5, \'rdb_005\');";
64
65
66 const char *SQL_ADD_FIELD_TABLE1 = "ALTER TABLE RDB_1 ADD COLUMN add_id INI";
67
68 const char *SQL_ADD_INDEX_TABLE2 = "CREATE INDEX name_index RDB_2 (name)";
69
70 const char *SQL_DROP_TABLE3 = "DROP TABLE RDB_3";
71
72 const char *SQL_DROP_CREATE_TABLE3 = "CREATE TABLE IF NOT EXISTS RDB_3(" \
73 "id INT NOT NULL PRIMARY KEY AUTO_INCREMENT);";
74
75 const char *SQL_DROP_TABLE4 = "DROP TABLE RDB_4";
76
77 const char *SQL_DROP_CREATE_TABLE4 = "CREATE TABLE IF NOT EXISTS RDB_4(" \
78 "id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, name CHAR(100));";
79
80 const char *SQL_JOURNAL_MODE = "PRAGMA journal_mode = DELETE;";
81
82 const char *SQL_SYNCHRONOUS_MODE = "PRAGMA synchronous = FULL;";
83
84 const char *SQL_INSERT_RDB5_TABLE = "INSERT INTO RDB_5 (id,name,age)" \
85 "VALUES (1, \'rdb_005\', \'name_rdb5\');";
86 }
87
GetOpenStoreStatus(const RelatetionalStoreManager * & manager,RelatetionalStoreDelegate * & delegate,const RdbParameters & param)88 DBStatus DistributedRdbTools::GetOpenStoreStatus(const RelatetionalStoreManager *&manager,
89 RelatetionalStoreDelegate *&delegate, const RdbParameters ¶m)
90 {
91 if (manager == nullptr) {
92 MST_LOG("%s GetRdbStore failed! manager nullptr.", TAG.c_str());
93 return DBStatus::DB_ERROR;
94 }
95 DBStatus status = manager->OpenStore(param.path, param.storeId, delegate);
96 if (delegate == nullptr) {
97 MST_LOG("%s GetRdbStore failed! delegate nullptr.", TAG.c_str());
98 }
99 return status;
100 }
101
GetCreateDistributedTableStatus(const RelatetionalStoreDelegate * & delegate,const std::string & tableName)102 DBStatus DistributedRdbTools::GetCreateDistributedTableStatus(const RelatetionalStoreDelegate *&delegate,
103 const std::string &tableName)
104 {
105 if (delegate == nullptr) {
106 MST_LOG("%s CreateDistributedTable failed! delegate nullptr.", TAG.c_str());
107 return DBStatus::DB_ERROR;
108 }
109 DBStatus status = delegate->CreateDistributedTable(tableName);
110 return status;
111 }
112
CloseStore(const RelatetionalStoreDelegate * & delegate)113 DBStatus DistributedRdbTools::CloseStore(const RelatetionalStoreDelegate *&delegate)
114 {
115 if (delegate == nullptr) {
116 MST_LOG("%s CloseStore failed! delegate nullptr.", TAG.c_str());
117 return DBStatus::DB_ERROR;
118 }
119 DBStatus status = delegate->CloseStore();
120 return status;
121 }
122
InitSqlite3Store(sqlite3 * & db,const RdbParameters & param)123 bool DistributedRdbTools::InitSqlite3Store(sqlite3 *&db, const RdbParameters ¶m)
124 {
125 const std::string dbName = param.path + param.storeId + ".db";
126 DBStributedDB::OS::RemoveFile(dbName);
127 int errCode = sqlite3_open(dbName, &db);
128 if (errCode != SQLITE_OK) {
129 MST_LOG("sqlite3_open Failed!");
130 return false;
131 }
132 int errCode1 = sqlite3_exec(db, "PRAGMA journal_mode = WAL;", 0, 0, 0);
133 if (errCode1 != SQLITE_OK) {
134 MST_LOG("PRAGMA journal_mode = WAL Failed!");
135 return false;
136 }
137 return true;
138 }
139
140 namespace {
SqliteExecSql(sqlite3 * db,const char * sql)141 void SqliteExecSql(sqlite3 *db, const char *sql)
142 {
143 char *errMsg = nullptr;
144 int errCode = sqlite3_exec(db, sql, nullptr, nullptr, &errMsg);
145 if (errCode != SQLITE_OK && errMsg != nullptr) {
146 MST_LOG("sqlite3_exec sql Failed(%s)", errMsg.c_str());
147 return false;
148 }
149 sqlite3_free(errMsg);
150 errMsg = nullptr;
151 }
152 }
153
InitTableDataAndTrigger(const sqlite3 * & db)154 bool DistributedRdbTools::InitTableDataAndTrigger(const sqlite3 *&db)
155 {
156 if (db == nullptr) {
157 MST_LOG("openStore Failed");
158 return false;
159 }
160 SqliteExecSql(db, SQL_CREATE_NORMAL_TABLE);
161 SqliteExecSql(db, SQL_CREATE_CONSTRAINT_TABLE);
162 SqliteExecSql(db, SQL_CREATE_TRIGGER);
163 SqliteExecSql(db, SQL_INSERT_NORMAL_TABLE);
164
165 for (int i = 1; i <= MAX_DISTRIBUTED_TABLE_COUNT + 1; i++) {
166 std::string str_0 = "RDB_" + std::to_string(i);
167 std::string str_1 = "CREATE TABLE IF NOT EXISTS "
168 std::string str_2 = "( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT," \
169 "name VARCHAR(100) NOT NULL, age VARCHAR(100) NOT NULL);";
170 std::string sql = str_1 + str_0 + str_2;
171
172 SqliteExecSql(db, sql.c_str());
173 gtableNameList[i-1] = str_0;
174 }
175 return true;
176 }
177
AlterTableAttributes(const sqlite3 * & db)178 bool DistributedRdbTools::AlterTableAttributes(const sqlite3 *&db)
179 {
180 if (db == nullptr) {
181 MST_LOG("openStore Failed");
182 return false;
183 }
184 char *errMsg = nullptr;
185 int errCode = sqlite3_exec(db, SQL_ADD_FIELD_TABLE1, nullptr, nullptr, &errMsg);
186 if (errCode != SQLITE_OK && errMsg != nullptr) {
187 MST_LOG("sqlite3_exec SQL_ADD_FIELD_TABLE1 Failed(%s)", errMsg.c_str());
188 return false;
189 }
190
191 int errCode1 = sqlite3_exec(db, SQL_ADD_INDEX_TABLE2, nullptr, nullptr, &errMsg);
192 if (errCode1 != SQLITE_OK && errMsg != nullptr) {
193 MST_LOG("sqlite3_exec SQL_ADD_INDEX_TABLE2 Failed(%s)", errMsg.c_str());
194 return false;
195 }
196
197 int errCode2 = sqlite3_exec(db, SQL_DROP_TABLE3, nullptr, nullptr, &errMsg);
198 if (errCode2 != SQLITE_OK && errMsg != nullptr) {
199 MST_LOG("sqlite3_exec SQL_DROP_TABLE3 Failed(%s)", errMsg.c_str());
200 return false;
201 }
202
203 int errCode3 = sqlite3_exec(db, SQL_DROP_CREATE_TABLE3, nullptr, nullptr, &errMsg);
204 if (errCode3 != SQLITE_OK && errMsg != nullptr) {
205 MST_LOG("sqlite3_exec SQL_ADD_INDEX_TABLE Failed(%s)", errMsg.c_str());
206 return false;
207 }
208
209 int errCode4 = sqlite3_exec(db, SQL_DROP_TABLE4, nullptr, nullptr, &errMsg);
210 if (errCode4 != SQLITE_OK && errMsg != nullptr) {
211 MST_LOG("sqlite3_exec SQL_DROP_TABLE4 Failed(%s)", errMsg.c_str());
212 return false;
213 }
214
215 int errCode5 = sqlite3_exec(db, SQL_DROP_CREATE_TABLE4, nullptr, nullptr, &errMsg);
216 if (errCode5 != SQLITE_OK && errMsg != nullptr) {
217 MST_LOG("sqlite3_exec SQL_DROP_CREATE_TABLE4 Failed(%s)", errMsg.c_str());
218 return false;
219 }
220 return true;
221 }
222
223
Sqlite3ExecOpration(const sqlite3 * & db,cont char * & sql_name)224 bool DistributedRdbTools::Sqlite3ExecOpration(const sqlite3 *&db, cont char *&sql_name)
225 {
226 if (db == nullptr) {
227 MST_LOG("openStore Failed");
228 return false;
229 }
230 int errCode = sqlite3_exec(db, sql_name, 0, 0, 0);
231 if (errCode != SQLITE_OK) {
232 MST_LOG("%s Failed!", sql_name);
233 return false;
234 }
235 return true;
236 }
237
CloseSqlite3Store(sqlite3 * & db)238 void DistributedRdbTools::CloseSqlite3Store(sqlite3 *&db)
239 {
240 if (db != nullptr) {
241 sqlite3_close(db);
242 db = nullptr;
243 }
244 }