Removed two triggers that couldn't be used after enabling multiple
[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_filepath", "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_mediaimage");
46         query.exec("DROP TABLE IF EXISTS mediaimagecontainer_filepath");
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_filepath";
120
121         ret = query.exec("CREATE TABLE IF NOT EXISTS mediaimagecontainer_filepath "
122                         "(fileid INTEGER REFERENCES file(id), "
123                         "filepathid INTEGER REFERENCES filepath(id), "
124                         "mediaimagecontainername TEXT, " // filepath specific name for media image container
125                         "updatetime NUMERIC)");
126
127         if (!ret) throw QString("tbl mediaimagecontainer_filepath");
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                         "mediaimageid INTEGER REFERENCES file(id), "
135                         "mediaimagename TEXT " // mediaimagecontainer specific name for media image
136                         ")");
137
138         if (!ret) throw QString("tbl mediaimagecontainer_mediaimage");
139
140         query.exec(
141             "CREATE TRIGGER IF NOT EXISTS trg_onplatformdelete "
142             "AFTER DELETE ON platform "
143             "BEGIN "
144             "   DELETE FROM setup WHERE setup.platformid = old.id;"
145             "END;"
146             );
147
148         if (!ret) throw QString("trg_onplatformdelete");
149
150         query.exec(
151             "CREATE TRIGGER IF NOT EXISTS trg_onmediatypedelete "
152             "AFTER DELETE ON mediatype "
153             "BEGIN "
154             "   DELETE FROM setup WHERE setup.mediatypeid = old.id;"
155             "END;"
156             );
157
158         if (!ret) throw QString("trg_onmediatypedelete");
159
160         query.exec(
161             "CREATE TRIGGER IF NOT EXISTS trg_onsetupdelete "
162             "AFTER DELETE ON setup "
163             "BEGIN "
164             "   DELETE FROM filepath WHERE filepath.setupid = old.id; "
165             "   DELETE FROM executable WHERE executable.setupid = old.id; "
166             "END;"
167             );
168
169         if (!ret) throw QString("trg_onsetupdelete");
170
171         query.exec(
172             "CREATE TRIGGER IF NOT EXISTS trg_onfilepathdelete "
173             "AFTER DELETE ON filepath "
174             "BEGIN "
175             "   DELETE FROM mediaimagecontainer_filepath WHERE mediaimagecontainer_filepath.filepathid=old.id; "
176             "END;"
177         );
178
179         if (!ret) throw QString("trg_onfilepathdelete");
180
181        // The following two triggers were removed after adding support for multiple instances of same media image container
182        // on different file paths or multiple instances of media images inside different media image containers.
183        // The trigger functionality must be done by removing the orphaned media images and media image containers
184        // after removing file paths or media image containers programmatically.
185
186         /* Cannot trigger this, media image container may reside also on another filepath, cannot remove the references with
187             media images
188         query.exec(
189             "CREATE TRIGGER IF NOT EXISTS trg_onmediaimagecontainerdelete "
190             "AFTER DELETE ON mediaimagecontainer_filepath "
191             "FOR EACH ROW WHEN
192             "BEGIN "
193             "   DELETE FROM mediaimagecontainer_mediaimage WHERE mediaimagecontainer_mediaimage.mediaimagecontainerid=old.fileid;"
194             "END;"
195         );
196
197         if (!ret) throw QString("trg_onmediaimagecontainerdelete");*/
198
199         /* Cannot trigger this, media image container may reside also on another filepath
200             or media image may be assigned with another media image container
201         query.exec(
202             "CREATE TRIGGER IF NOT EXISTS trg_onmediaimagecontainer_mediaimagedelete "
203             "AFTER DELETE ON mediaimagecontainer_mediaimage "
204             "BEGIN "
205             "    DELETE FROM file WHERE file.id=old.mediaimageid; "
206             "    DELETE FROM file WHERE file.id=old.mediaimagecontainerid; "
207             "END;"
208         );
209         if (!ret) throw QString("trg_onmediaimagecontainer_mediaimagedelete");*/
210
211     }
212     catch (QString tbl)
213     {
214         QString err = query.lastError().text();
215         throw QString("Couldn't CREATE '%1'!").arg(tbl).append(err);
216     }
217     return ret;
218 }
219
220 /**
221  * Check if database already exists.
222  * Returns false if doesn't or we don't have a connection.
223 */
224 bool DbCreator::dbExists()
225 {
226     for (int i = 0; i < TABLES_COUNT; ++i)
227     {
228         if (!tableExists(TABLES[i]))
229         {
230             qDebug() << "Table " << TABLES[i] << " missing.";
231             return false;
232         }
233        qDebug() << "Table " << TABLES[i] << " exists.";
234     }
235     return true;
236 }
237
238 bool DbCreator::tableExists(QString TABLE)
239 {
240     QSqlQuery query;
241     query.exec(QString("SELECT name FROM sqlite_master WHERE name='%1'").arg(TABLE));
242     return query.next();
243 }
244
245 bool DbCreator::deleteDB()
246 {
247     // return QFile::remove(getDbPath());
248     return false;
249 }