autosql.cpp 18.2 KB
Newer Older
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
1
#include <iostream>
2
#include <autosql.h>
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
3

Leon Do Castelo's avatar
Leon Do Castelo committed
4
5
std::unique_ptr<Database> Database::instance = nullptr;

Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
6
7
8
9
10
11
Database::Database(std::string path): db(QSqlDatabase::addDatabase("QSQLITE")) {
	db.setDatabaseName(path.c_str());
	if (!db.open()) {
		throw "Unable to open database";
	}

Leon Do Castelo's avatar
Leon Do Castelo committed
12
	db.exec("CREATE TABLE IF NOT EXISTS automates (nom VARCHAR(30) PRIMARY KEY, defaut INTEGER NOT NULL, description TEXT NOT NULL, auteur VARCHAR(30), annee DATE)");
13
14
15
16
17
18
19
20
21
22
23

	db.exec("CREATE TABLE IF NOT EXISTS regles_transition (id VARCHAR(30) NOT NULL, min1 INTEGER, min2 INTEGER, min3 INTEGER, min4 INTEGER, min5 INTEGER, min6 INTEGER, min7 INTEGER, min8 INTEGER, max1 INTEGER, max2 INTEGER, max3 INTEGER, max4 INTEGER, max5 INTEGER, max6 INTEGER, max7 INTEGER, max8 INTEGER, courant INTEGER, destination INTEGER NOT NULL, FOREIGN KEY('id') REFERENCES 'automates'('nom'))");

	db.exec("CREATE TABLE IF NOT EXISTS regles_voisinage (id VARCHAR(30) PRIMARY KEY, type INTEGER NOT NULL, rayon INTEGER, FOREIGN KEY('id') REFERENCES 'automates'('nom'))");

	db.exec("CREATE TABLE IF NOT EXISTS coord_voisinage (id VARCHAR(30) NOT NULL, x INTEGER NOT NULL, y INTEGER NOT NULL,FOREIGN KEY('id') REFERENCES 'automates'('nom'))");

	db.exec("CREATE TABLE IF NOT EXISTS reseaux (id INTEGER PRIMARY KEY, nom VARCHAR(30) NOT NULL, h INTEGER NOT NULL, 	l INTEGER NOT NULL, automate VARCHAR(30) NOT NULL, FOREIGN KEY('automate') REFERENCES 'automates'('nom'))");

    db.exec("CREATE TABLE IF NOT EXISTS EnsembleEtats (id INTEGER PRIMARY KEY, automate VARCHAR(30) NOT NULL, UNIQUE(automate), FOREIGN KEY('automate') REFERENCES 'automates'('nom'))");

24
    db.exec("CREATE TABLE IF NOT EXISTS Etats (ensemble INTEGER NOT NULL, indice INTEGER NOT NULL, label VARCHAR NOT NULL, r INTEGER NOT NULL, g INTEGER NOT NULL, b INTEGER NOT NULL, CHECK(indice>=0), CHECK(r>=0), CHECK(r<=255), CHECK(g>=0), CHECK(g<=255), CHECK(b>=0), CHECK(b<=255), PRIMARY KEY (ensemble, indice), FOREIGN KEY('ensemble') REFERENCES 'EnsembleEtats'('id'))");
25
26
27

    db.exec("CREATE TABLE IF NOT EXISTS Cellules (reseau INTEGER NOT NULL, ensemble INTEGER NOT NULL, etat INTEGER NOT NULL, x INTEGER NOT NULL, y INTEGER NOT NULL, FOREIGN KEY('reseau') REFERENCES 'reseaux'('id'))");

Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
28
29
30
31
32
33
34
35
36
37
38
39
40
41
}

std::vector<QString> Database::getAutomates() const {
	QSqlQuery query = db.exec("SELECT nom FROM automates");
	std::vector<QString> names;
	if(query.first()) {
		names.push_back(query.value("nom").toString());
	}
	while(query.next()) {
		names.push_back(query.value("nom").toString());
	}

	return names;
}
42

