玉兔远程控制 0.1.0-bate6
载入中...
搜索中...
未找到
Database.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include <QSqlDriver>
4#include <QSqlDatabase>
5#include <QSqlQuery>
6#include <QSqlError>
7#include <QLoggingCategory>
8#include <QJsonDocument>
9#include <QJsonArray>
10#include <QJsonObject>
11#include "RabbitCommonDir.h"
12#include "RabbitCommonTools.h"
13#include "IconUtils.h"
14#include "Database.h"
15
16static Q_LOGGING_CATEGORY(log, "DB")
17CDatabase::CDatabase(QObject *parent)
18 : QObject{parent}
19 , m_MinVersion("0.1.0")
20 , m_pPara(nullptr)
21{
22 qDebug(log) << Q_FUNC_INFO;
23 m_szConnectName = "connect";
24}
25
26CDatabase::~CDatabase()
27{
28 qDebug(log) << Q_FUNC_INFO;
29 CloseDatabase();
30}
31
32void CDatabase::SetDatabase(QSqlDatabase db, CParameterDatabase *pPara)
33{
34 QString szErr = "Only one of OpenDatabase and SetDatabase can be called, and it can only be called once";
35 Q_ASSERT_X(!IsOpen(), "Database", szErr.toStdString().c_str());
36 m_database = db;
37 m_pPara = pPara;
38}
39
40QSqlDatabase CDatabase::GetDatabase() const
41{
42 return m_database;
43}
44
46{
47 bool bRet = false;
48 if(!pPara) {
49 bRet = OpenSQLiteDatabase();
50 if(!bRet) return false;
51 return OnInitializeDatabase();
52 }
53
54 m_pPara = pPara;
55 QString szErr = "Only one of OpenDatabase or SetDatabase can be called, and it can only be called once";
56 Q_ASSERT_X(!IsOpen(), "Database", szErr.toStdString().c_str());
57
58 if(pPara->GetType() == "QSQLITE")
59 bRet = OpenSQLiteDatabase(QString(), pPara->GetDatabaseName());
60 else if(pPara->GetType() == "QMYSQL")
61 bRet = OpenMySqlDatabase(pPara);
62 else if(pPara->GetType() == "QODBC")
63 bRet = OpenODBCDatabase(pPara);
64
65 QSqlDriver *driver = GetDatabase().driver();
66 if (driver) {
67 qDebug(log) << "=== Features for" << pPara->GetType() << "===";
68 qDebug(log) << "Transactions:" << driver->hasFeature(QSqlDriver::Transactions);
69 qDebug(log) << "Query size:" << driver->hasFeature(QSqlDriver::QuerySize);
70 qDebug(log) << "BLOB:" << driver->hasFeature(QSqlDriver::BLOB);
71 qDebug(log) << "Unicode:" << driver->hasFeature(QSqlDriver::Unicode);
72 qDebug(log) << "Prepared queries:" << driver->hasFeature(QSqlDriver::PreparedQueries);
73 qDebug(log) << "Named placeholders:" << driver->hasFeature(QSqlDriver::NamedPlaceholders);
74 qDebug(log) << "Positional placeholders:" << driver->hasFeature(QSqlDriver::PositionalPlaceholders);
75 qDebug(log) << "Last insert ID:" << driver->hasFeature(QSqlDriver::LastInsertId);
76 qDebug(log) << "Batch operations:" << driver->hasFeature(QSqlDriver::BatchOperations);
77 qDebug(log) << "Event notifications:" << driver->hasFeature(QSqlDriver::EventNotifications);
78 qDebug(log) << "Finish query:" << driver->hasFeature(QSqlDriver::FinishQuery);
79 qDebug(log) << "Multiple result sets:" << driver->hasFeature(QSqlDriver::MultipleResultSets);
80 qDebug(log) << "Cancel query:" << driver->hasFeature(QSqlDriver::CancelQuery);
81 }
82
83 if(!bRet) return false;
84
85 return OnInitializeDatabase();
86}
87
88bool CDatabase::OpenSQLiteDatabase(
89 const QString &connectionName, const QString &dbPath)
90{
91 QString databasePath;
92 if (dbPath.isEmpty()) {
93 // 使用默认路径
94 QString dataDir = RabbitCommon::CDir::Instance()->GetDirUserDatabase();
95 QDir dir(dataDir);
96 if (!dir.exists()) {
97 dir.mkpath(dataDir);
98 }
99 databasePath = dir.filePath("remote_control.db");
100 } else {
101 databasePath = dbPath;
102 }
103
104 if(!connectionName.isEmpty())
105 m_szConnectName = connectionName;
106
107 // 打开或创建数据库
108 m_database = QSqlDatabase::addDatabase("QSQLITE", m_szConnectName);
109 m_database.setDatabaseName(databasePath);
110
111 if (!m_database.open()) {
112 qCritical(log) << "Failed to open sqlite database:"
113 << m_database.lastError().text()
114 << "connect name:" << m_database.connectionName()
115 << "database name:" << m_database.databaseName();
116 return false;
117 }
118
119 qInfo(log) << "Open sqlite database connect:"
120 << m_database.connectionName()
121 << "database name:" << m_database.databaseName();
122 return true;
123}
124
125bool CDatabase::OpenMySqlDatabase(CParameterDatabase *pPara)
126{
127 if(!pPara) return false;
128 // 打开或创建数据库
129 m_database = QSqlDatabase::addDatabase("QMYSQL", m_szConnectName);
130 QString szDbName = pPara->GetDatabaseName();
131 if(szDbName.isEmpty())
132 szDbName = "remote_control";
133 m_database.setDatabaseName(szDbName);
134 auto &net = pPara->m_Net;
135 m_database.setHostName(net.GetHost());
136 m_database.setPort(net.GetPort());
137 auto &user = net.m_User;
138 m_database.setUserName(user.GetName());
139 m_database.setPassword(user.GetPassword());
140
141 if (!m_database.open()) {
142 qCritical(log) << "Failed to open mysql database:"
143 << m_database.lastError().text()
144 << "connect name:" << m_database.connectionName()
145 << "database name:" << m_database.databaseName();
146 return false;
147 }
148
149 QSqlQuery query(GetDatabase());
150 bool success = query.exec("CREATE DATABASE IF NOT EXISTS " + szDbName);
151 if (!success) {
152 qCritical(log) << "Failed to create" << szDbName << "database:"
153 << query.lastError().text()
154 << "Sql:" << query.executedQuery();
155 return false;
156 }
157
158 success = query.exec("use remote_control");
159 if (!success) {
160 qCritical(log) << "Failed to use" << szDbName << "database:"
161 << query.lastError().text()
162 << "Sql:" << query.executedQuery();
163 return false;
164 }
165
166 qInfo(log) << "Open mysql database connect:"
167 << m_database.connectionName()
168 << "database name:" << m_database.databaseName();
169 return true;
170}
171
172bool CDatabase::OpenODBCDatabase(CParameterDatabase* pPara)
173{
174 if(!pPara) return false;
175 // 打开或创建数据库
176 m_database = QSqlDatabase::addDatabase("QODBC", m_szConnectName);
177 QString szDbName = pPara->GetDatabaseName();
178 if(szDbName.isEmpty())
179 szDbName = "remote_control";
180 m_database.setDatabaseName(szDbName);
181
182 if (!m_database.open()) {
183 qCritical(log) << "Failed to open odbc database:"
184 << m_database.lastError().text()
185 << "connect name:" << m_database.connectionName()
186 << "database name:" << m_database.databaseName();
187 return false;
188 }
189
190 QSqlQuery query(GetDatabase());
191 bool success = query.exec("CREATE DATABASE IF NOT EXISTS " + szDbName);
192 if (!success) {
193 qCritical(log) << "Failed to create" << szDbName << "database:"
194 << query.lastError().text()
195 << "Sql:" << query.executedQuery();
196 return false;
197 }
198
199 success = query.exec("use remote_control");
200 if (!success) {
201 qCritical(log) << "Failed to use" << szDbName << "database:"
202 << query.lastError().text()
203 << "Sql:" << query.executedQuery();
204 return false;
205 }
206
207 qInfo(log) << "Open odbc database connect:"
208 << m_database.connectionName()
209 << "database name:" << m_database.databaseName();
210 return true;
211}
212
213bool CDatabase::OnInitializeDatabase()
214{
215 bool bRet = false;
216 if(!m_pPara) {
217 bRet = OnInitializeSqliteDatabase();
218 return bRet;
219 }
220 if(m_pPara->GetType() == "QSQLITE")
221 bRet = OnInitializeSqliteDatabase();
222 else if(m_pPara->GetType() == "QMYSQL" || m_pPara->GetType() == "QODBC") {
223 bRet = OnInitializeMySqlDatabase();
224 }
225 return bRet;
226}
227
228bool CDatabase::OnInitializeSqliteDatabase()
229{
230 return true;
231}
232
233bool CDatabase::OnInitializeMySqlDatabase()
234{
235 return true;
236}
237
238bool CDatabase::IsOpen() const
239{
240 return m_database.isOpen();
241}
242
243void CDatabase::CloseDatabase()
244{
245 if (m_database.isOpen()) {
246 m_database.close();
247 }
248 QSqlDatabase::removeDatabase(m_szConnectName);
249}
250
251bool CDatabase::ExportToJsonFile(const QString &szFile)
252{
253 QFile file(szFile);
254 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
255 qCritical(log) << "Failed to open file:" << szFile << file.errorString();
256 return false;
257 }
258
259 QTextStream out(&file);
260#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
261 out.setEncoding(QStringConverter::Utf8);
262#else
263 out.setCodec("UTF-8");
264#endif
265 out.setGenerateByteOrderMark(true); // 添加 UTF-8 BOM
266
267 QJsonDocument doc;
268 QJsonObject root;
269 root.insert("Title", "Rabbit Remote Control");
270 root.insert("Author", "Kang Lin");
271 root.insert("Version", "0.1.0");
272
273 bool bRet = true;
274 bRet = ExportToJson(root);
275 if(bRet) {
276 doc.setObject(root);
277 out << doc.toJson();
278 }
279
280 file.close();
281 return true;
282}
283
284bool CDatabase::ImportFromJsonFile(const QString &szFile)
285{
286 bool bRet = false;
287 QFile file(szFile);
288 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
289 qCritical(log) << "Failed to open file:" << szFile << file.errorString();
290 return false;
291 }
292
293 do {
294 QJsonDocument doc;
295 doc = QJsonDocument::fromJson(file.readAll());
296 if(!doc.isObject())
297 break;
298 auto root = doc.object();
299 if(root["Title"] != "Rabbit Remote Control") {
300 qCritical(log) << "The file format is error";
301 break;
302 }
303 QString szVersion = root["Version"].toString();
304 if(RabbitCommon::CTools::VersionCompare(szVersion, m_MinVersion) < 0) {
305 qCritical(log) << "The version is not support:"
306 << szVersion << "<" << m_MinVersion;
307 break;
308 }
309 bRet = ImportFromJson(doc.object());
310 } while(0);
311
312 file.close();
313 return bRet;
314}
315
316CDatabaseIcon::CDatabaseIcon(QObject *parent)
317 : CDatabase(parent)
318{
319 m_szConnectName = "icon_connect";
320 m_szTableName = "icon";
321}
322
323CDatabaseIcon::CDatabaseIcon(const QString &szPrefix, QObject *parent)
324 : CDatabaseIcon(parent)
325{
326 m_szConnectName = "icon_connect";
327 if(!szPrefix.isEmpty())
328 m_szTableName = szPrefix + "_" + m_szTableName;
329}
330
331bool CDatabaseIcon::OnInitializeSqliteDatabase()
332{
333 QSqlQuery query(GetDatabase());
334
335 // Create icon table
336 QString szSql =
337 "CREATE TABLE IF NOT EXISTS " + m_szTableName + " ("
338 " id INTEGER PRIMARY KEY AUTOINCREMENT,"
339 " name TEXT UNIQUE," // Icon name. see QIcon::name()
340 " hash TEXT," // Icon hash value
341 " data BLOB" // Icon binary data
342 ")"
343 ;
344 bool success = query.exec(szSql);
345 if (!success) {
346 qCritical(log) << "Failed to create icon sqlite table:"
347 << m_szTableName << query.lastError().text()
348 << "Sql:" << query.executedQuery();
349 return false;
350 }
351 success = query.exec("CREATE INDEX IF NOT EXISTS idx_" + m_szTableName + "_name ON " + m_szTableName + "(name)");
352 if (!success) {
353 qWarning(log) << "Failed to create icon name index:"
354 << m_szTableName << query.lastError().text()
355 << "Sql:" << query.executedQuery();
356 }
357 success = query.exec("CREATE INDEX IF NOT EXISTS idx_" + m_szTableName + "_hash ON " + m_szTableName + "(hash)");
358 if (!success) {
359 qWarning(log) << "Failed to create icon hash index:"
360 << m_szTableName << query.lastError().text()
361 << "Sql:" << query.executedQuery();
362 }
363 return true;
364}
365
366bool CDatabaseIcon::OnInitializeMySqlDatabase()
367{
368 QSqlQuery query(GetDatabase());
369
370 // Create icon table
371 QString szSql =
372 "CREATE TABLE IF NOT EXISTS " + m_szTableName + " ("
373 " id INTEGER PRIMARY KEY AUTO_INCREMENT,"
374 " name TEXT," // Icon name. see QIcon::name()
375 " hash TEXT," // Icon hash value
376 " data LONGBLOB," // Icon binary data
377 " UNIQUE KEY idx_icon_name (name(255)),"
378 " INDEX idx_icon_hash (hash(255))"
379 ")"
380 ;
381 bool success = query.exec(szSql);
382 if (!success) {
383 qCritical(log) << "Failed to create icon mysql table:"
384 << m_szTableName << query.lastError().text()
385 << "Sql:" << query.executedQuery();
386 return false;
387 }
388
389 return true;
390}
391
392int CDatabaseIcon::GetIcon(const QIcon &icon)
393{
394 bool bRet = false;
395 if(icon.isNull()) return 0;
396
397 QString szSql;
398 QSqlQuery query(GetDatabase());
399 QString szName = icon.name();
400 if(szName.isEmpty()) {
401 // Check hash and data
402 QByteArray data = RabbitCommon::CIconUtils::iconToByteArray(icon);
403 QString szHash = RabbitCommon::CIconUtils::hashIconData(data);
404 if(data.isEmpty() || szHash.isEmpty())
405 return 0;
406 szSql = "SELECT id, data FROM " + m_szTableName + " WHERE hash=:hash";
407 query.prepare(szSql);
408 query.bindValue(":hash", szHash);
409 // qDebug(log) << "prepare:" << query.executedQuery();
410 // qDebug(log) << "Bound values:" << query.boundValues();
411 bRet = query.exec();
412 if(!bRet) {
413 qCritical(log) << "Failed to select icon hash:"
414 << szHash << query.lastError().text();
415 return 0;
416 }
417 while (query.next()) {
418 // check a same data
419 if(data == query.value(1).toByteArray()) {
420 return query.value(0).toInt();
421 }
422 }
423
424 szSql = "INSERT INTO " + m_szTableName + " (hash, data) "
425 "VALUES (:hash, :data)";
426 query.prepare(szSql);
427 query.bindValue(":hash", szHash);
428 query.bindValue(":data", data);
429 bRet = query.exec();
430 if(!bRet) {
431 qCritical(log) << "Failed to insert icon hash:"
432 << szHash << query.lastError().text();
433 return 0;
434 }
435 return query.lastInsertId().toInt();
436 }
437
438 // Check name
439 szSql = "SELECT id FROM " + m_szTableName + " WHERE name=:name";
440 query.prepare(szSql);
441 query.bindValue(":name", szName);
442 bRet = query.exec();
443 if(!bRet) {
444 qCritical(log) << "Failed to select icon name:"
445 << szName << query.lastError().text();
446 return 0;
447 }
448 if(query.next()) {
449 return query.value(0).toInt();
450 }
451
452 // Insert icon
453 szSql = "INSERT INTO " + m_szTableName + " (name) VALUES (:name)";
454 query.prepare(szSql);
455 query.bindValue(":name", szName);
456 bRet = query.exec();
457 if(!bRet) {
458 qCritical(log) << "Failed to insert icon name:"
459 << szName << query.lastError().text();
460 return 0;
461 }
462 return query.lastInsertId().toInt();
463}
464
465QIcon CDatabaseIcon::GetIcon(int id)
466{
467 QIcon icon;
468 QSqlQuery query(GetDatabase());
469 query.prepare(
470 "SELECT name, data FROM " + m_szTableName +
471 " WHERE id=:id "
472 );
473 query.bindValue(":id", id);
474 bool bRet = query.exec();
475 if(!bRet) {
476 qCritical(log) << "Failed to get icon id:"
477 << id << query.lastError().text();
478 return icon;
479 }
480
481 if (query.next()) {
482 QString szName = query.value(0).toString();
483 if(!szName.isEmpty()) {
484 return QIcon::fromTheme(szName);
485 }
486 QByteArray ba = query.value(1).toByteArray();
487 return RabbitCommon::CIconUtils::byteArrayToIcon(ba);
488 }
489 return icon;
490}
491
492bool CDatabaseIcon::ExportToJson(QJsonObject &obj)
493{
494 QSqlQuery query(GetDatabase());
495 query.prepare(
496 "SELECT id, name, hash, data FROM " + m_szTableName
497 );
498 //qDebug(log) << "Sql:" << query.executedQuery();
499 bool bRet = query.exec();
500 if(!bRet) {
501 qCritical(log) << "Failed to export icon to json:"
502 << query.lastError().text()
503 << "Sql:" << query.executedQuery();
504 return false;
505 }
506
507 QJsonArray icon;
508 while (query.next()) {
509 QJsonObject i;
510 i.insert("id", query.value(0).toInt());
511 i.insert("name", query.value(1).toString());
512 i.insert("hash", query.value(2).toString());
513 i.insert("data", query.value(3).toByteArray().toBase64().toStdString().c_str());
514 icon.append(i);
515 }
516 if(!icon.isEmpty())
517 obj.insert("icon", icon);
518 return true;
519}
520
521bool CDatabaseIcon::ImportFromJson(const QJsonObject &obj)
522{
523 return true;
524}
525
526bool CDatabaseIcon::ExportIconToJson(const QIcon &icon, QJsonObject &obj)
527{
528 QString szIconName = icon.name();
529 if(szIconName.isEmpty()) {
530 QByteArray baIcon = RabbitCommon::CIconUtils::iconToByteArray(icon);
531 obj.insert("IconData", baIcon.toBase64().toStdString().c_str());
532 } else {
533 obj.insert("IconName", szIconName);
534 }
535 return true;
536}
537
538bool CDatabaseIcon::ImportIconFromJson(const QJsonObject &itemObj, QIcon &icon)
539{
540 QString szIconName = itemObj["IconName"].toString();
541 if(szIconName.isEmpty()) {
542 QByteArray baIcon(itemObj["IconData"].toString().toStdString().c_str());
543 if(!baIcon.isEmpty()) {
544 baIcon = QByteArray::fromBase64(baIcon);
545 icon = RabbitCommon::CIconUtils::byteArrayToIcon(baIcon);
546 }
547 } else {
548 icon = QIcon::fromTheme(szIconName);
549 }
550 return true;
551}
552
553bool CDatabaseFile::ExportFileToJson(const QString &szFile, QJsonObject &obj)
554{
555 QFileInfo fi(szFile);
556 if(!fi.exists()) {
557 qCritical(log) << "File is not exist:" << szFile;
558 return false;
559 }
560 QFile f(szFile);
561 if(!f.open(QFile::ReadOnly | QFile::Text)) {
562 qCritical(log) << "Failed to open file:" << szFile << f.errorString();
563 return false;
564 }
565 QString szFileContent = f.readAll();
566 f.close();
567 if(szFileContent.isEmpty()) {
568 qCritical(log) << "The file is empty:" << szFile;
569 return false;
570 };
571 obj.insert("FileName", fi.fileName());
572 obj.insert("FileContent", szFileContent);
573 return true;
574}
575
576bool CDatabaseFile::ImportFileFromJson(const QJsonObject &obj, QString &szFile)
577{
578 QString szFileContent = obj["FileContent"].toString();
579 if(szFileContent.isEmpty()) {
580 qCritical(log) << "The file is empty";
581 return false;
582 }
583 szFile = obj["FileName"].toString();
584 if(szFile.isEmpty()) {
585 qCritical(log) << "The file name is empty";
586 return false;
587 }
588 szFile = RabbitCommon::CDir::Instance()->GetDirUserData()
589 + QDir::separator() + szFile;
590 QFileInfo fi(szFile);
591 if(!fi.exists()) {
592 QFile f(szFile);
593 if(!f.open(QFile::WriteOnly | QFile::Text)) {
594 qCritical(log) << "Failed to open file:" << szFile
595 << f.errorString();
596 return false;
597 }
598 f.write(szFileContent.toStdString().c_str(), szFileContent.size());
599 f.close();
600 }
601 return true;
602}
603
604bool CDatabaseFile::ImportFileToDatabaseFromJson(const QJsonObject &obj, QString &szFile)
605{
606 bool bRet = ImportFileFromJson(obj, szFile);
607 if(!bRet) return bRet;
608 bRet = Save(szFile);
609 return bRet;
610}
611
612CDatabaseFile::CDatabaseFile(QObject* parent) : CDatabase(parent)
613{
614 m_szConnectName = "file_connect";
615 m_szTableName = "file";
616}
617
618CDatabaseFile::CDatabaseFile(const QString &szPrefix, QObject *parent)
619 : CDatabase(parent)
620{
621 m_szConnectName = "file_connect";
622 if(!szPrefix.isEmpty())
623 m_szTableName = szPrefix + "_" + m_szTableName;
624}
625
626bool CDatabaseFile::ExportToJson(QJsonObject &obj)
627{
628 return true;
629}
630
631bool CDatabaseFile::ImportFromJson(const QJsonObject &obj)
632{
633 return true;
634}
635
636QByteArray CDatabaseFile::Load(const QString &szFile)
637{
638 QByteArray content;
639 if(szFile.isEmpty()) return content;
640 QFileInfo fi(szFile);
641 QSqlQuery query(GetDatabase());
642 query.prepare(
643 "SELECT content FROM " + m_szTableName + " "
644 " WHERE file=:file");
645 query.bindValue(":file", fi.fileName());
646 bool ok = query.exec();
647 if(ok) {
648 if(query.next()) {
649 content = query.value(0).toByteArray();
650 }
651 } else {
652 qCritical(log) << "Failed to Load:"
653 << m_szTableName << query.lastError().text()
654 << "Sql:" << query.executedQuery();
655 }
656 return content;
657}
658
659bool CDatabaseFile::Save(const QString &szFile)
660{
661 bool bRet = true;
662 if(szFile.isEmpty()) return false;
663 QFile f(szFile);
664 if(!f.open(QFile::ReadOnly | QFile::Text)) {
665 qCritical(log) << "Failed to open file:"
666 << szFile << f.errorString() << ":" << f.error();
667 return false;
668 }
669 QByteArray content = f.readAll();
670 f.close();
671 QFileInfo fi(szFile);
672 QSqlQuery query(GetDatabase());
673 query.prepare(
674 "SELECT content FROM " + m_szTableName + " "
675 " WHERE file=:file");
676 query.bindValue(":file", fi.fileName());
677 bool success = query.exec();
678 if(success && query.next()) {
679 query.prepare(
680 "UPDATE " + m_szTableName + " "
681 "SET content = :content "
682 "WHERE file = :file"
683 );
684 query.bindValue(":file", fi.fileName());
685 query.bindValue(":content", content);
686 } else {
687 query.prepare(
688 "INSERT INTO " + m_szTableName + " "
689 "(file, content) "
690 "VALUES (:file, :content)"
691 );
692 query.bindValue(":file", fi.fileName());
693 query.bindValue(":content", content);
694 }
695 success = query.exec();
696 if (!success) {
697 qCritical(log) << "Failed to save file:"
698 << m_szTableName << query.lastError().text()
699 << "Sql:" << query.executedQuery();
700 return false;
701 }
702
703 return bRet;
704}
705
706bool CDatabaseFile::OnInitializeSqliteDatabase()
707{
708 QSqlQuery query(GetDatabase());
709
710 // Create file table
711 QString szSql =
712 "CREATE TABLE IF NOT EXISTS " + m_szTableName + " ("
713 " file TEXT KEY NOT NULL UNIQUE,"
714 " content LONGBLOB"
715 ")"
716 ;
717 bool success = query.exec(szSql);
718 if (!success) {
719 qCritical(log) << "Failed to create file table:"
720 << m_szTableName << query.lastError().text()
721 << "Sql:" << query.executedQuery();
722 return false;
723 }
724
725 return true;
726}
727
728bool CDatabaseFile::OnInitializeMySqlDatabase()
729{
730 QSqlQuery query(GetDatabase());
731 QString szSql = "CREATE TABLE IF NOT EXISTS `" + m_szTableName + "` ( "
732 "`file` TEXT NOT NULL , "
733 "`content` LONGBLOB, "
734 "UNIQUE KEY `uk_file` (`file`(255))"
735 ")";
736 bool success = query.exec(szSql);
737 if (!success) {
738 qCritical(log) << "Failed to create file table:"
739 << m_szTableName << query.lastError().text()
740 << "Sql:" << query.executedQuery();
741 return false;
742 }
743
744 return true;
745}
bool Save(const QString &szFile)
Save
Definition Database.cpp:659
QByteArray Load(const QString &szFile)
Load
Definition Database.cpp:636
int GetIcon(const QIcon &icon)
Get icon id
Definition Database.cpp:392
virtual bool OpenDatabase(CParameterDatabase *pPara=nullptr)
OpenDatabase
Definition Database.cpp:45