2011-02-13 19:30:12 +01:00
/*
Copyright 2011 Grégory Soutadé
This file is part of KissCount .
KissCount is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
KissCount is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with KissCount . If not , see < http : //www.gnu.org/licenses/>.
*/
2011-08-27 18:35:36 +02:00
# include <iostream>
# include <QString>
# include <QMessageBox>
# include <QSqlQuery>
# include <QSqlError>
# include <QVariant>
# include <QSqlRecord>
2011-08-20 14:02:47 +02:00
# include "Database.hpp"
2011-02-13 19:30:12 +01:00
2011-08-27 18:35:36 +02:00
# define ON_ERROR(m) \
QMessageBox : : critical ( 0 , _ ( " Error " ) , m ) ; \
throw m ;
2011-02-13 19:30:12 +01:00
2011-08-27 18:35:36 +02:00
typedef void ( * update_func ) ( QSqlDatabase & _db ) ;
2011-02-13 19:30:12 +01:00
# define UPDATE_TABLE(from, to, step) EXECUTE_SQL_UPDATE_WITH_CODE(req, , throw std::string("Error while upgrading from version " from " to version " to ", step " step);, });
2011-08-27 18:35:36 +02:00
static void Version_1_to_2 ( QSqlDatabase & _db )
2011-02-13 19:30:12 +01:00
{
2011-08-27 18:35:36 +02:00
QString req ;
2011-02-13 19:30:12 +01:00
/* Category */
2011-08-27 18:35:36 +02:00
req = " ALTER TABLE category ADD fix_cost CHAR(1) " ;
2011-02-13 19:30:12 +01:00
UPDATE_TABLE ( " 1 " , " 2 " , " 1 " ) ;
2011-08-27 18:35:36 +02:00
req = " UPDATE category SET fix_cost='0' " ;
2011-02-13 19:30:12 +01:00
UPDATE_TABLE ( " 1 " , " 2 " , " 2 " ) ;
2011-08-27 18:35:36 +02:00
req = " UPDATE category SET fix_cost='1' WHERE id IN ( " ;
req + = " SELECT MIN(category.id) FROM category, user WHERE category.user = user.id " ;
req + = " ) " ;
2011-02-13 19:30:12 +01:00
UPDATE_TABLE ( " 1 " , " 2 " , " 3 " ) ;
/* Account */
2011-08-27 18:35:36 +02:00
req = " ALTER TABLE account ADD virtual CHAR(1) " ;
2011-02-13 19:30:12 +01:00
UPDATE_TABLE ( " 1 " , " 2 " , " 4 " ) ;
2011-08-27 18:35:36 +02:00
req = " UPDATE account SET virtual='0' " ;
2011-02-13 19:30:12 +01:00
UPDATE_TABLE ( " 1 " , " 2 " , " 5 " ) ;
2011-02-14 20:56:59 +01:00
/* Operation */
2011-08-27 18:35:36 +02:00
req = " ALTER TABLE operation ADD virtual CHAR(1) " ;
2011-02-14 20:56:59 +01:00
UPDATE_TABLE ( " 1 " , " 2 " , " 6 " ) ;
2011-08-27 18:35:36 +02:00
req = " UPDATE operation SET virtual='0' " ;
2011-02-14 20:56:59 +01:00
UPDATE_TABLE ( " 1 " , " 2 " , " 7 " ) ;
2011-03-23 20:35:29 +01:00
/* Import Pattern */
2011-08-27 18:35:36 +02:00
req = " CREATE TABLE import_pattern(id INTEGER PRIMARY KEY, user REFERENCES user(id), description VARCHAR(255), pattern VARCHAR(255), account REFERENCES account(id), category REFERENCES category(id)) " ;
2011-03-23 20:35:29 +01:00
UPDATE_TABLE ( " 1 " , " 2 " , " 8 " ) ;
2011-02-13 19:30:12 +01:00
}
2012-02-01 12:43:43 +01:00
static void Version_2_to_3 ( QSqlDatabase & _db )
{
QString req ;
/* Account */
req = " ALTER TABLE account ADD hidden CHAR(1) " ;
UPDATE_TABLE ( " 2 " , " 3 " , " 1 " ) ;
req = " UPDATE account SET hidden='0' " ;
UPDATE_TABLE ( " 2 " , " 3 " , " 2 " ) ;
}
2011-02-13 19:30:12 +01:00
static update_func updates [ ] = {
2012-02-01 12:43:43 +01:00
Version_1_to_2 ,
Version_2_to_3
2011-02-13 19:30:12 +01:00
} ;
void Database : : CheckDatabaseVersion ( )
{
2011-08-27 18:35:36 +02:00
QString req ;
QSqlRecord set ;
QSqlQuery query ( _db ) ;
2011-02-13 19:30:12 +01:00
long int version ;
int i ;
2011-08-27 18:35:36 +02:00
req = " SELECT db_version FROM kisscount " ;
EXECUTE_SQL_QUERY_WITH_CODE ( req , , ON_ERROR ( " Unable to get database version " ) , { } ) ;
2011-02-13 19:30:12 +01:00
2011-08-27 18:35:36 +02:00
query . next ( ) ;
set = query . record ( ) ;
2011-02-13 19:30:12 +01:00
2011-08-27 18:35:36 +02:00
if ( ! ( version = set . value ( " db_version " ) . toInt ( ) ) )
2011-02-13 19:30:12 +01:00
{
ON_ERROR ( " Invalid database version " ) ;
}
2011-08-16 18:22:35 +02:00
if ( version = = Database : : VERSION ) return ;
2011-02-13 19:30:12 +01:00
2011-08-16 18:22:35 +02:00
if ( version > Database : : VERSION )
2011-02-13 19:30:12 +01:00
{
ON_ERROR ( " Your current version of KissCount is too old and can't load this database. Please upgrade KissCount " ) ;
}
version - - ;
// Maybe one update is impossible
2011-08-16 18:22:35 +02:00
for ( i = version ; i < Database : : VERSION - 1 ; i + + )
2011-02-13 19:30:12 +01:00
{
if ( ! updates [ i ] )
{
ON_ERROR ( " The database cannot be upgraded. Please use an older version of KissCount " ) ;
}
}
2011-08-27 18:35:36 +02:00
if ( QMessageBox : : question ( 0 , " KissCount " , " You use an old database model. KissCount will try to upgrade it to the lastest version " )
= = QMessageBox : : No )
2011-02-13 19:30:12 +01:00
throw std : : string ( " can't load this database " ) ;
2011-08-27 18:35:36 +02:00
_db . transaction ( ) ;
2011-02-13 19:30:12 +01:00
try
{
2011-08-16 18:22:35 +02:00
for ( i = version ; i < Database : : VERSION - 1 ; i + + )
2011-02-13 19:30:12 +01:00
{
updates [ i ] ( _db ) ;
}
2011-08-27 18:35:36 +02:00
req = " UPDATE kisscount SET db_version=' " + QString : : number ( Database : : VERSION ) + " ' " ;
2011-02-13 19:30:12 +01:00
EXECUTE_SQL_UPDATE_WITH_CODE ( req , , throw std : : string ( " Unable to set new database version " ) , { } ) ;
}
catch ( std : : string e )
{
std : : cout < < e < < std : : endl ;
2011-08-27 18:35:36 +02:00
_db . rollback ( ) ;
2011-02-13 19:30:12 +01:00
throw e ;
}
2011-08-27 18:35:36 +02:00
_db . commit ( ) ;
2011-02-13 19:30:12 +01:00
2011-08-27 18:35:36 +02:00
QMessageBox : : information ( 0 , " KissCount " , " Database upgrade successful ! " ) ;
2011-02-13 19:30:12 +01:00
}