43
void Database::initEnsEtat(Automate& a) const {
44
45
46
	QSqlQuery query(db);

	query.prepare("SELECT indice, label, r, g, b FROM Etats INNER JOIN EnsembleEtats ON Etats.ensemble = EnsembleEtats.id WHERE automate = :nom");
47
	query.bindValue(":nom", a.getTitle().c_str());
48
49
50
	query.exec();

	if(!query.first())
51
		throw "Unable to select this object (ensemble)";
52

53
	EnsembleEtat& ens = a.getEnsemble();
54
	ens.reset();
55
56
57
58
59
60
61
62
63
64
65
66

	do {
		unsigned int ind = static_cast<unsigned int>(query.value("indice").toInt());
		int r = query.value("r").toInt();
		int g = query.value("g").toInt();
		int b = query.value("b").toInt();
		std::string label = query.value("label").toString().toStdString();

		ens.ajouterEtat(ind, label, r, g, b);
	} while(query.next());
}

67
68
69
/// Retourne la fonction de transition d'un automate par son nom
///
/// Une règle prend en compte l'état courant seulement s'il est défini à non nul dans la BDD
70
Fonction* Database::getFonction(Automate& a) const {
71
72
73
	QSqlQuery query(db);

	query.prepare("SELECT defaut FROM automates WHERE nom = :nom");
74
	query.bindValue(":nom", a.getTitle().c_str());
75
76
77
	query.exec();

	if(!query.first())
78
		throw "Unable to select this object (function)";
79

80
	Fonction* fonction = new Fonction(a.getEnsemble().getEtat(query.value("defaut").toInt()));
81
82

	query.prepare("SELECT * FROM regles_transition WHERE id = :id");
83
	query.bindValue(":id", a.getTitle().c_str());
84
85
86
87
88
89
	query.exec();

	if(!query.first())
		throw "No rule defined for this object";

	do {
90
91
		int min[8] = {-1};
		int max[8] = {-1};
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

		if(!query.isNull("min1")) {
			min[0] = query.value("min1").toInt();
		}
		if(!query.isNull("min2")) {
			min[1] = query.value("min2").toInt();
		}
		if(!query.isNull("min3")) {
			min[2] = query.value("min3").toInt();
		}
		if(!query.isNull("min4")) {
			min[3] = query.value("min4").toInt();
		}
		if(!query.isNull("min5")) {
			min[4] = query.value("min5").toInt();
		}
		if(!query.isNull("min6")) {
			min[5] = query.value("min6").toInt();
		}
		if(!query.isNull("min7")) {
			min[6] = query.value("min7").toInt();
		}
		if(!query.isNull("min8")) {
			min[7] = query.value("min8").toInt();
		}
		if(!query.isNull("max1")) {
			max[0] = query.value("max1").toInt();
		}
		if(!query.isNull("max2")) {
			max[1] = query.value("max2").toInt();
		}
		if(!query.isNull("max3")) {
			max[2] = query.value("max3").toInt();
		}
		if(!query.isNull("max4")) {
			max[3] = query.value("max4").toInt();
		}
		if(!query.isNull("max5")) {
			max[4] = query.value("max5").toInt();
		}
		if(!query.isNull("max6")) {
			max[5] = query.value("max6").toInt();
		}
		if(!query.isNull("max7")) {
			max[6] = query.value("max7").toInt();
		}
		if(!query.isNull("max8")) {
			max[7] = query.value("max8").toInt();
		}

		if(query.isNull("courant")) { // on ne prend pas en compte l'état courant
143
			fonction->ajouterRegle(a.getEnsemble().getEtat(query.value("destination").toInt()), min, max);
144
		} else {
145
			fonction->ajouterRegle(a.getEnsemble().getEtat(query.value("destination").toInt()), min, max, query.value("courant").toInt());
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
		}
	} while (query.next());

	return fonction;
}

