1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : database migration dialog
9
* Copyright (C) 2009-2010 by Holger Foerster <Hamsi2k at freenet dot de>
11
* This program is free software; you can redistribute it
12
* and/or modify it under the terms of the GNU General
13
* Public License as published by the Free Software Foundation;
14
* either version 2, or (at your option)
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* ============================================================ */
24
#include "databasecopymanager.moc"
38
#include "databasecorebackend.h"
39
#include "databaseparameters.h"
41
#include "schemaupdater.h"
46
DatabaseCopyManager::DatabaseCopyManager()
50
DatabaseCopyManager::~DatabaseCopyManager()
54
void DatabaseCopyManager::stopProcessing()
56
isStopProcessing=true;
59
void DatabaseCopyManager::copyDatabases(DatabaseParameters fromDBParameters, DatabaseParameters toDBParameters)
61
isStopProcessing = false;
62
DatabaseLocking fromLocking;
63
DatabaseBackend fromDBbackend(&fromLocking, "MigrationFromDatabase");
65
if (!fromDBbackend.open(fromDBParameters))
67
emit finished(DatabaseCopyManager::failed, i18n("Error while opening the source database."));
71
DatabaseLocking toLocking;
72
DatabaseBackend toDBbackend(&toLocking, "MigrationToDatabase");
74
if (!toDBbackend.open(toDBParameters))
76
emit finished(DatabaseCopyManager::failed, i18n("Error while opening the target database."));
77
fromDBbackend.close();
81
QMap<QString, QVariant> bindingMap;
84
if (toDBbackend.execDBAction(toDBbackend.getDBAction("Migrate_Cleanup_DB"), bindingMap) != DatabaseCoreBackend::NoErrors)
86
emit finished(DatabaseCopyManager::failed, i18n("Error while scrubbing the target database."));
87
fromDBbackend.close();
92
// then create the schema
93
AlbumDB albumDB(&toDBbackend);
94
SchemaUpdater updater(&albumDB, &toDBbackend, toDBParameters);
96
emit stepStarted(i18n("Create Schema..."));
98
if (!updater.update())
100
emit finished(DatabaseCopyManager::failed, i18n("Error while creating the database schema."));
101
fromDBbackend.close();
106
emit stepStarted(i18n("Copy AlbumRoots..."));
108
// now perform the copy action
109
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_AlbumRoots"), toDBbackend, QString("Migrate_Write_AlbumRoots")))
111
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
115
emit stepStarted(i18n("Copy Albums..."));
117
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_Albums"), toDBbackend, QString("Migrate_Write_Albums")))
119
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
123
emit stepStarted(i18n("Copy Images..."));
125
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_Images"), toDBbackend, QString("Migrate_Write_Images")))
127
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
131
emit stepStarted(i18n("Copy ImageHaarMatrix..."));
133
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_ImageHaarMatrix"), toDBbackend, QString("Migrate_Write_ImageHaarMatrix")))
135
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
139
emit stepStarted(i18n("Copy ImageInformation..."));
141
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_ImageInformation"), toDBbackend, QString("Migrate_Write_ImageInformation")))
143
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
147
emit stepStarted(i18n("Copy ImageMetadata..."));
149
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_ImageMetadata"), toDBbackend, QString("Migrate_Write_ImageMetadata")))
151
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
155
emit stepStarted(i18n("Copy ImagePositions..."));
157
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_ImagePositions"), toDBbackend, QString("Migrate_Write_ImagePositions")))
159
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
163
emit stepStarted(i18n("Copy ImageComments..."));
165
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_ImageComments"), toDBbackend, QString("Migrate_Write_ImageComments")))
167
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
171
emit stepStarted(i18n("Copy ImageCopyright..."));
173
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_ImageCopyright"), toDBbackend, QString("Migrate_Write_ImageCopyright")))
175
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
179
emit stepStarted(i18n("Copy Tags..."));
181
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_Tags"), toDBbackend, QString("Migrate_Write_Tags")))
183
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
187
emit stepStarted(i18n("Copy ImageTags..."));
189
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_ImageTags"), toDBbackend, QString("Migrate_Write_ImageTags")))
191
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
195
emit stepStarted(i18n("Copy ImageProperties..."));
197
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_ImageProperties"), toDBbackend, QString("Migrate_Write_ImageProperties")))
199
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
203
emit stepStarted(i18n("Copy Searches..."));
205
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_Searches"), toDBbackend, QString("Migrate_Write_Searches")))
207
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
211
emit stepStarted(i18n("Copy DownloadHistory..."));
213
if (isStopProcessing || !copyTable(fromDBbackend, QString("Migrate_Read_DownloadHistory"), toDBbackend, QString("Migrate_Write_DownloadHistory")))
215
handleClosing(isStopProcessing, fromDBbackend, toDBbackend);
220
if (isStopThread || !copyTable(fromDBbackend, QString("Migrate_Read_Settings"), toDBbackend, QString("Migrate_Write_Settings")))
222
handleClosing(isStopThread, fromDBbackend, toDBbackend);
226
fromDBbackend.close();
229
emit finished(DatabaseCopyManager::success, QString());
232
bool DatabaseCopyManager::copyTable(DatabaseBackend& fromDBbackend, QString fromActionName, DatabaseBackend& toDBbackend, QString toActionName)
234
kDebug(50003) << "Trying to copy contents from DB with ActionName: [" << fromActionName
235
<< "] to DB with ActionName [" << toActionName << "]";
237
QMap<QString, QVariant> bindingMap;
238
// now perform the copy action
239
QList<QString> columnNames;
240
QSqlQuery result = fromDBbackend.execDBActionQuery(fromDBbackend.getDBAction(fromActionName), bindingMap) ;
244
if (result.driver()->hasFeature(QSqlDriver::QuerySize))
246
resultSize=result.size();
250
kDebug(50003) << "Driver doesn't support query size. We try to go to the last row and back to the current.";
253
* Now get the current row. If this is not possible, a value lower than 0 will be returned.
254
* To not confuse the log reading user, we reset this value to 0.
256
resultSize = result.at()<0 ? 0 : result.at();
260
kDebug(50003) << "Result size: ["<< resultSize << "]";
263
* If the sql query is forward only - perform the query again.
264
* This is not atomic, so it can be tend to different results between
265
* real database entries copied and shown at the progressbar.
267
if (result.isForwardOnly())
270
result = fromDBbackend.execDBActionQuery(fromDBbackend.getDBAction(fromActionName), bindingMap) ;
273
int columnCount = result.record().count();
275
for (int i=0; i<columnCount; i++)
277
// kDebug(50003) << "Column: ["<< result.record().fieldName(i) << "]";
278
columnNames.append(result.record().fieldName(i));
283
while (result.next())
285
kDebug(50003) << "Query isOnValidRow ["<< result.isValid() <<"] isActive ["<< result.isActive() <<"] result size: ["<< result.size() << "]";
287
if (isStopProcessing==true)
292
// Send a signal to the GUI to entertain the user
293
emit smallStepStarted(++resultCounter, resultSize);
295
// read the values from the fromDB into a hash
296
QMap<QString, QVariant> tempBindingMap;
299
foreach (QString columnName, columnNames)
301
kDebug(50003) << "Column: ["<< columnName << "] value ["<<result.value(i)<<"]";
302
tempBindingMap.insert(columnName.insert(0, ':'), result.value(i));
306
// insert the previous requested values to the toDB
307
DatabaseAction action = toDBbackend.getDBAction(toActionName);
308
DatabaseCoreBackend::QueryState queryStateResult = toDBbackend.execDBAction(action, tempBindingMap);
310
if (queryStateResult != DatabaseCoreBackend::NoErrors && toDBbackend.lastSQLError().isValid() && toDBbackend.lastSQLError().number()!=0)
312
kDebug(50003) << "Error while converting table data. Details: " << toDBbackend.lastSQLError();
313
QString errorMsg = i18n("Error while converting the database. \n Details: %1", toDBbackend.lastSQLError().databaseText());
314
emit finished(DatabaseCopyManager::failed, errorMsg);
323
void DatabaseCopyManager::handleClosing(bool isStopThread, DatabaseBackend& fromDBbackend, DatabaseBackend& toDBbackend)
327
emit finished(DatabaseCopyManager::canceled, "");
330
fromDBbackend.close();
334
} // namespace Digikam