1 #include <QApplication>
2 #include <QDateTime>
3 #include <QSqlDriver>
4 #include <QSqlQuery>
5 #include <QSqlError>
6 #include <QDateTime>
7 #include <QDir>
8 #include <QUuid>
9 #include <QRegExp>
10
11 #include "macros.h"
12 #include "settings.h"
13 #include "options.h"
14 #include "checksumdbmgr.h"
15
16 // external global variables
17 extern Settings *qmc2Config;
18
CheckSumDatabaseManager(QObject * parent,QString settingsKey)19 CheckSumDatabaseManager::CheckSumDatabaseManager(QObject *parent, QString settingsKey) :
20 QObject(parent),
21 m_settingsKey(settingsKey)
22 {
23 m_fileTypes << "ZIP" << "7Z" << "CHD" << "FILE";
24 m_connectionName = QString("checksum-db-connection-%1").arg(QUuid::createUuid().toString());
25 m_db = QSqlDatabase::addDatabase("QSQLITE", m_connectionName);
26 QString variantName(QMC2_VARIANT_NAME.toLower().replace(QRegExp("\\..*$"), ""));
27 if ( m_settingsKey == "ROMAlyzer" )
28 m_db.setDatabaseName(qmc2Config->value(QMC2_FRONTEND_PREFIX + m_settingsKey + "/CheckSumDbDatabasePath", QString(Options::configPath() + "/%1-checksum.db").arg(variantName)).toString());
29 else
30 m_db.setDatabaseName(qmc2Config->value(QMC2_FRONTEND_PREFIX + m_settingsKey + "/CheckSumDbDatabasePath", QString(Options::configPath() + "/%1-software-checksum.db").arg(variantName)).toString());
31 m_tableBasename = QString("%1_checksum").arg(variantName.replace("-", "_"));
32 if ( m_db.open() ) {
33 QStringList tables(m_db.driver()->tables(QSql::Tables));
34 if ( tables.count() != 2 || !tables.contains(m_tableBasename) || !tables.contains(QString("%1_metadata").arg(m_tableBasename)) || checkSumDbVersion() != QMC2_CHECKSUM_DB_VERSION )
35 recreateDatabase();
36 } else
37 emitlog(tr("WARNING: failed to open check-sum database '%1': error = '%2'").arg(m_db.databaseName()).arg(m_db.lastError().text()));
38 m_lastRowId = -1;
39 }
40
~CheckSumDatabaseManager()41 CheckSumDatabaseManager::~CheckSumDatabaseManager()
42 {
43 if ( m_db.isOpen() )
44 m_db.close();
45 }
46
qmc2Version()47 QString CheckSumDatabaseManager::qmc2Version()
48 {
49 QString qmc2_version;
50 QSqlQuery query(m_db);
51 query.prepare(QString("SELECT qmc2_version FROM %1_metadata WHERE row=0").arg(m_tableBasename));
52 if ( query.exec() ) {
53 if ( query.first() )
54 qmc2_version = query.value(0).toString();
55 query.finish();
56 } else
57 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("qmc2_version").arg(query.lastQuery()).arg(query.lastError().text()));
58 return qmc2_version;
59 }
60
setQmc2Version(QString qmc2_version)61 void CheckSumDatabaseManager::setQmc2Version(QString qmc2_version)
62 {
63 QSqlQuery query(m_db);
64 query.prepare(QString("SELECT qmc2_version FROM %1_metadata WHERE row=0").arg(m_tableBasename));
65 if ( query.exec() ) {
66 if ( !query.next() ) {
67 query.finish();
68 query.prepare(QString("INSERT INTO %1_metadata (qmc2_version, row) VALUES (:qmc2_version, 0)").arg(m_tableBasename));
69 query.bindValue(":qmc2_version", qmc2_version);
70 if ( !query.exec() )
71 emitlog(tr("WARNING: failed to add '%1' to check-sum database: query = '%2', error = '%3'").arg("qmc2_version").arg(query.lastQuery()).arg(query.lastError().text()));
72 } else {
73 query.finish();
74 query.prepare(QString("UPDATE %1_metadata SET qmc2_version=:qmc2_version WHERE row=0").arg(m_tableBasename));
75 query.bindValue(":qmc2_version", qmc2_version);
76 if ( !query.exec() )
77 emitlog(tr("WARNING: failed to update '%1' in check-sum database: query = '%2', error = '%3'").arg("qmc2_version").arg(query.lastQuery()).arg(query.lastError().text()));
78 }
79 query.finish();
80 } else
81 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("qmc2_version").arg(query.lastQuery()).arg(query.lastError().text()));
82 }
83
checkSumDbVersion()84 int CheckSumDatabaseManager::checkSumDbVersion()
85 {
86 int checksum_db_version = -1;
87 QSqlQuery query(m_db);
88 query.prepare(QString("SELECT checksum_db_version FROM %1_metadata WHERE row=0").arg(m_tableBasename));
89 if ( query.exec() ) {
90 if ( query.first() )
91 checksum_db_version = query.value(0).toInt();
92 query.finish();
93 } else
94 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("checksum_db_version").arg(query.lastQuery()).arg(query.lastError().text()));
95 return checksum_db_version;
96 }
97
setCheckSumDbVersion(int checksum_db_version)98 void CheckSumDatabaseManager::setCheckSumDbVersion(int checksum_db_version)
99 {
100 QSqlQuery query(m_db);
101 query.prepare(QString("SELECT checksum_db_version FROM %1_metadata WHERE row=0").arg(m_tableBasename));
102 if ( query.exec() ) {
103 if ( !query.next() ) {
104 query.finish();
105 query.prepare(QString("INSERT INTO %1_metadata (checksum_db_version, row) VALUES (:checksum_db_version, 0)").arg(m_tableBasename));
106 query.bindValue(":checksum_db_version", checksum_db_version);
107 if ( !query.exec() )
108 emitlog(tr("WARNING: failed to add '%1' to check-sum database: query = '%2', error = '%3'").arg("checksum_db_version").arg(query.lastQuery()).arg(query.lastError().text()));
109 } else {
110 query.finish();
111 query.prepare(QString("UPDATE %1_metadata SET checksum_db_version=:checksum_db_version WHERE row=0").arg(m_tableBasename));
112 query.bindValue(":checksum_db_version", checksum_db_version);
113 if ( !query.exec() )
114 emitlog(tr("WARNING: failed to update '%1' in check-sum database: query = '%2', error = '%3'").arg("checksum_db_version").arg(query.lastQuery()).arg(query.lastError().text()));
115 }
116 query.finish();
117 } else
118 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("checksum_db_version").arg(query.lastQuery()).arg(query.lastError().text()));
119 }
120
scanTime()121 uint CheckSumDatabaseManager::scanTime()
122 {
123 uint scan_time = 0;
124 QSqlQuery query(m_db);
125 query.prepare(QString("SELECT scan_time FROM %1_metadata WHERE row=0").arg(m_tableBasename));
126 if ( query.exec() ) {
127 if ( query.first() )
128 scan_time = query.value(0).toUInt();
129 query.finish();
130 } else
131 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("scan_time").arg(query.lastQuery()).arg(query.lastError().text()));
132 return scan_time;
133 }
134
setScanTime(uint scan_time)135 void CheckSumDatabaseManager::setScanTime(uint scan_time)
136 {
137 QSqlQuery query(m_db);
138 query.prepare(QString("SELECT scan_time FROM %1_metadata WHERE row=0").arg(m_tableBasename));
139 if ( query.exec() ) {
140 if ( !query.next() ) {
141 query.finish();
142 query.prepare(QString("INSERT INTO %1_metadata (scan_time, row) VALUES (:scan_time, 0)").arg(m_tableBasename));
143 query.bindValue(":scan_time", scan_time);
144 if ( !query.exec() )
145 emitlog(tr("WARNING: failed to add '%1' to check-sum database: query = '%2', error = '%3'").arg("scan_time").arg(query.lastQuery()).arg(query.lastError().text()));
146 } else {
147 query.finish();
148 query.prepare(QString("UPDATE %1_metadata SET scan_time=:scan_time WHERE row=0").arg(m_tableBasename));
149 query.bindValue(":scan_time", scan_time);
150 if ( !query.exec() )
151 emitlog(tr("WARNING: failed to update '%1' in check-sum database: query = '%2', error = '%3'").arg("scan_time").arg(query.lastQuery()).arg(query.lastError().text()));
152 }
153 query.finish();
154 } else
155 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("scan_time").arg(query.lastQuery()).arg(query.lastError().text()));
156 }
157
checkSumRowCount()158 qint64 CheckSumDatabaseManager::checkSumRowCount()
159 {
160 QSqlQuery query(m_db);
161 if ( query.exec(QString("SELECT COUNT(*) FROM %1").arg(m_tableBasename)) ) {
162 if ( query.first() )
163 return query.value(0).toLongLong();
164 else
165 return -1;
166 } else {
167 emitlog(tr("WARNING: failed to fetch row count from check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
168 return -1;
169 }
170 }
171
nextRowId(bool refreshRowIds)172 qint64 CheckSumDatabaseManager::nextRowId(bool refreshRowIds)
173 {
174 if ( refreshRowIds ) {
175 m_rowIdList.clear();
176 m_lastRowId = -1;
177 QSqlQuery query(m_db);
178 if ( query.exec(QString("SELECT rowid FROM %1").arg(m_tableBasename)) ) {
179 if ( query.first() ) {
180 do {
181 m_rowIdList << query.value(0).toLongLong();
182 } while ( query.next() );
183 m_lastRowId = 0;
184 return m_rowIdList[0];
185 }
186 } else {
187 emitlog(tr("WARNING: failed to fetch row IDs from check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
188 return -1;
189 }
190 } else if ( m_lastRowId > -1 ) {
191 m_lastRowId++;
192 if ( m_lastRowId < m_rowIdList.count() )
193 return m_rowIdList[m_lastRowId];
194 else
195 return -1;
196 }
197 return -1;
198 }
199
databaseSize()200 quint64 CheckSumDatabaseManager::databaseSize()
201 {
202 QSqlQuery query(m_db);
203 if ( query.exec("PRAGMA page_count") ) {
204 if ( query.first() ) {
205 quint64 page_count = query.value(0).toULongLong();
206 query.finish();
207 if ( query.exec("PRAGMA page_size") ) {
208 if ( query.first() ) {
209 quint64 page_size = query.value(0).toULongLong();
210 return page_count * page_size;
211 } else
212 return 0;
213 } else
214 return 0;
215 } else
216 return 0;
217 } else
218 return 0;
219 }
220
setCacheSize(quint64 kiloBytes)221 void CheckSumDatabaseManager::setCacheSize(quint64 kiloBytes)
222 {
223 QSqlQuery query(m_db);
224 if ( !query.exec(QString("PRAGMA cache_size = -%1").arg(kiloBytes)) )
225 emitlog(tr("WARNING: failed to change the '%1' setting for the check-sum database: query = '%2', error = '%3'").arg("cache_size").arg(query.lastQuery()).arg(query.lastError().text()));
226 }
227
setSyncMode(uint syncMode)228 void CheckSumDatabaseManager::setSyncMode(uint syncMode)
229 {
230 static QStringList dbSyncModes = QStringList() << "OFF" << "NORMAL" << "FULL";
231 if ( (int)syncMode > dbSyncModes.count() - 1 )
232 return;
233 QSqlQuery query(m_db);
234 if ( !query.exec(QString("PRAGMA synchronous = %1").arg(dbSyncModes[syncMode])) )
235 emitlog(tr("WARNING: failed to change the '%1' setting for the check-sum database: query = '%2', error = '%3'").arg("synchronous").arg(query.lastQuery()).arg(query.lastError().text()));
236 }
237
setJournalMode(uint journalMode)238 void CheckSumDatabaseManager::setJournalMode(uint journalMode)
239 {
240 static QStringList dbJournalModes = QStringList() << "DELETE" << "TRUNCATE" << "PERSIST" << "MEMORY" << "WAL" << "OFF";
241 if ( (int)journalMode > dbJournalModes.count() - 1 )
242 return;
243 QSqlQuery query(m_db);
244 if ( !query.exec(QString("PRAGMA journal_mode = %1").arg(dbJournalModes[journalMode])) )
245 emitlog(tr("WARNING: failed to change the '%1' setting for the check-sum database: query = '%2', error = '%3'").arg("journal_mode").arg(query.lastQuery()).arg(query.lastError().text()));
246 }
247
exists(QString sha1,QString crc,quint64 size)248 bool CheckSumDatabaseManager::exists(QString sha1, QString crc, quint64 size)
249 {
250 QSqlQuery query(m_db);
251 if ( size > 0 ) {
252 if ( sha1.isEmpty() ) {
253 query.prepare(QString("SELECT sha1, crc, size FROM %1 WHERE crc=:crc AND size=:size LIMIT 1").arg(m_tableBasename));
254 query.bindValue(":crc", crc);
255 query.bindValue(":size", size);
256 } else if ( crc.isEmpty() ) {
257 query.prepare(QString("SELECT sha1, crc, size FROM %1 WHERE sha1=:sha1 AND size=:size LIMIT 1").arg(m_tableBasename));
258 query.bindValue(":sha1", sha1);
259 query.bindValue(":size", size);
260 } else {
261 query.prepare(QString("SELECT sha1, crc, size FROM %1 WHERE sha1=:sha1 AND crc=:crc AND size=:size LIMIT 1").arg(m_tableBasename));
262 query.bindValue(":sha1", sha1);
263 query.bindValue(":crc", crc);
264 query.bindValue(":size", size);
265 }
266 } else {
267 if ( sha1.isEmpty() ) {
268 query.prepare(QString("SELECT sha1, crc FROM %1 WHERE crc=:crc LIMIT 1").arg(m_tableBasename));
269 query.bindValue(":crc", crc);
270 } else if ( crc.isEmpty() ) {
271 query.prepare(QString("SELECT sha1, crc FROM %1 WHERE sha1=:sha1 LIMIT 1").arg(m_tableBasename));
272 query.bindValue(":sha1", sha1);
273 } else {
274 query.prepare(QString("SELECT sha1, crc FROM %1 WHERE sha1=:sha1 AND crc=:crc LIMIT 1").arg(m_tableBasename));
275 query.bindValue(":sha1", sha1);
276 query.bindValue(":crc", crc);
277 }
278 }
279 if ( query.exec() )
280 return query.first();
281 else {
282 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("sha1, crc").arg(query.lastQuery()).arg(query.lastError().text()));
283 return false;
284 }
285 }
286
setData(QString sha1,QString crc,quint64 size,QString path,QString member,QString type)287 void CheckSumDatabaseManager::setData(QString sha1, QString crc, quint64 size, QString path, QString member, QString type)
288 {
289 QSqlQuery query(m_db);
290 query.prepare(QString("INSERT INTO %1 (sha1, crc, size, path, member, type) VALUES (:sha1, :crc, :size, :path, :member, :type)").arg(m_tableBasename));
291 query.bindValue(":sha1", sha1);
292 query.bindValue(":crc", crc);
293 query.bindValue(":size", size);
294 query.bindValue(":path", path);
295 query.bindValue(":member", member);
296 query.bindValue(":type", type);
297 if ( !query.exec() )
298 emitlog(tr("WARNING: failed to add '%1' to check-sum database: query = '%2', error = '%3'").arg("sha1, crc, size, path, member, type").arg(query.lastQuery()).arg(query.lastError().text()));
299 }
300
getData(QString sha1,QString crc,quint64 * size,QString * path,QString * member,QString * type)301 bool CheckSumDatabaseManager::getData(QString sha1, QString crc, quint64 *size, QString *path, QString *member, QString *type)
302 {
303 QSqlQuery query(m_db);
304 if ( *size > 0 ) {
305 if ( sha1.isEmpty() ) {
306 query.prepare(QString("SELECT size, path, member, type FROM %1 WHERE crc=:crc AND size=:size").arg(m_tableBasename));
307 query.bindValue(":crc", crc);
308 query.bindValue(":size", *size);
309 } else if ( crc.isEmpty() ) {
310 query.prepare(QString("SELECT size, path, member, type FROM %1 WHERE sha1=:sha1 AND size=:size").arg(m_tableBasename));
311 query.bindValue(":sha1", sha1);
312 query.bindValue(":size", *size);
313 } else {
314 query.prepare(QString("SELECT size, path, member, type FROM %1 WHERE sha1=:sha1 AND crc=:crc AND size=:size").arg(m_tableBasename));
315 query.bindValue(":sha1", sha1);
316 query.bindValue(":crc", crc);
317 query.bindValue(":size", *size);
318 }
319 } else {
320 if ( sha1.isEmpty() ) {
321 query.prepare(QString("SELECT size, path, member, type FROM %1 WHERE crc=:crc").arg(m_tableBasename));
322 query.bindValue(":crc", crc);
323 } else if ( crc.isEmpty() ) {
324 query.prepare(QString("SELECT size, path, member, type FROM %1 WHERE sha1=:sha1").arg(m_tableBasename));
325 query.bindValue(":sha1", sha1);
326 } else {
327 query.prepare(QString("SELECT size, path, member, type FROM %1 WHERE sha1=:sha1 AND crc=:crc").arg(m_tableBasename));
328 query.bindValue(":sha1", sha1);
329 query.bindValue(":crc", crc);
330 }
331 }
332 if ( query.exec() ) {
333 if ( query.first() ) {
334 *size = query.value(0).toULongLong();
335 *path = query.value(1).toString();
336 *member = query.value(2).toString();
337 *type = query.value(3).toString();
338 return true;
339 } else
340 return false;
341 } else {
342 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("path, member, type").arg(query.lastQuery()).arg(query.lastError().text()));
343 return false;
344 }
345 }
346
getCrc(QString sha1)347 QString CheckSumDatabaseManager::getCrc(QString sha1)
348 {
349 QSqlQuery query(m_db);
350 query.prepare(QString("SELECT crc FROM %1 WHERE sha1=:sha1").arg(m_tableBasename));
351 query.bindValue(":sha1", sha1);
352 if ( query.exec() ) {
353 if ( query.first() )
354 return query.value(0).toString();
355 else
356 return QString();
357 } else {
358 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("crc").arg(query.lastQuery()).arg(query.lastError().text()));
359 return QString();
360 }
361 }
362
getSha1(QString crc)363 QString CheckSumDatabaseManager::getSha1(QString crc)
364 {
365 QSqlQuery query(m_db);
366 query.prepare(QString("SELECT sha1 FROM %1 WHERE crc=:crc").arg(m_tableBasename));
367 query.bindValue(":crc", crc);
368 if ( query.exec() ) {
369 if ( query.first() )
370 return query.value(0).toString();
371 else
372 return QString();
373 } else {
374 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("sha1").arg(query.lastQuery()).arg(query.lastError().text()));
375 return QString();
376 }
377 }
378
pathRemove(QString path)379 void CheckSumDatabaseManager::pathRemove(QString path)
380 {
381 QSqlQuery query(m_db);
382 query.prepare(QString("DELETE FROM %1 WHERE path=:path").arg(m_tableBasename));
383 query.bindValue(":path", path);
384 if ( !query.exec() )
385 emitlog(tr("WARNING: failed to remove path '%1' from check-sum database: query = '%2', error = '%3'").arg(path).arg(query.lastQuery()).arg(query.lastError().text()));
386 }
387
pathOfRow(qint64 row,QString * key,bool simpleKey)388 QString CheckSumDatabaseManager::pathOfRow(qint64 row, QString *key, bool simpleKey)
389 {
390 QSqlQuery query(m_db);
391 if ( key ) {
392 query.prepare(QString("SELECT path, sha1, crc, size, type FROM %1 WHERE rowid=:row").arg(m_tableBasename));
393 query.bindValue(":row", row);
394 if ( query.exec() ) {
395 if ( query.first() ) {
396 if ( !simpleKey )
397 *key = QString("%1-%2-%3").arg(query.value(1).toString()).arg(query.value(2).toString()).arg(query.value(3).toString());
398 else if ( query.value(4).toString() == "CHD" )
399 *key = QString("%1-0-0").arg(query.value(1).toString());
400 else
401 *key = QString("%1-%2-%3").arg(query.value(1).toString()).arg(query.value(2).toString()).arg(query.value(3).toString());
402 return query.value(0).toString();
403 } else
404 return QString();
405 } else {
406 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("path, sha1, crc, size").arg(query.lastQuery()).arg(query.lastError().text()));
407 return QString();
408 }
409 } else {
410 query.prepare(QString("SELECT path FROM %1 WHERE rowid=:row").arg(m_tableBasename));
411 query.bindValue(":row", row);
412 if ( query.exec() ) {
413 if ( query.first() )
414 return query.value(0).toString();
415 else
416 return QString();
417 } else {
418 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("path").arg(query.lastQuery()).arg(query.lastError().text()));
419 return QString();
420 }
421 }
422 }
423
keyOfRow(qint64 row)424 QString CheckSumDatabaseManager::keyOfRow(qint64 row)
425 {
426 QSqlQuery query(m_db);
427 query.prepare(QString("SELECT sha1, crc, size FROM %1 WHERE rowid=:row").arg(m_tableBasename));
428 query.bindValue(":row", row);
429 if ( query.exec() ) {
430 if ( query.first() )
431 return QString("%1-%2-%3").arg(query.value(0).toString()).arg(query.value(1).toString()).arg(query.value(2).toString());
432 else
433 return QString();
434 } else {
435 emitlog(tr("WARNING: failed to fetch '%1' from check-sum database: query = '%2', error = '%3'").arg("sha1, crc, size").arg(query.lastQuery()).arg(query.lastError().text()));
436 return QString();
437 }
438 }
439
invalidateRow(qint64 row)440 void CheckSumDatabaseManager::invalidateRow(qint64 row)
441 {
442 QSqlQuery query(m_db);
443 query.prepare(QString("UPDATE %1 SET sha1='I' WHERE rowid=:row").arg(m_tableBasename));
444 query.bindValue(":row", row);
445 if ( !query.exec() )
446 emitlog(tr("WARNING: failed to update '%1' in check-sum database: query = '%2', error = '%3'").arg("sha1").arg(query.lastQuery()).arg(query.lastError().text()));
447
448 }
449
removeInvalidatedRows()450 void CheckSumDatabaseManager::removeInvalidatedRows()
451 {
452 QSqlQuery query(m_db);
453 if ( !query.exec(QString("DELETE FROM %1 WHERE sha1='I'").arg(m_tableBasename)) )
454 emitlog(tr("WARNING: failed to remove invalidated rows from check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
455 }
456
nameToType(QString name)457 int CheckSumDatabaseManager::nameToType(QString name)
458 {
459 return m_fileTypes.indexOf(name);
460 }
461
typeToName(int type)462 QString CheckSumDatabaseManager::typeToName(int type)
463 {
464 if ( type < m_fileTypes.count() )
465 return m_fileTypes[type];
466 else
467 return QString("UNKNOWN");
468 }
469
vacuum()470 void CheckSumDatabaseManager::vacuum()
471 {
472 QSqlQuery query(m_db);
473 query.exec("VACUUM");
474 query.finish();
475 }
476
recreateDatabase()477 void CheckSumDatabaseManager::recreateDatabase()
478 {
479 QSqlQuery query(m_db);
480 if ( !query.exec(QString("DROP INDEX IF EXISTS %1_index").arg(m_tableBasename)) ) {
481 emitlog(tr("WARNING: failed to remove check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
482 return;
483 }
484 query.finish();
485 if ( !query.exec(QString("DROP TABLE IF EXISTS %1").arg(m_tableBasename)) ) {
486 emitlog(tr("WARNING: failed to remove check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
487 return;
488 }
489 query.finish();
490 if ( !query.exec(QString("DROP TABLE IF EXISTS %1_metadata").arg(m_tableBasename)) ) {
491 emitlog(tr("WARNING: failed to remove check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
492 return;
493 }
494 query.finish();
495 // vaccum'ing the database frees all disk-space previously used
496 query.exec("VACUUM");
497 query.finish();
498 if ( !query.exec(QString("CREATE TABLE %1 (sha1 TEXT, crc TEXT, size UNSIGNED BIG INT, path TEXT, member TEXT, type TEXT, PRIMARY KEY (sha1, crc), CONSTRAINT %1_unique_checksums UNIQUE (sha1, crc))").arg(m_tableBasename)) ) {
499 emitlog(tr("WARNING: failed to create check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
500 return;
501 }
502 query.finish();
503 if ( !query.exec(QString("CREATE INDEX %1_index ON %1 (sha1, crc)").arg(m_tableBasename)) ) {
504 emitlog(tr("WARNING: failed to create check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
505 return;
506 }
507 query.finish();
508 if ( !query.exec(QString("CREATE TABLE %1_metadata (row INTEGER PRIMARY KEY, scan_time UNSIGNED BIG INT, qmc2_version TEXT, checksum_db_version INTEGER)").arg(m_tableBasename)) ) {
509 emitlog(tr("WARNING: failed to create check-sum database: query = '%1', error = '%2'").arg(query.lastQuery()).arg(query.lastError().text()));
510 return;
511 }
512 setScanTime(QDateTime::currentDateTime().toTime_t());
513 setQmc2Version(XSTR(QMC2_VERSION));
514 setCheckSumDbVersion(QMC2_CHECKSUM_DB_VERSION);
515 emitlog(tr("check-sum database '%1' initialized").arg(databasePath()));
516 }
517
emitlog(QString message)518 void CheckSumDatabaseManager::emitlog(QString message)
519 {
520 emit log(QDateTime::currentDateTime().toString("hh:mm:ss.zzz") + ": " + message);
521 }
522