/// Dans la base de donnée:
///
/// - type = 1 => von Neumann
/// - type = 2 => Moore
/// - type = 3 => arbitraire
RegleVoisinage* Database::getRegleVoisinage(const QString& name) const {
	QSqlQuery query(db);

	query.prepare("SELECT type, rayon FROM regles_voisinage WHERE id = :id");
	query.bindValue(":id", name);
	query.exec();

	if(!query.first())
165
		throw "Unable to select this object (neighbourhood)";
166
167
168

	int type = query.value("type").toInt();

169
	RegleVoisinage *regle = nullptr;
170
171
172
173
	if(type == 1) {
		if(query.isNull("rayon"))
			throw "Error: r can't be undefined here";

174
175
		regle = new RegleVoisinageNeumann;
		dynamic_cast<RegleVoisinageNeumann*>(regle)->setr(query.value("rayon").toInt());
176
177
	}
	else if(type == 2) {
178
179
180
		if(query.isNull("rayon"))
			throw "Error: r can't be undefined here";

181
182
		regle = new RegleVoisinageMoore;
		dynamic_cast<RegleVoisinageMoore*>(regle)->setr(query.value("rayon").toInt());
183
	}
184
	else if(type == 3) {
185
186
187
188
189
190
191
		query.prepare("SELECT x, y FROM coord_voisinage WHERE id = :id");
		query.bindValue(":id", name);
		query.exec();

		if(!query.first())
			throw "There must be at least one coord in this rule";

192
		regle = new RegleVoisinageArbitraire;
193
194
195
196
		Coordonnees coord;
		do {
			coord.x = query.value(0).toUInt();
			coord.y = query.value(1).toUInt();
197
			dynamic_cast<RegleVoisinageArbitraire*>(regle)->coordonnees.push_back(coord);
198
199
		} while(query.next());
	}
200
201
202
	else {
		throw "Unknown type of neighbourhood!";
	}
203
204

	return regle;
205
}
Leon Do Castelo's avatar
Leon Do Castelo committed
206
207
208
209
210
211

/// Retourne un descriptif des réseaux ("id", "nom", "id", "nom", etc.) liés à un automate
std::vector<QString> Database::getListeReseaux(const QString& name) const
{
    QSqlQuery query(db);

Leon Do Castelo's avatar
Leon Do Castelo committed
212
    query.prepare("SELECT id, nom FROM reseaux WHERE automate = :nom");
Leon Do Castelo's avatar
Leon Do Castelo committed
213
214
215
216
    query.bindValue(":nom", name);
    query.exec();

    std::vector<QString> names;
Leon Do Castelo's avatar
Leon Do Castelo committed
217
218
219
220

    if(!query.first())
        throw "There must be at least one coord in this rule";
    do {
Leon Do Castelo's avatar
Leon Do Castelo committed
221
222
        names.push_back(query.value("id").toString());
        names.push_back(query.value("nom").toString());
Leon Do Castelo's avatar
Leon Do Castelo committed
223
    } while(query.next());
Leon Do Castelo's avatar
Leon Do Castelo committed
224
225
226

    return names;
}
Leon Do Castelo's avatar
Leon Do Castelo committed
227
228
229
230


/// Cette fonction réinitialise le singleton EnsembleEtat avec des valeurs contenues dans la BDD, afin de retourner un réseau à partir des valeurs stockées dans la BDD.
/// @param idReseau correspond à la clé primaire du réseau dans la BDD, il est conseillé de l'avoir récupérée avec getListeReseaux() auparavant
231
Reseau& Database::getReseau(int idReseau) const {
Leon Do Castelo's avatar
Leon Do Castelo committed
232
233
234
235
236
    //initialisation du réseau de retour
    QSqlQuery reseau(db);
    reseau.prepare("SELECT * FROM reseaux WHERE id = :id");
    reseau.bindValue(":id", idReseau);
    reseau.exec();
237
    if(!reseau.first())
238
	    throw "Can't select (reseau) !";
239
    Reseau* r = new Reseau(reseau.value("l").toUInt(), reseau.value("h").toUInt());
Leon Do Castelo's avatar
Leon Do Castelo committed
240
241

    //remplissage du réseau
242
    for(size_t i = 0; i<reseau.value("l").toUInt(); i++)
Leon Do Castelo's avatar
Leon Do Castelo committed
243
    {
244
        for(size_t j = 0; j<reseau.value("h").toUInt(); j++)
Leon Do Castelo's avatar
Leon Do Castelo committed
245
246
        {
            QSqlQuery cellule(db);
247
            cellule.prepare("SELECT etat FROM Cellules WHERE (reseau = :id AND x = :i AND y = :j)");
Leon Do Castelo's avatar
Leon Do Castelo committed
248
            cellule.bindValue(":id", idReseau);
249
250
            cellule.bindValue(":i", static_cast<int>(i));
            cellule.bindValue(":j", static_cast<int>(j));
Leon Do Castelo's avatar
Leon Do Castelo committed
251
            cellule.exec();
252
	    if(!cellule.first())
253
		    throw "Can't select (cell) !";
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
254
            while(static_cast<int>(r->getReseau()[i][j].getIndEtat()) != cellule.value("etat").toInt())
Leon Do Castelo's avatar
Leon Do Castelo committed
255
256
257
258
259
260
261
                r->getReseau()[i][j].incrementerEtat();
        }
    }

    return *r;
}

