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_database.h"
17 #include<iostream>
18
19 #include "resource_util.h"
20
21 namespace OHOS {
22 namespace Global {
23 namespace Restool {
24 using namespace std;
25 int32_t SqliteDatabase::id_ = 0;
Init(const string & dbPath)26 void SqliteDatabase::Init(const string &dbPath)
27 {
28 dbPath_ = dbPath;
29 }
30
OpenDatabase()31 bool SqliteDatabase::OpenDatabase()
32 {
33 int result = sqlite3_open(dbPath_.c_str(), &db_);
34 if (result) {
35 cerr << "Can't open database: " << sqlite3_errmsg(db_) << endl;
36 return false;
37 }
38
39 if (!CreateTable()) {
40 return false;
41 }
42
43 if (!FindMaxId()) {
44 return false;
45 }
46 return true;
47 }
48
CloseDatabase()49 void SqliteDatabase::CloseDatabase()
50 {
51 if (db_ == nullptr) {
52 return;
53 }
54 sqlite3_close(db_);
55 db_ = nullptr;
56 }
57
Insert(const ResourceItem & resourceItem)58 bool SqliteDatabase::Insert(const ResourceItem &resourceItem)
59 {
60 if (resourceItem.GetResType() == ResType::ID) {
61 return true;
62 }
63
64 int32_t id = -1;
65 if (!Query(resourceItem, id)) {
66 return false;
67 }
68
69 if (id >= 0) {
70 return true;
71 }
72
73 string data = GetValue(resourceItem);
74 string sql = "insert into resource_index values(" + to_string(id_) + ",'" + resourceItem.GetName() + "','" + \
75 data + "'," + \
76 to_string((int32_t)resourceItem.GetResType()) + ",'" + resourceItem.GetFilePath() + \
77 "','" + resourceItem.GetLimitKey() + "'," + to_string(priority_) + ")";
78 auto callback = [](void *owner, int argc, char **argv, char **azColName) -> int {
79 return 0;
80 };
81
82 char *zErrMsg = 0;
83 int result = sqlite3_exec(db_, sql.c_str(), callback, nullptr, &zErrMsg);
84 if (result) {
85 cerr << "insert sql error: " << zErrMsg << endl;
86 sqlite3_free(zErrMsg);
87 return false;
88 }
89 id_++;
90 return true;
91 }
92
Query(const ResourceItem & resourceItem,int32_t & id)93 bool SqliteDatabase::Query(const ResourceItem &resourceItem, int32_t &id)
94 {
95 string sql = "select id from resource_index where name='" + resourceItem.GetName() + \
96 "' and type='" + to_string((int32_t)resourceItem.GetResType()) + \
97 "' and limitkey='" + resourceItem.GetLimitKey() + \
98 "' and priority=" + to_string(priority_);
99 auto callback = [](void *id, int argc, char **argv, char **azColName) -> int {
100 if (argc > 0 && id) {
101 (*static_cast<int *>(id)) = atoi(argv[0]);
102 }
103 return 0;
104 };
105
106 id = -1;
107 char *zErrMsg = 0;
108 int result = sqlite3_exec(db_, sql.c_str(), callback, &id, &zErrMsg);
109 if (result) {
110 cerr << "query sql error: " << zErrMsg << endl;
111 sqlite3_free(zErrMsg);
112 return false;
113 }
114
115 if (id < 0) {
116 return true;
117 }
118
119 sql = "update resource_index set value='" + GetValue(resourceItem) + \
120 "', path='" + resourceItem.GetFilePath() + \
121 "' where id = " + to_string(id);
122 result = sqlite3_exec(db_, sql.c_str(), callback, nullptr, &zErrMsg);
123 if (result) {
124 cerr << "query sql error: " << zErrMsg << endl;
125 sqlite3_free(zErrMsg);
126 return false;
127 }
128 return true;
129 }
130
FindMaxId()131 bool SqliteDatabase::FindMaxId()
132 {
133 string sql = "select max(id) from resource_index";
134 auto callback = [](void *owner, int argc, char **argv, char **azColName) -> int {
135 if (argc > 0 && argv[0]) {
136 id_ = atoi(argv[0]) + 1;
137 }
138 return 0;
139 };
140
141 char *zErrMsg = 0;
142 int result = sqlite3_exec(db_, sql.c_str(), callback, nullptr, &zErrMsg);
143 if (result) {
144 cerr << "find max id sql error: " << zErrMsg << endl;
145 sqlite3_free(zErrMsg);
146 return false;
147 }
148 return true;
149 }
150
CreateTable()151 bool SqliteDatabase::CreateTable()
152 {
153 string sql = "select * from sqlite_master where name = 'resource_index'";
154 auto callback = [](void *find, int argc, char **argv, char **azColName) -> int {
155 if (argc > 0 && find) {
156 (*static_cast<bool *>(find)) = true;
157 }
158 return 0;
159 };
160
161 bool find = false;
162 char *zErrMsg = 0;
163 int result = sqlite3_exec(db_, sql.c_str(), callback, &find, &zErrMsg);
164 if (result) {
165 cerr << "search table error: " << zErrMsg << endl;
166 sqlite3_free(zErrMsg);
167 return false;
168 }
169
170 if (find) {
171 return true;
172 }
173
174 sql = "create table resource_index(id int, name, value image, type int, path, limitkey, priority int)";
175 result = sqlite3_exec(db_, sql.c_str(), callback, nullptr, &zErrMsg);
176 if (result) {
177 cerr << "create table error: " << zErrMsg << endl;
178 sqlite3_free(zErrMsg);
179 return false;
180 }
181 return true;
182 }
183
GetValue(const ResourceItem & resourceItem) const184 string SqliteDatabase::GetValue(const ResourceItem &resourceItem) const
185 {
186 string data(reinterpret_cast<const char *>(resourceItem.GetData()), resourceItem.GetDataLength());
187 if (resourceItem.GetResType() == ResType::STRARRAY || resourceItem.GetResType() == ResType::INTARRAY ||
188 resourceItem.GetResType() == ResType::THEME || resourceItem.GetResType() == ResType::PATTERN ||
189 resourceItem.GetResType() == ResType::PLURAL) {
190 vector<string> contents = ResourceUtil::DecomposeStrings(data);
191 Json::Value array(Json::arrayValue);
192 for (const auto &iter : contents) {
193 array.append(iter);
194 }
195 data = array.toStyledString();
196 }
197 return data;
198 }
199 }
200 }
201 }
202