Modified the license text comment type.
[emufront] / src / db / dbcreator.cpp
1 /*
2 ** EmuFront
3 ** Copyright 2010 Mikko Keinänen
4 **
5 ** This file is part of EmuFront.
6 **
7 **
8 ** EmuFront is free software: you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License version 2 as published by
10 ** the Free Software Foundation and appearing in the file gpl.txt included in the
11 ** packaging of this file.
12 **
13 ** EmuFront is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
20 */
21 #include <QObject>
22 #include <QDir>
23 #include <QSqlDatabase>
24 #include <QSqlQuery>
25 #include <QSqlRecord>
26 #include <QSqlTableModel>
27 #include <QSqlError>
28 #include <QDebug>
29 #include <exception>
30 #include "dbcreator.h"
31 #include "emufrontexception.h"
32
33 using namespace std;
34
35 const int DbCreator::DB_VERSION = 1;
36 //const int DbCreator::TABLES_COUNT = 3;
37 //const QString DbCreator::TABLES[] = {"platform", "mediatype", "filepath", "mediaimagecontainer_filepath", "mediaimage", "mediaimagecontainer_mediaimage"};
38
39 DbCreator::DbCreator(QObject *parent) : QObject(parent)
40 {
41 }
42
43
44 bool DbCreator::createDB()
45 {
46     bool ret = false;
47     QSqlQuery query;
48
49     try
50     {
51
52         /*
53
54             N O T I C E
55             -----------
56
57             When adding a new table, remember to add a drop table
58             clause also!
59
60             When changing the database structure, increase
61             also the version number and create a sql command
62             for updating from last version to new version.
63
64             Update those version upgrade "patches" here as a version history:
65             -----------------------------------------------------------------
66
67         */
68
69         query.exec("DROP TABLE IF EXISTS mediaimagecontainer_mediaimage");
70         query.exec("DROP TABLE IF EXISTS mediaimagecontainer_filepath");
71         query.exec("DROP TABLE IF EXISTS filepath");
72         query.exec("DROP TABLE IF EXISTS setup");
73         query.exec("DROP TABLE IF EXISTS mediatype");
74         query.exec("DROP TABLE IF EXISTS platform");
75         query.exec("DROP TABLE IF EXISTS file") ;
76         query.exec("DROP TABLE IF EXISTS executable");
77         query.exec("DROP TABLE IF EXISTS config");
78
79         qDebug() << "Creating TABLE file";
80
81         ret = query.exec("CREATE TABLE IF NOT EXISTS config"
82                 "(tmpdirpath TEXT, "
83                 "dbversion INTEGER)"
84             );
85
86         if (ret) {
87             query.prepare("INSERT INTO config "
88                 "(tmpdirpath, dbversion) "
89                 "VALUES (:tmpdir, :dbversion)");
90             query.bindValue(":tmpdir", QDir::homePath());
91             query.bindValue(":dbversion", DbCreator::DB_VERSION);
92             ret = query.exec();
93         }
94
95         if (!ret) throw QString("tbl config");
96
97         ret = query.exec("CREATE TABLE IF NOT EXISTS file"
98                         "(id INTEGER PRIMARY KEY, "
99                         "name TEXT, "
100                         "type INTEGER, "
101                         "checksum TEXT, "
102                         "size INTEGER, "
103                         "updatetime NUMERIC, "
104                         "extname TEXT)");
105
106         if (!ret) throw QString("tbl file");
107
108         qDebug() << "Creating TABLE platform";
109
110         ret = query.exec("CREATE TABLE IF NOT EXISTS platform "
111                          "(id INTEGER PRIMARY KEY, "
112                          "name TEXT, "
113                          "fileid INTEGER REFERENCES file(id))");
114
115         if (!ret) throw QString("tbl platform");
116
117         qDebug() << "Creating TABLE mediatype ";
118
119         ret = query.exec("CREATE TABLE IF NOT EXISTS mediatype "
120                          "(id INTEGER PRIMARY KEY, "
121                          "name TEXT, "
122                          "fileid INTEGER REFERENCES file(id))");
123
124         if (!ret) throw QString("tbl mediatype");
125
126         qDebug() << "Creating TABLE setup";
127
128         ret = query.exec("CREATE TABLE IF NOT EXISTS setup "
129                         "(id INTEGER PRIMARY KEY, "
130                         "platformid INTEGER REFERENCES platform(id) ON DELETE CASCADE, "
131                         "mediatypeid INTEGER REFERENCES mediatype(id) ON DELETE CASCADE, "
132                         "filetypeextensions TEXT)");
133
134         if (!ret) throw QString("tbl setup");
135
136         qDebug() << "Creating table executable";
137
138         ret = query.exec("CREATE TABLE IF NOT EXISTS executable "
139                         "(id INTEGER PRIMARY KEY, "
140                         "name TEXT, "
141                         "executable TEXT, "
142                         "options TEXT, "
143                         "type INTEGER, "
144                         "setupid INTEGER REFERENCES setup(id))");
145
146         if (!ret) throw QString("tbl executable");
147
148         qDebug() << "Creating TABLE filepath";
149
150         ret = query.exec("CREATE TABLE IF NOT EXISTS filepath "
151                          "(id INTEGER PRIMARY KEY, "
152                          "name TEXT, "
153                          "filetypeid INTEGER, "
154                          "setupid INTEGER, "
155                          "lastscanned NUMERIC, "
156                          "FOREIGN KEY (setupid) REFERENCES setup(id))");
157
158         if (!ret) throw QString("tbl filepath");
159
160         qDebug() << "Creating TABLE mediaimagecontainer_filepath";
161
162         ret = query.exec("CREATE TABLE IF NOT EXISTS mediaimagecontainer_filepath "
163                         "(fileid INTEGER REFERENCES file(id), "
164                         "filepathid INTEGER REFERENCES filepath(id), "
165                         "updatetime NUMERIC)");
166
167         if (!ret) throw QString("tbl mediaimagecontainer_filepath");
168
169
170         qDebug() << "Creating TABLE mediaimagecontainer_mediaimage";
171
172         ret = query.exec("CREATE TABLE IF NOT EXISTS mediaimagecontainer_mediaimage "
173                         "(mediaimagecontainerid INTEGER REFERENCES file(id), "
174                         "mediaimageid INTEGER REFERENCES file(id))");
175
176         if (!ret) throw QString("tbl mediaimagecontainer_mediaimage");
177
178         query.exec(
179             "CREATE TRIGGER IF NOT EXISTS trg_onplatformdelete "
180             "AFTER DELETE ON platform "
181             "BEGIN "
182             "   DELETE FROM setup WHERE setup.platformid = old.id;"
183             "END;"
184             );
185
186         if (!ret) throw QString("trg_onplatformdelete");
187
188         query.exec(
189             "CREATE TRIGGER IF NOT EXISTS trg_onmediatypedelete "
190             "AFTER DELETE ON mediatype "
191             "BEGIN "
192             "   DELETE FROM setup WHERE setup.mediatypeid = old.id;"
193             "END;"
194             );
195
196         if (!ret) throw QString("trg_onmediatypedelete");
197
198         query.exec(
199             "CREATE TRIGGER IF NOT EXISTS trg_onsetupdelete "
200             "AFTER DELETE ON setup "
201             "BEGIN "
202             "   DELETE FROM filepath WHERE filepath.setupid = old.id; "
203             "   DELETE FROM executable WHERE executable.setupid = old.id; "
204             "END;"
205             );
206
207         if (!ret) throw QString("trg_onsetupdelete");
208
209         query.exec(
210             "CREATE TRIGGER IF NOT EXISTS trg_onfilepathdelete "
211             "AFTER DELETE ON filepath "
212             "BEGIN "
213             "   DELETE FROM mediaimagecontainer_filepath WHERE mediaimagecontainer_filepath.filepathid=old.id; "
214             "END;"
215         );
216
217         if (!ret) throw QString("trg_onfilepathdelete");
218
219         query.exec(
220             "CREATE TRIGGER IF NOT EXISTS trg_onmediaimagecontainerdelete "
221             "AFTER DELETE ON mediaimagecontainer_filepath "
222             "BEGIN "
223             "   DELETE FROM mediaimagecontainer_mediaimage WHERE mediaimagecontainer_mediaimage.mediaimagecontainerid=old.fileid;"
224             "END;"
225         );
226
227         if (!ret) throw QString("trg_onmediaimagecontainerdelete");
228
229         query.exec(
230             "CREATE TRIGGER IF NOT EXISTS trg_onmediaimagecontainer_mediaimagedelete "
231             "AFTER DELETE ON mediaimagecontainer_mediaimage "
232             "BEGIN "
233             "    DELETE FROM file WHERE file.id=old.mediaimageid; "
234             "    DELETE FROM file WHERE file.id=old.mediaimagecontainerid; "
235             "END;"
236         );
237         if (!ret) throw QString("trg_onmediaimagecontainer_mediaimagedelete");
238
239     }
240     catch (QString tbl)
241     {
242         QString err = query.lastError().text();
243         throw EmuFrontException(QString("Couldn't CREATE '%1'!").arg(tbl).append(err));
244     }
245     return ret;
246 }
247
248 /**
249  * Check if database already exists.
250  *
251  * Returns  0 if database doesn't exist
252  *          or database version number 1 if database exists
253  *
254 */
255 int DbCreator::dbExists()
256 {
257     int ret = 0;
258     QString sql("SELECT dbversion FROM config");
259     QSqlQuery q;
260     q.exec(sql);
261     if (q.next()) {
262         ret = q.value(0).toInt();
263         qDebug() << "Database version is " << ret
264             << " the application requires " << DB_VERSION;
265     }
266     return ret;
267     /*for (int i = 0; i < TABLES_COUNT; ++i)
268     {
269         if (!tableExists(TABLES[i]))
270         {
271             qDebug() << "Table " << TABLES[i] << " missing.";
272             return false;
273         }
274        qDebug() << "Table " << TABLES[i] << " exists.";
275     }
276     return true;*/
277 }
278
279 bool DbCreator::tableExists(QString TABLE)
280 {
281     QSqlQuery query;
282     query.exec(QString("SELECT name FROM sqlite_master WHERE name='%1'").arg(TABLE));
283     return query.next();
284 }
285
286 bool DbCreator::deleteDB()
287 {
288     // return QFile::remove(getDbPath());
289     return false;
290 }