262
263
264
void Database::saveAutomaton(const Automate& a) const {
	QSqlQuery query(db);
	query.prepare("INSERT INTO automates (nom, defaut, description, auteur, annee) VALUES (:nom, :etatDefaut, :description, :auteur, :annee)");
265
266
267
268
269
	query.bindValue(":nom", a.getTitle().c_str());
	query.bindValue(":etatDefaut", a.getFonction().getEtatDefaut().getIndice());
	query.bindValue(":description", a.getDesc().c_str());
	query.bindValue(":auteur", a.getAuthor().c_str());
	query.bindValue(":annee", a.getYear());
270
271
	query.exec();

272
	saveFunction(a.getTitle().c_str(), a.getFonction());
273
	saveVoisinage(a.getTitle().c_str(), a.getRegleVoisinage());
Boris Cazic's avatar
Boris Cazic committed
274
    stockerReseau(a.getReseauInit(), "Grille Aleatoire", a.getTitle().c_str());
Leon Do Castelo's avatar
Leon Do Castelo committed
275
    saveEnsemble(Automate::getInstance());
276
277
278
279
280
281
}

void Database::saveFunction(const QString& name, const Fonction& f) const {
	QSqlQuery query(db);
	for(auto rule: f.getRules()) {
		query.prepare("INSERT INTO regles_transition VALUES (:name, :min1, :min2, :min3, :min4, :min5, :min6, :min7, :min8, :max1, :max2, :max3, :max4, :max5, :max6, :max7, :max8, :courant, :dest)");
282
283
284
285
		query.bindValue(":name", name);
		query.bindValue(":dest", static_cast<int>(rule->getDestination().getIndice()));
		if(rule->getCourant() != -1) {
			query.bindValue(":courant", rule->getCourant());
286
287
		}
		else { // NULL value
288
			query.bindValue(":courant", QVariant(QVariant::Int));
289
290
		}

291
292
		if(rule->getMin(1) != -1) {
			query.bindValue(":min1", rule->getMin(1));
293
294
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
295
            query.bindValue(":min1", -1);
296
		}
297
298
		if(rule->getMin(2) != -1) {
			query.bindValue(":min2", rule->getMin(2));
299
300
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
301
            query.bindValue(":min2", -1);
302
		}
303
304
		if(rule->getMin(3) != -1) {
			query.bindValue(":min3", rule->getMin(3));
305
306
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
307
            query.bindValue(":min3", -1);
308
		}
309
310
		if(rule->getMin(4) != -1) {
			query.bindValue(":min4", rule->getMin(4));
311
312
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
313
            query.bindValue(":min4", -1);
314
		}
315
316
		if(rule->getMin(5) != -1) {
			query.bindValue(":min5", rule->getMin(5));
317
318
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
319
            query.bindValue(":min5", -1);
320
		}
321
322
		if(rule->getMin(6) != -1) {
			query.bindValue(":min6", rule->getMin(6));
323
324
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
325
            query.bindValue(":min6", -1);
326
		}
327
328
		if(rule->getMin(7) != -1) {
			query.bindValue(":min7", rule->getMin(7));
329
330
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
331
            query.bindValue(":min7", -1);
332
		}
333
334
		if(rule->getMin(8) != -1) {
			query.bindValue(":min8", rule->getMin(8));
335
336
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
337
            query.bindValue(":min8", -1);
338
339
		}

340
341
		if(rule->getMax(1) != -1) {
			query.bindValue(":max1", rule->getMax(1));
342
343
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
344
            query.bindValue(":max1", -1);
345
		}
346
347
		if(rule->getMax(2) != -1) {
			query.bindValue(":max2", rule->getMax(2));
348
349
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
350
            query.bindValue(":max2", -1);
351
		}
352
353
		if(rule->getMax(3) != -1) {
			query.bindValue(":max3", rule->getMax(3));
354
355
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
356
            query.bindValue(":max3", -1);
357
		}
358
359
		if(rule->getMax(4) != -1) {
			query.bindValue(":max4", rule->getMax(4));
360
361
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
362
            query.bindValue(":max4", -1);
363
		}
364
365
		if(rule->getMax(5) != -1) {
			query.bindValue(":max5", rule->getMax(5));
366
367
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
368
            query.bindValue(":max5", -1);
369
		}
370
371
		if(rule->getMax(6) != -1) {
			query.bindValue(":max6", rule->getMax(6));
372
373
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
374
            query.bindValue(":max6", -1);
375
		}
376
377
		if(rule->getMax(7) != -1) {
			query.bindValue(":max7", rule->getMax(7));
378
379
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
380
            query.bindValue(":max7", -1);
381
		}
382
383
		if(rule->getMax(8) != -1) {
			query.bindValue(":max8", rule->getMax(8));
384
385
		}
		else { // NULL value
Leon Do Castelo's avatar
Leon Do Castelo committed
386
            query.bindValue(":max8", -1);
387
388
389
390
391
392
393
394
395
396
397
398
		}

		query.exec();
	}
}

