Media image container scanning has now a buffer. Scanned media image
[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, "
59                         "type INTEGER, "
60                         "checksum TEXT, "
61                         "size INTEGER, "
62                         "updatetime NUMERIC)");
63
64         qDebug() << "Creating TABLE platform";
65
66         ret = query.exec("CREATE TABLE IF NOT EXISTS platform "
67                          "(id INTEGER PRIMARY KEY, "
68                          "name TEXT, "
69                          "fileid INTEGER REFERENCES file(id))");
70
71         if (!ret) throw QString("platform.");
72
73         qDebug() << "Creating TABLE mediatype ";
74
75         ret = query.exec("CREATE TABLE IF NOT EXISTS mediatype "
76                          "(id INTEGER PRIMARY KEY, "
77                          "name TEXT, "
78                          "fileid INTEGER REFERENCES file(id))");
79
80         if (!ret) throw QString("mediatype.");
81
82         qDebug() << "Creating TABLE setup";
83
84         ret = query.exec("CREATE TABLE IF NOT EXISTS setup "
85                         "(id INTEGER PRIMARY KEY, "
86                         "platformid INTEGER REFERENCES platform(id) ON DELETE CASCADE, "
87                         "mediatypeid INTEGER REFERENCES mediatype(id) ON DELETE CASCADE, "
88                         "filetypeextensions TEXT)");
89
90         qDebug() << "Creating table executable";
91
92         ret = query.exec("CREATE TABLE IF NOT EXISTS executable "
93                         "(id INTEGER PRIMARY KEY, "
94                         "name TEXT, "
95                         "executable TEXT, "
96                         "options TEXT, "
97                         "type INTEGER, "
98                         "setupid INTEGER REFERENCES setup(id))");
99
100         /*qDebug() << "Creating TABLE filetype";
101             ret = query.exec("CREATE TABLE filetype IF NOT EXISTS"
102                              "(id INTEGER PRIMARY KEY, "
103                              "name TEXT)");
104             if (!ret) throw QString("filetype.");
105             query.exec("insert into filetype (id, name) values (1, 'media image container')");
106             query.exec("insert into filetype (id, name) values (2, 'screenshot')");
107             query.exec("insert into filetype (id, name) values (3, 'platform icon')");
108             query.exec("insert into filetype (id, name) values (4, 'media type icon')");*/
109
110         qDebug() << "Creating TABLE filepath";
111
112         ret = query.exec("CREATE TABLE IF NOT EXISTS filepath "
113                          "(id INTEGER PRIMARY KEY, "
114                          "name TEXT, "
115                          "filetypeid INTEGER, "
116                          "setupid INTEGER, "
117                          "lastscanned NUMERIC, "
118                          "FOREIGN KEY (setupid) REFERENCES setup(id))");
119
120         if (!ret) throw QString("filepath");
121
122         qDebug() << "Creating TABLE mediaimagecontainer";
123
124         ret = query.exec("CREATE TABLE IF NOT EXISTS mediaimagecontainer "
125                         "(fileid INTEGER REFERENCES file(id), "
126                         "filepathid INTEGER REFERENCES filepath(id), "
127                         "updatetime NUMERIC)");
128
129         if (!ret) throw QString("mediaimagecontainer");
130
131
132         qDebug() << "Creating TABLE mediaimagecontainer_mediaimage";
133
134         ret = query.exec("CREATE TABLE IF NOT EXISTS mediaimagecontainer_mediaimage "
135                         "(mediaimagecontainerid INTEGER REFERENCES file(id), "
136                         "mediaimageid INTEGER REFERENCES file(id))");
137
138         if (!ret) throw QString("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         query.exec(
149             "CREATE TRIGGER IF NOT EXISTS trg_onmediatypedelete "
150             "AFTER DELETE ON mediatype "
151             "BEGIN "
152             "   DELETE FROM setup WHERE setup.mediatypeid = old.id;"
153             "END;"
154             );
155
156         query.exec(
157             "CREATE TRIGGER IF NOT EXISTS trg_onsetupdelete "
158             "AFTER DELETE ON setup "
159             "BEGIN "
160             "   DELETE FROM filepath WHERE filepath.setupid = old.id; "
161             "   DELETE FROM executable WHERE executable.setupid = old.id; "
162             "END;"
163             );
164
165         query.exec(
166             "CREATE TRIGGER IF NOT EXISTS trg_onfilepathdelete "
167             "AFTER DELETE ON filepath "
168             "BEGIN "
169             "   DELETE FROM mediaimagecontainer WHERE filepathid=old.id; "
170             "END;"
171         );
172
173         // NOTE:
174         // media image container is not explicitily deleted,
175         // mediaimagecontainer entry should be deleted implicitely with
176         // file tables trigger!
177         /*query.exec(
178             "CREATE TRIGGER IF NOT EXISTS trg_onmediaimagecontainerdelete "
179             "AFTER DELETE ON mediaimagecontainer "
180             "BEGIN "
181             "    DELETE FROM file WHERE id=old.fileid; "
182             "    DELETE FROM mediaimagecontainer_mediaimage WHERE mediaimagecontainerid=old.fileid; "
183             "END;"
184         );*/
185
186         /* NOTE: Entries from mediaimagecontainer_mediaimage are not explicitily deleted, they
187             are deleted implicitely using file tables trigger. */
188         /*query.exec(
189             "CREATE TRIGGER IF NOT EXISTS trg_onmediaimagecontainer_mediaimagedelete "
190             "AFTER DELETE ON mediaimagecontainer_mediaimage "
191             "BEGIN "
192             "    DELETE FROM file WHERE id=old.mediaimageid; "
193             "    DELETE FROM mediaimagecontainer WHERE fileid=old.mediaimagecontainerid; "
194         );*/
195
196         query.exec(
197             "CREATE TRIGGER IF NOT EXISTS trg_onfiledelete "
198             "AFTER DELETE ON file "
199             "BEGIN "
200             "   UPDATE platform SET platform.fileid=NULL WHERE platform.fileid = old.id;."
201             "   UPDATE mediatype SET mediatype.fileid=NULL WHERE mediatype.fileid = old.id;"
202             "   DELETE FROM mediaimagecontainer WHERE fileid = old.id;"
203             "   DELETE FROM mediaimagecontainer_mediaimage WHERE mediaimagecontainer_mediaimage.mediaimageid = old.id;"
204             "   DELETE FROM mediaimagecontainer_mediaimage WHERE mediaimagecontainer_mediaimage.mediaimagecontainerid = old.id;"
205             "END;"
206         );
207     }
208     catch (QString tbl)
209     {
210         QString err = query.lastError().text();
211         throw QString("Couldn't CREATE table '%1'!").arg(tbl).append(err);
212     }
213     return ret;
214 }
215
216 /**
217  * Check if database already exists.
218  * Returns false if doesn't or we don't have a connection.
219 */
220 bool DbCreator::dbExists()
221 {
222     for (int i = 0; i < TABLES_COUNT; ++i)
223     {
224         if (!tableExists(TABLES[i]))
225         {
226             qDebug() << "Table " << TABLES[i] << " missing.";
227             return false;
228         }
229        qDebug() << "Table " << TABLES[i] << " exists.";
230     }
231     return true;
232 }
233
234 bool DbCreator::tableExists(QString TABLE)
235 {
236     QSqlQuery query;
237     query.exec(QString("SELECT name FROM sqlite_master WHERE name='%1'").arg(TABLE));
238     return query.next();
239 }
240
241 bool DbCreator::deleteDB()
242 {
243     // return QFile::remove(getDbPath());
244     return false;
245 }