1 /* vi: set sw=4 ts=4:
2  *
3  * Copyright (C) 2017 Christian Hohnstaedt.
4  *
5  * All rights reserved.
6  */
7 
8 #ifndef __SQL_H
9 #define __SQL_H
10 
11 #include <QtSql>
12 #include <QList>
13 
14 #define SQL_PREPARE(q,cmd) do { \
15 	(q).prepare(cmd); \
16 	(q).location(__FILE__,__LINE__); \
17 } while (0)
18 
19 class DbTransaction
20 {
21 	private:
22 		static int mutex;
23 		static int error;
24 		static QList<quint64> items;
25 		static bool hasTransaction;
26 		bool has_begun;
27 		void debug(const char *func, const char *file, int line);
28 		bool finish(const char *oper, const char *file, int line);
29 
30 	public:
31 		DbTransaction();
32 		~DbTransaction();
33 		bool begin(const char *file, int line);
34 		bool commit(const char *file, int line);
35 		bool rollback(const char *file, int line);
36 		bool done(QSqlError e, const char *file, int line);
37 		static quint64 DatabaseStamp;
active()38 		static bool active()
39 		{
40 			return mutex > 0;
41 		}
addItems(QVariant v)42 		static void addItems(QVariant v)
43 		{
44 			items << v.toULongLong();
45 		}
setHasTransaction(bool trans)46 		static void setHasTransaction(bool trans)
47 		{
48 			hasTransaction = trans;
49 		}
50 };
51 
52 #define Transaction DbTransaction __trans
53 #define TransBegin() __trans.begin(__FILE__, __LINE__)
54 #define TransThrow() if (!__trans.begin(__FILE__, __LINE__)) { \
55 	throw errorEx(QObject::tr("Failed to start a database transaction")); }
56 #define TransCommit() __trans.commit(__FILE__, __LINE__)
57 #define TransRollback() __trans.rollback(__FILE__, __LINE__)
58 #define TransDone(e) __trans.done(e, __FILE__, __LINE__);
59 #define AffectedItems(v) (DbTransaction::addItems(v))
60 
61 
62 class XSqlQuery: public QSqlQuery
63 {
64 	private:
65 		QString lastq, query;
66 		const char *file;
67 		int line;
68 		QString rewriteQuery(QString query);
69 		static QString table_prefix;
70 	public:
71 		XSqlQuery();
72 		XSqlQuery(QString q);
73 
74 		static int schemaVersion();
setTablePrefix(QString p)75 		static void setTablePrefix(QString p)
76 		{
77 			table_prefix = p;
78 		}
clearTablePrefix()79 		static void clearTablePrefix()
80 		{
81 			table_prefix.clear();
82 		}
83 		QString query_details();
84 		QSqlError lastError();
85 		bool exec(QString q);
86 		bool exec();
87 		bool prepare(QString q);
88 		void location(const char *f, int l);
89 };
90 
91 #endif
92