void Database::saveVoisinage(const QString& name, const RegleVoisinage& r) const {
	QSqlQuery query(db);
	int type = r.getType();

	if(type == 1 || type == 2) { //Von Neumann OR Moore (same structure)
		query.prepare("INSERT INTO regles_voisinage (id, type, rayon) VALUES (:nom, :type, :rayon)");
399
400
401
		query.bindValue(":nom", name);
		query.bindValue(":type", type);
		query.bindValue(":rayon", r.getr());
402
403
404
405

		query.exec();
	}
	else if(type == 3) { //Arbitrary
Leon Do Castelo's avatar
Leon Do Castelo committed
406
407
408
409
410
411
        query.prepare("INSERT INTO regles_voisinage (id, type, rayon) VALUES (:nom, :type, :rayon)");
        query.bindValue(":nom", name);
        query.bindValue(":type", type);
        query.bindValue(":rayon", r.getr());
        query.exec();

412
        const RegleVoisinageArbitraire& new_r = dynamic_cast<const RegleVoisinageArbitraire&>(r);
Leon Do Castelo's avatar
Leon Do Castelo committed
413
414
415
416
417
418
419
420
        for(size_t i = 0 ; i<new_r.coordonnees.size() ; i++)
        {
            query.prepare("INSERT INTO coord_voisinage VALUES (:nom, :x, :y)");
            query.bindValue(":nom", name);
            query.bindValue(":x", new_r.coordonnees[i].x);
            query.bindValue(":y", new_r.coordonnees[i].y);
            query.exec();
        }
421
422
423
424
425
	}
	else {
		throw "Unknown type!";
	}
}
Leon Do Castelo's avatar
Leon Do Castelo committed
426

427
void Database::saveEnsemble(Automate& a) const {
Leon Do Castelo's avatar
Leon Do Castelo committed
428
429
    //On passe à la création du tuple de l'ensemble d'état :
    //les tuples de Cellules prennent une clé étrangère d'EnsembleEtats (car elle appartient à la clé d'Etats) !
430
    //Il nous faut donc : id, automate --> on a la clé étrangère vers automate (nomAutomate), il faut créer l'id
Leon Do Castelo's avatar
Leon Do Castelo committed
431
432

    //Création de l'id du nouvel ensemble d'états
433
	QSqlQuery query(db);
Leon Do Castelo's avatar
Leon Do Castelo committed
434
435
    query.prepare("SELECT COUNT(*) FROM EnsembleEtats");
    query.exec();
436
437
    if(!query.first())
	    throw "Error sql!";
Leon Do Castelo's avatar
Leon Do Castelo committed
438
439
440
    int idEns = query.value(0).toInt() + 1;

    //Insertion du tuple dans EnsembleEtats
441
    query.prepare("INSERT INTO EnsembleEtats VALUES (:id, :automate)");
Leon Do Castelo's avatar
Leon Do Castelo committed
442
    query.bindValue(":id", idEns);
443
    query.bindValue(":automate", a.getTitle().c_str());
Leon Do Castelo's avatar
Leon Do Castelo committed
444
445
    query.exec();

446
447
    EnsembleEtat& enseEtats = a.getEnsemble();

Leon Do Castelo's avatar
Leon Do Castelo committed
448
449
450
451
452
    //On passe au stockage des états de l'ensemble :
    //les tuples de Cellules prennent une clé étrangère d'Etats !
    //Il nous faut prendre de chaque état : ensemble (idEns), indice, label, r, g, b
    for(unsigned int i = 0 ; i < enseEtats.getNbEtats() ; i++)
    {
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
453
        query.prepare("INSERT INTO Etats VALUES (:ensemble, :indice, :label, :r, :g, :b)");
Leon Do Castelo's avatar
Leon Do Castelo committed
454
455
456
457
458
459
460
461
        query.bindValue(":ensemble", idEns);
        query.bindValue(":indice", enseEtats.getEtat(i).getIndice());
        query.bindValue(":label", QString::fromStdString(enseEtats.getEtat(i).getLabel()));
        query.bindValue(":r", enseEtats.getEtat(i).getColor().red());
        query.bindValue(":g", enseEtats.getEtat(i).getColor().green());
        query.bindValue(":b", enseEtats.getEtat(i).getColor().blue());
        query.exec();
    }
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
}

