1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2020 Christian Hohnstaedt.
4  *
5  * All rights reserved.
6  */
7 
8 #ifndef __DATABASE_MODEL_H
9 #define __DATABASE_MODEL_H
10 
11 #include <QList>
12 #include <QObject>
13 #include <QDebug>
14 #include <QStringList>
15 #include <QSqlDatabase>
16 
17 #include "sql.h"
18 #include "db_base.h"
19 #include "lib/Passwd.h"
20 
21 typedef QMap<QString, QString> DbMap;
22 
23 class database_model: public QObject
24 {
25 	Q_OBJECT
26 
27 	private:
28 		QList<db_base*> models;
29 		int dbTimer;
30 		void openSqlDB();
31 		QSqlError initSqlDB();
32 		QString dbName;
33 		bool checkForOldDbFormat(const QString &dbfile) const;
34 		enum open_result verifyOldDbPass(const QString &dbname) const;
35 		void importOldDatabase(const QString &dbfile);
36 		QString get_default_db() const;
37 		QString checkPre2Xdatabase() const;
38 		enum open_result initPass(const QString &dbName,
39 				const QString &passhash) const;
40 		void restart_timer();
41 		static void openDatabase(const QString &descriptor,
42 					 const Passwd &pass);
43 		static void openRemoteDatabase(const QString &connName,
44 						const DbMap &params,
45 						const Passwd &pass);
46 		static void openLocalDatabase(const QString &connName,
47 						const QString &descriptor);
48 	private slots:
49 		void pkiChangedSlot(pki_base *pki);
50 
51 	public:
52 		database_model(const QString &dbName,
53 				const Passwd &pass = Passwd());
54 		~database_model();
55 		void timerEvent(QTimerEvent *event);
56 		db_base *modelForPki(const pki_base *pki) const;
57 
dbname()58 		QString dbname() const
59 		{
60 			return dbName;
61 		}
62 		void dump_database(const QString &dirname) const;
getModels()63 		QList<db_base*> getModels() const
64 		{
65 			return models;
66 		}
model()67 		template <class T> T *model() const
68 		{
69 			foreach(db_base *model, models) {
70 				T *m = dynamic_cast<T*>(model);
71 				if (m)
72 					return m;
73 			}
74 			return NULL;
75 		}
76 		pki_base *insert(pki_base *pki);
77 
78 		static DbMap splitRemoteDbName(const QString &db);
79 		static bool isRemoteDB(const QString &db);
80 		static void as_default_database(const QString &db);
81 
82 	signals:
83 		void pkiChanged(pki_base *pki) const;
84 };
85 
86 class xca_db
87 {
88 	private:
89 		database_model *db;
90 
91 	public:
xca_db()92 		xca_db() : db(nullptr) { }
~xca_db()93 		~xca_db()
94 		{
95 			close();
96 		}
97 		void open(const QString &dbName, const Passwd &pass = Passwd())
98 		{
99 			close();
100 			db = new database_model(dbName, pass);
101 			qDebug() << "Opening database:" << name();
102 		}
open_default()103 		void open_default()
104 		{
105 			open(QString());
106 		}
close()107 		void close()
108 		{
109 			if (db) {
110 				qDebug() << "Closing database:" << name();
111 				delete db;
112 				db = NULL;
113 			}
114 		}
name()115 		QString name() const
116 		{
117 			return db ? db->dbname() : QString();
118 		}
isOpen()119 		bool isOpen()
120 		{
121 			return db != NULL;
122 		}
model()123 		template <class T> T *model() const
124 		{
125 			return db ? db->model<T>() : NULL;
126 		}
dump(const QString & dirname)127 		void dump(const QString &dirname) const
128 		{
129 			if (db)
130 				db->dump_database(dirname);
131 		}
as_default()132 		void as_default() const
133 		{
134 			database_model::as_default_database(name());
135 		}
getModels()136 		QList<db_base*> getModels() const
137 		{
138 			return db ? db->getModels() : QList<db_base*>();
139 		}
insert(pki_base * pki)140 		pki_base *insert(pki_base *pki)
141 		{
142 			return db ? db->insert(pki) : NULL;
143 		}
modelForPki(const pki_base * pki)144 		db_base *modelForPki(const pki_base *pki) const
145 		{
146 			return db ? db->modelForPki(pki) : NULL;
147 		}
connectToDbChangeEvt(QObject * o,const char * slot)148 		void connectToDbChangeEvt(QObject *o, const char *slot)
149 		{
150 			if (db)
151 				QObject::connect(
152 					db, SIGNAL(pkiChanged(pki_base*)),
153 					o, slot);
154 		}
155 };
156 
157 extern xca_db Database;
158 
159 #endif
160