825cd44a3677e43a778a9e9a08d7e94d0e151403
[emufront] / src / db / dbcreator.cpp
1 // EmuFront
2 // Copyright 2010 Mikko Keinänen
3 //
4 // This file is part of EmuFront.
5 //
6 //
7 // EmuFront is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2 as published by
9 // the Free Software Foundation and appearing in the file gpl.txt included in the
10 // packaging of this file.
11 //
12 // EmuFront is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
19
20 #include <QObject>
21 #include <QSqlDatabase>
22 #include <QSqlQuery>
23 #include <QSqlError>
24 #include <QDebug>
25 #include <exception>
26 #include "dbcreator.h"
27
28 using namespace std;
29
30 const int DbCreator::TABLES_COUNT = 3;
31 const QString DbCreator::TABLES[] = {"platform", "mediatype", "filepath", "mediaimagecontainer", "mediaimage", "mediaimagecontainer_mediaimage"};
32
33 DbCreator::DbCreator(QObject *parent) : QObject(parent)
34 {
35 }
36
37
38 bool DbCreator::createDB()
39 {
40     bool ret = false;
41     QSqlQuery query;
42
43     try
44     {
45         query.exec("DROP TABLE IF EXISTS mediaimagecontainer_file");
46         query.exec("DROP TABLE IF EXISTS mediaimagecontainer");
47         query.exec("DROP TABLE IF EXISTS filepath");
48         query.exec("DROP TABLE IF EXISTS setup");
49         query.exec("DROP TABLE IF EXISTS mediatype");
50         query.exec("DROP TABLE IF EXISTS platform");
51         query.exec("DROP TABLE IF EXISTS file");
52         query.exec("DROP TABLE IF EXISTS executable");
53
54         qDebug() << "Creating TABLE file";
55
56         ret = query.exec("CREATE TABLE IF NOT EXISTS file"
57                         "(id INTEGER PRIMARY KEY, "
58                         "name TEXT, "   // TODO: optional here! -> mediaimagecontainer has filepath spesific name and media image has mediaimagecontainer specific name
59                                         // so no name here for those file types
60                         "type INTEGER, "
61                         "checksum TEXT, "
62                         "size INTEGER, "
63                         "updatetime NUMERIC)");
64
65         if (!ret) throw QString("tbl file");
66
67         qDebug() << "Creating TABLE platform";
68
69         ret = query.exec("CREATE TABLE IF NOT EXISTS platform "
70                          "(id INTEGER PRIMARY KEY, "
71                          "name TEXT, "
72                          "fileid INTEGER REFERENCES file(id))");
73
74         if (!ret) throw QString("tbl platform");
75
76         qDebug() << "Creating TABLE mediatype ";
77
78         ret = query.exec("CREATE TABLE IF NOT EXISTS mediatype "
79                          "(id INTEGER PRIMARY KEY, "
80                          "name TEXT, "
81                          "fileid INTEGER REFERENCES file(id))");
82
83         if (!ret) throw QString("tbl mediatype");
84
85         qDebug() << "Creating TABLE setup";
86
87         ret = query.exec("CREATE TABLE IF NOT EXISTS setup "
88                         "(id INTEGER PRIMARY KEY, "
89                         "platformid INTEGER REFERENCES platform(id) ON DELETE CASCADE, "
90                         "mediatypeid INTEGER REFERENCES mediatype(id) ON DELETE CASCADE, "
91                         "filetypeextensions TEXT)");
92
93         if (!ret) throw QString("tbl setup");
94
95         qDebug() << "Creating table executable";
96
97         ret = query.exec("CREATE TABLE IF NOT EXISTS executable "
98                         "(id INTEGER PRIMARY KEY, "
99                         "name TEXT, "
100                         "executable TEXT, "
101                         "options TEXT, "
102                         "type INTEGER, "
103                         "setupid INTEGER REFERENCES setup(id))");
104
105         if (!ret) throw QString("tbl executable");
106
107         qDebug() << "Creating TABLE filepath";
108
109         ret = query.exec("CREATE TABLE IF NOT EXISTS filepath "
110                          "(id INTEGER PRIMARY KEY, "
111                          "name TEXT, "
112                          "filetypeid INTEGER, "
113                          "setupid INTEGER, "
114                          "lastscanned NUMERIC, "
115                          "FOREIGN KEY (setupid) REFERENCES setup(id))");
116
117         if (!ret) throw QString("tbl filepath");
118
119         qDebug() << "Creating TABLE mediaimagecontainer";
120
121         ret = query.exec("CREATE TABLE IF NOT EXISTS mediaimagecontainer " // mediaimagecontainer_filepath
122                         "(fileid INTEGER REFERENCES file(id), "
123                         "filepathid INTEGER REFERENCES filepath(id), "
124                         // TODO: mediaimagecontainername -> filepath specific name for media image container!
125                         "updatetime NUMERIC)");
126
127         if (!ret) throw QString("tbl mediaimagecontainer");
128
129
130         qDebug() << "Creating TABLE mediaimagecontainer_mediaimage";
131
132         ret = query.exec("CREATE TABLE IF NOT EXISTS mediaimagecontainer_mediaimage "
133                         "(mediaimagecontainerid INTEGER REFERENCES file(id), "
134                         // TODO: mediaimagename -> mediaimagecontainer specific name for media image!
135                         "mediaimageid INTEGER REFERENCES file(id))");
136
137         if (!ret) throw QString("tbl mediaimagecontainer_mediaimage");
138
139         query.exec(
140             "CREATE TRIGGER IF NOT EXISTS trg_onplatformdelete "
141             "AFTER DELETE ON platform "
142             "BEGIN "
143             "   DELETE FROM setup WHERE setup.platformid = old.id;"
144             "END;"
145             );
146
147         if (!ret) throw QString("trg_onplatformdelete");
148
149         query.exec(
150             "CREATE TRIGGER IF NOT EXISTS trg_onmediatypedelete "
151             "AFTER DELETE ON mediatype "
152             "BEGIN "
153             "   DELETE FROM setup WHERE setup.mediatypeid = old.id;"
154             "END;"
155             );
156
157         if (!ret) throw QString("trg_onmediatypedelete");
158
159         query.exec(
160             "CREATE TRIGGER IF NOT EXISTS trg_onsetupdelete "
161             "AFTER DELETE ON setup "
162             "BEGIN "
163             "   DELETE FROM filepath WHERE filepath.setupid = old.id; "
164             "   DELETE FROM executable WHERE executable.setupid = old.id; "
165             "END;"
166             );
167
168         if (!ret) throw QString("trg_onsetupdelete");
169
170         query.exec(
171             "CREATE TRIGGER IF NOT EXISTS trg_onfilepathdelete "
172             "AFTER DELETE ON filepath "
173             "BEGIN "
174             "   DELETE FROM mediaimagecontainer WHERE mediaimagecontainer.filepathid=old.id; "
175             "END;"
176         );
177
178         if (!ret) throw QString("trg_onfilepathdelete");
179
180         query.exec(
181             "CREATE TRIGGER IF NOT EXISTS trg_onmediaimagecontainerdelete "
182             "AFTER DELETE ON mediaimagecontainer "
183             "BEGIN "
184             "   DELETE FROM mediaimagecontainer_mediaimage WHERE mediaimagecontainer_mediaimage.mediaimagecontainerid=old.fileid;"
185             "END;"
186         );
187
188         if (!ret) throw QString("trg_onmediaimagecontainerdelete");
189
190         query.exec(
191             "CREATE TRIGGER IF NOT EXISTS trg_onmediaimagecontainer_mediaimagedelete "
192             "AFTER DELETE ON mediaimagecontainer_mediaimage "
193             "BEGIN "
194             "    DELETE FROM file WHERE file.id=old.mediaimageid; "
195             "    DELETE FROM file WHERE file.id=old.mediaimagecontainerid; "
196             "END;"
197         );
198         if (!ret) throw QString("trg_onmediaimagecontainer_mediaimagedelete");
199
200     }
201     catch (QString tbl)
202     {
203         QString err = query.lastError().text();
204         throw QString("Couldn't CREATE '%1'!").arg(tbl).append(err);
205     }
206     return ret;
207 }
208
209 /**
210  * Check if database already exists.
211  * Returns false if doesn't or we don't have a connection.
212 */
213 bool DbCreator::dbExists()
214 {
215     for (int i = 0; i < TABLES_COUNT; ++i)
216     {
217         if (!tableExists(TABLES[i]))
218         {
219             qDebug() << "Table " << TABLES[i] << " missing.";
220             return false;
221         }
222        qDebug() << "Table " << TABLES[i] << " exists.";
223     }
224     return true;
225 }
226
227 bool DbCreator::tableExists(QString TABLE)
228 {
229     QSqlQuery query;
230     query.exec(QString("SELECT name FROM sqlite_master WHERE name='%1'").arg(TABLE));
231     return query.next();
232 }
233
234 bool DbCreator::deleteDB()
235 {
236     // return QFile::remove(getDbPath());
237     return false;
238 }