玉兔远程控制 0.1.0-bate8
载入中...
搜索中...
未找到
DatabaseUrl.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include <QSqlQuery>
4#include <QSqlError>
5#include <QDateTime>
6#include <QLoggingCategory>
7#include "DatabaseUrl.h"
8
9static Q_LOGGING_CATEGORY(log, "DB.Url")
10CDatabaseUrl::CDatabaseUrl(const QString &szSuffix, QObject *parent)
11 : CDatabase{parent}
12{
13 m_szTableName = "url";
14 if(!szSuffix.isEmpty()) {
15 m_szTableName = m_szTableName + "_" + szSuffix;
16 }
17 m_szConnectName = "connect_" + m_szTableName;
18}
19
21{
22 bool success = false;
24 if(!success) return success;
25 success = m_iconDB.SetDatabase(GetDatabase(), m_pPara);
26 return success;
27}
28
29bool CDatabaseUrl::OnInitializeSqliteDatabase()
30{
31 QSqlQuery query(GetDatabase());
32 bool bRet = query.prepare(
33 "CREATE TABLE IF NOT EXISTS " + m_szTableName + " ("
34 " id INTEGER PRIMARY KEY AUTOINCREMENT,"
35 " url TEXT UNIQUE NOT NULL,"
36 " title TEXT,"
37 " icon INTEGER DEFAULT 0,"
38 " visit_time DATETIME DEFAULT CURRENT_TIMESTAMP"
39 ")"
40 );
41 if (!bRet) {
42 SetError("Failed to create " + m_szTableName + " sqlite table. Error: " + query.lastError().text());
43 qCritical(log) << GetError();
44 return false;
45 }
46 bRet = query.exec();
47 if (!bRet) {
48 SetError("Failed to create " + m_szTableName + " sqlite table: " + query.lastError().text()
49 + "; Sql: " + query.executedQuery());
50 return false;
51 }
52
53 // 创建索引
54 query.prepare("CREATE INDEX IF NOT EXISTS idx_" + m_szTableName + "_url ON " + m_szTableName + "(url)");
55 bRet = query.exec();
56 if (!bRet) {
57 qWarning(log) << "Failed to create index idx_" + m_szTableName + "_url:"
58 << query.lastError().text()
59 << query.executedQuery();
60 }
61
62 return true;
63}
64
65bool CDatabaseUrl::OnInitializeMySqlDatabase()
66{
67 QSqlQuery query(GetDatabase());
68
69 // 创建历史记录表
70 bool bRet = query.prepare(
71 "CREATE TABLE IF NOT EXISTS `" + m_szTableName + "` ("
72 " `id` INTEGER PRIMARY KEY AUTO_INCREMENT,"
73 " `url` TEXT NOT NULL,"
74 " `title` TEXT,"
75 " `icon` INTEGER DEFAULT 0,"
76 " `visit_time` DATETIME DEFAULT CURRENT_TIMESTAMP,"
77 " UNIQUE KEY `idx_url` (`url`(255))"
78 ")"
79 );
80 if (!bRet) {
81 SetError("Failed to create " + m_szTableName + " mysql table. Error: " + query.lastError().text());
82 qCritical(log) << GetError();
83 return false;
84 }
85 bRet = query.exec();
86 if (!bRet) {
87 SetError("Failed to create " + m_szTableName + " mysql table. Error: " + query.lastError().text()
88 + "; Sql: " + query.executedQuery());
89 qCritical(log) << GetError();
90 return false;
91 }
92
93 return bRet;
94}
95
96int CDatabaseUrl::AddUrl(const QString &url, const QString &title, const QIcon &icon)
97{
98 int nId = 0;
99 if (url.isEmpty()) return 0;
100
101 QSqlQuery query(GetDatabase());
102
103 // 检查URL是否已存在
104 query.prepare("SELECT id, title, icon FROM " + m_szTableName + " WHERE url = :url");
105 query.bindValue(":url", url);
106 if (!query.exec()) {
107 SetError("Failed to exec: " + query.executedQuery()
108 + "; Error: " + query.lastError().text());
109 qCritical(log) << GetError();
110 return -1;
111 }
112 if(query.next()) {
113 // 更新现有记录
114 nId = query.value(0).toInt();
115 QString szTitle = query.value(1).toString();
116 if(!title.isEmpty())
117 szTitle = title;
118 int iconID = query.value(2).toInt();
119 if(!icon.isNull())
120 iconID = m_iconDB.GetIcon(icon);
121 query.prepare(
122 "UPDATE " + m_szTableName + " SET "
123 "title = :title, "
124 "icon = :icon, "
125 "visit_time = :visit_time "
126 "WHERE id = :id"
127 );
128 query.bindValue(":title", szTitle);
129 query.bindValue(":icon", iconID);
130 query.bindValue(":visit_time", QDateTime::currentDateTime());
131 query.bindValue(":id", nId);
132 } else {
133 // 插入新记录
134 query.prepare(
135 "INSERT INTO " + m_szTableName + " (url, title, icon) "
136 "VALUES (:url, :title, :icon)"
137 );
138 query.bindValue(":url", url);
139 QString szTitle = title;
140 if(szTitle.isEmpty())
141 szTitle = url;
142 query.bindValue(":title", szTitle);
143 query.bindValue(":icon", m_iconDB.GetIcon(icon));
144 }
145
146 qDebug(log) << "Sql:" << query.executedQuery();
147 qDebug(log) << "Bound values:" << query.boundValues();
148 bool success = query.exec();
149 if (!success) {
150 nId = 0;
151 SetError("Failed to add " + m_szTableName + ": " + url
152 + "; Error: " + query.lastError().text()
153 + "; Sql: " + query.executedQuery());
154 qCritical(log) << GetError();
155 } else {
156 if(0 == nId)
157 nId = query.lastInsertId().toInt();
158 }
159
160 return nId;
161}
162
163bool CDatabaseUrl::DeleteUrl(const QString &url)
164{
165 if (url.isEmpty()) return false;
166
167 QSqlQuery query(GetDatabase());
168 query.prepare("DELETE from " + m_szTableName + " WHERE url = :url");
169 query.bindValue(":url", url);
170 bool bRet = query.exec();
171 if (!bRet) {
172 SetError("Failed to delete " + m_szTableName + ": " + url
173 + "; Error: " + query.lastError().text()
174 + "; Sql: " + query.executedQuery());
175 qCritical(log) << GetError();
176 }
177
178 return bRet;
179}
180
181bool CDatabaseUrl::DeleteUrl(int id)
182{
183 if (0 >= id) return false;
184
185 QSqlQuery query(GetDatabase());
186
187 query.prepare("DELETE from " + m_szTableName + " WHERE id = :id");
188 query.bindValue(":id", id);
189
190 bool success = query.exec();
191 if (!success) {
192 SetError("Failed to delete " + m_szTableName + ": " + QString::number(id)
193 + "; Error: " + query.lastError().text()
194 + "; Sql: " + query.executedQuery());
195 qCritical(log) << GetError();
196 }
197
198 return success;
199}
200
201bool CDatabaseUrl::UpdateUrl(const QString &url, const QString &title, const QIcon &icon)
202{
203 if (url.isEmpty()) return false;
204 if(title.isEmpty() && icon.isNull()) return false;
205
206 QString szSql;
207 szSql += "visit_time=\"" + QDateTime::currentDateTime().toString(Qt::ISODate) + "\" ";
208 if(!title.isEmpty())
209 szSql += ", title=\"" + title + "\" ";
210 if(!icon.isNull()) {
211 szSql += ", icon=" + QString::number(m_iconDB.GetIcon(icon)) + " ";
212 }
213
214 szSql = "UPDATE " + m_szTableName + " SET " + szSql;
215 szSql += " WHERE url=\"" + url + "\"";
216
217 QSqlQuery query(GetDatabase());
218 bool success = query.exec(szSql);
219 if (!success) {
220 SetError("Failed to update url: " + query.lastError().text() + "; Sql: " + szSql);
221 qCritical(log) << GetError();
222 }
223
224 return success;
225}
226
227bool CDatabaseUrl::UpdateUrl(int id, const QString &title, const QIcon &icon)
228{
229 if (0 >= id) return false;
230 if(title.isEmpty() && icon.isNull()) return false;
231
232 QString szSql;
233 szSql += "visit_time=\"" + QDateTime::currentDateTime().toString(Qt::ISODate) + "\" ";
234 if(!title.isEmpty())
235 szSql += ", title=\"" + title + "\" ";
236 if(!icon.isNull()) {
237 szSql += ", icon=" + QString::number(m_iconDB.GetIcon(icon)) + " ";
238 }
239 szSql = "UPDATE " + m_szTableName + " SET " + szSql;
240 szSql += " WHERE id = " + QString::number(id);
241
242 QSqlQuery query(GetDatabase());
243 query.prepare(szSql);
244 query.bindValue(":id", id);
245 bool success = query.exec();
246 if (!success) {
247 SetError("Failed to update url: " + query.lastError().text() + "; Sql: " + szSql);
248 qCritical(log) << GetError();
249 }
250
251 return success;
252}
253
254CDatabaseUrl::UrlItem CDatabaseUrl::GetItem(int id)
255{
256 UrlItem item;
257 if (0 >= id) return item;
258
259 QSqlQuery query(GetDatabase());
260 query.prepare("SELECT url, title, icon, visit_time FROM " + m_szTableName +
261 " WHERE id = :id");
262 query.bindValue(":id", id);
263 if (query.exec() && query.next()) {
264 item.id = id;
265 item.szUrl = query.value(0).toString();
266 item.szTitle = query.value(1).toString();
267 item.iconId = query.value(2).toInt();
268 item.icon = m_iconDB.GetIcon(item.iconId);
269 item.visit_time = query.value(3).toDateTime();
270 }
271 return item;
272}
273
274CDatabaseUrl::UrlItem CDatabaseUrl::GetItem(const QString& url)
275{
276 UrlItem item;
277 if (url.isEmpty()) return item;
278
279 QSqlQuery query(GetDatabase());
280 query.prepare("SELECT id, title, icon, visit_time FROM " + m_szTableName +
281 " WHERE url = :url");
282 query.bindValue(":url", url);
283 if (query.exec() && query.next()) {
284 item.szUrl = url;
285 item.id = query.value(0).toInt();
286 item.szTitle = query.value(1).toString();
287 item.iconId = query.value(2).toInt();
288 item.icon = m_iconDB.GetIcon(item.iconId);
289 item.visit_time = query.value(3).toDateTime();
290 }
291 return item;
292}
293
294int CDatabaseUrl::GetId(const QString& url)
295{
296 if (url.isEmpty()) return 0;
297 QSqlQuery query(GetDatabase());
298 bool bRet = query.prepare("SELECT id, title, icon FROM " + m_szTableName +
299 " WHERE url = :url");
300 if(!bRet) {
301 SetError("Failed to get id prepare: " + query.lastError().text() + "; url: " + url);
302 qCritical(log) << GetError();
303 return 0;
304 }
305 query.bindValue(":url", url);
306 bRet = query.exec();
307 if (!bRet) {
308 SetError("Failed to get id: " + query.lastError().text()
309 + "; Sql: " + query.executedQuery() + "; url: " + url);
310 qCritical(log) << GetError();
311 }
312 if(query.next()) {
313 return query.value(0).toInt();
314 }
315 return 0;
316}
317
318QList<int> CDatabaseUrl::GetDomain(const QString &szDomain)
319{
320 QList<int> ret;
321 QSqlQuery query(GetDatabase());
322 query.prepare("SELECT id FROM " + m_szTableName + " WHERE url LIKE :url");
323 query.bindValue(":url", QString("%%://%%%1%%").arg(szDomain));
324 bool bRet = query.exec();
325 if (bRet) {
326 while(query.next()) {
327 ret << query.value(0).toInt();
328 }
329 } else {
330 qCritical(log) << "Failed to get domain:"
331 << query.lastError().text()
332 << query.executedQuery();
333 }
334 return ret;
335}
336
337QList<CDatabaseUrl::UrlItem> CDatabaseUrl::Search(const QString &keyword)
338{
339 QList<UrlItem> items;
340
341 QSqlQuery query(GetDatabase());
342 QString searchPattern = "%" + keyword + "%";
343 query.prepare(
344 "SELECT id, url, title, visit_time, icon "
345 "FROM " + m_szTableName + " "
346 "WHERE url LIKE :pattern OR title LIKE :pattern "
347 "ORDER BY visit_time DESC"
348 );
349 query.bindValue(":pattern", searchPattern);
350 if (query.exec()) {
351 while (query.next()) {
352 UrlItem item;
353 item.id = query.value(0).toInt();
354 item.szUrl = query.value(1).toString();
355 item.szTitle = query.value(2).toString();
356 item.visit_time = query.value(3).toDateTime();
357 item.icon = m_iconDB.GetIcon(query.value(4).toInt());
358 items.append(item);
359 }
360 } else {
361 SetError("Failed to search:" + query.lastError().text()
362 + "; Sql: " + query.executedQuery());
363 qCritical(log) << GetError();
364 }
365
366 return items;
367}
368
369bool CDatabaseUrl::ExportToJson(QJsonObject &obj)
370{
371 return true;
372}
373
374bool CDatabaseUrl::ImportFromJson(const QJsonObject &obj)
375{
376 return true;
377}
int GetIcon(const QIcon &icon)
Get icon id
Definition Database.cpp:493
virtual bool OnInitializeDatabase() override
Initialize database
提供打开数据库和初始化数据库等接口
Definition Database.h:21
virtual bool OnInitializeDatabase()
Initialize database
Definition Database.cpp:288
bool SetDatabase(const CDatabase *db)
Share an existing database
Definition Database.cpp:34