defuze.me  Client
migration.cpp
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 }