///Cette fonction permet de stocker un réseau dans la BDD
///@param reseau est le réseau à stocker
///@param nomReseau est le nom du réseau à stocker
///@param nomAutomate est le nom de l'automate en cours
void Database::stockerReseau(const Reseau& reseau, const QString& nomReseau, const QString& nomAutomate) const
{
    //Tout d'abord, on a besoin de créer un tuple dans la table reseaux :
    //toutes les autres tables l'ont en clé étrangère !
    //Il nous faut donc : id, nom, h, l, automate --> tout est en paramètre ou dans reseau (avec getH, getL) sauf l'id à recréer

    //Création de l'id du nouveau réseau
    QSqlQuery query(db);
    query.prepare("SELECT COUNT(*) FROM reseaux");
    query.exec();
478
479
    if(!query.first())
	    throw "error sql!";
480
    int idReseau = query.value(0).toInt() + 1;
Leon Do Castelo's avatar
Leon Do Castelo committed
481

482
    //Insertion du tuple dans reseaux
483
    query.prepare("INSERT INTO reseaux VALUES (:id, :nom, :h, :l, :automate)");
484
485
486
487
488
489
    query.bindValue(":id", idReseau);
    query.bindValue(":nom", nomReseau);
    query.bindValue(":h", reseau.getHauteur());
    query.bindValue(":l", reseau.getLargeur());
    query.bindValue(":automate", nomAutomate);
    query.exec();
Leon Do Castelo's avatar
Leon Do Castelo committed
490
491
492
493
494
495
    //On termine avec les Cellules.
    //Il nous faut : reseau (idReseau), ensemble (idEns), etat (indice de la cellule), x, y
    for(int i = 0 ; i < reseau.getHauteur() ; i++)
    {
        for(int j = 0 ; j < reseau.getLargeur() ; j++)
        {
496
            query.prepare("INSERT INTO Cellules VALUES (:reseau, :etat, :x, :y)");
Leon Do Castelo's avatar
Leon Do Castelo committed
497
498
            query.bindValue(":reseau", idReseau);
            query.bindValue(":etat", reseau.getReseau()[i][j].getIndEtat());
Leon Do Castelo's avatar
Leon Do Castelo committed
499
500
            query.bindValue(":x", j);
            query.bindValue(":y", i);
Leon Do Castelo's avatar
Leon Do Castelo committed
501
502
503
504
505
            query.exec();
        }
    }
}

506
void Database::initSingletonAutomate(const QString& modele) const
Leon Do Castelo's avatar
Leon Do Castelo committed
507
508
509
510
{
    Automate::getInstance().reinitialiserAutomate();

    QSqlQuery reseau(db);
511
    reseau.prepare("SELECT nom, auteur, description, annee FROM automates WHERE nom = :id");
Leon Do Castelo's avatar
Leon Do Castelo committed
512
513
514
    reseau.bindValue(":id", modele);
    reseau.exec();

515
    if(!reseau.first())
516
	    throw "Can't select (automaton) !";
517
518
519
520
521

    Automate::getInstance().setTitle(reseau.value(0).toString().toStdString());
    Automate::getInstance().setAuthor(reseau.value(1).toString().toStdString());
    Automate::getInstance().setDesc(reseau.value(2).toString().toStdString());
    Automate::getInstance().setYear(reseau.value(3).toInt());
Leon Do Castelo's avatar
Leon Do Castelo committed
522

523
    Database::initEnsEtat(Automate::getInstance());
524
525
    Automate::getInstance().setFonction(Database::getFonction(Automate::getInstance()));
    Automate::getInstance().setRegleVoisinage(Database::getRegleVoisinage(modele));
Leon Do Castelo's avatar
Leon Do Castelo committed
526
527
528
529
530

    std::vector<QString> reseaux = Database::getListeReseaux(modele);
    Automate::getInstance().setReseauInit(Database::getReseau(reseaux[0].toInt()));
    Automate::getInstance().initialiserBuffer();
}