defuze.me
Client
|
00001 /************************************************************************** 00002 ** defuze.me Epitech Innovative Project 00003 ** 00004 ** Copyright 2010 00005 ** Athena Calmettes - Jocelyn De La Rosa - Francois Gaillard 00006 ** Adrien Jarthon - Alexandre Moore - Luc Peres - Arnaud Sellier 00007 ** 00008 ** All rights reserved. 00009 **************************************************************************/ 00010 00011 #include <iostream> 00012 #include "dbcore.hpp" 00013 #include "migration.hpp" 00014 #include "migration_list.hpp" 00015 #include "exception.hpp" 00016 00017 using namespace DB; 00018 00019 Migration::Migration(const char* _name) : _name(_name) 00020 {} 00021 00022 Migration::~Migration() 00023 {} 00024 00025 const QString& Migration::name() 00026 { 00027 return (_name); 00028 } 00029 00030 bool Migration::run(bool forward) 00031 { 00032 QSqlDatabase db = QSqlDatabase::database(); 00033 try { 00034 db.transaction(); 00035 if (forward) 00036 { 00037 qDebug() << "DB::Migration [" << name() << "] run up"; 00038 up(); 00039 } 00040 else 00041 { 00042 qDebug() << "DB::Migration [" << name() << "] run down"; 00043 down(); 00044 } 00045 db.commit(); 00046 return true; 00047 } catch (...) { 00048 qDebug() << "DB::Migration [" << name() << "] failed: " << db.lastError().text(); 00049 db.rollback(); 00050 throw_exception(0x01, QObject::tr("Can't update your database !")); 00051 return false; 00052 } 00053 } 00054 00055 bool Migration::exec(const QString sql) 00056 { 00057 return QSqlQuery().exec(sql); 00058 } 00059 00060 bool Migration::createTable(const QString name, const QString definition) 00061 { 00062 return exec(QString("create table %1 (%2)").arg(name, definition)); 00063 } 00064 00065 bool Migration::dropTable(const QString name) 00066 { 00067 return exec(QString("drop table %1").arg(name)); 00068 } 00069 00070 MigrationEngine::MigrationEngine(DBCore& dbCore) : db(dbCore) 00071 { 00072 migrations.push_back(new SettingsMigration("Settings & Initial setup")); 00073 migrations.push_back(new ConfigurationsMigration("Configurations")); 00074 migrations.push_back(new SourcesMigration("Audio sources")); 00075 migrations.push_back(new AudioTracksMigration("Audio tracks & Queue")); 00076 migrations.push_back(new PlaylistsMigration("Playlists")); 00077 migrations.push_back(new SchedulerMigration("Scheduler")); 00078 } 00079 00080 MigrationEngine::~MigrationEngine() 00081 { 00082 while (!migrations.empty()) 00083 { 00084 delete migrations.back(); 00085 migrations.pop_back(); 00086 } 00087 } 00088 00089 int MigrationEngine::migrationsCount() 00090 { 00091 return (migrations.size()); 00092 } 00093 00094 00095 bool MigrationEngine::migrate() 00096 { 00097 return migrate(migrationsCount()); 00098 } 00099 00100 bool MigrationEngine::undo() 00101 { 00102 return migrate(0); 00103 } 00104 00105 bool MigrationEngine::migrate(int to) 00106 { 00107 return migrate(db.currentMigration(), to); 00108 } 00109 00110 bool MigrationEngine::migrate(int from, int to) 00111 { 00112 int i; 00113 int step = (from > to ? -1 : 1); 00114 00115 if (from < 0 || from > migrationsCount()) 00116 throw_exception(0x02, QObject::tr("Initial migration outside bounds")); 00117 if (to < 0 || to > migrationsCount()) 00118 throw_exception(0x03, QObject::tr("Destination migration outside bounds")); 00119 00120 // from = 4; to = 8; => 4..5..6..7..8 00121 for (i = from; i != to; i += step) 00122 { 00123 int newMig = i + step; 00124 Migration* mig = migrations.at(i + (step - 1)/2); 00125 // run up if step > 0, down otherwise 00126 if (!mig->run(step > 0)) 00127 break; 00128 if (newMig > 0) 00129 db.setSetting("migration", QVariant(newMig)); 00130 } 00131 if (i != to) 00132 qDebug() << "DB::MigrationEngine" << abs(to - i) << "later migrations cancelled"; 00133 else 00134 qDebug() << "DB::MigrationEngine" << abs(to - from) << "migrations run successfully."; 00135 return (i >= migrationsCount()); 00136 }