-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathSqlMonitor.h
141 lines (113 loc) · 4.33 KB
/
SqlMonitor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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
/*
Copyright (C) 2011-2013 Klarälvdalens Datakonsult AB,
a KDAB Group company, [email protected],
author Andras Mantia <[email protected]>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef SQL_MONITOR_H
#define SQL_MONITOR_H
#include <QObject>
#include <QSqlDatabase>
#include <QStringList>
#include "sqlate_export.h"
#include "SqlUtils.h"
#include <boost/preprocessor/repetition.hpp>
/**
* Helper class for monitoring a set up tables for changes.
*/
class SQLATE_EXPORT SqlMonitor : public QObject
{
Q_OBJECT
public:
/**
* Creates a table monitor for the given database.
* @param db The database on which we want to monitor tables.
* @param parent The parent object.
*/
explicit SqlMonitor( const QSqlDatabase& db, QObject* parent = 0 );
virtual ~SqlMonitor();
/**
* Set a list of table names to monitor.
* @param tables List of table names.
*/
void setMonitorTables( const QStringList &tables );
/**
* Monitor a row and emits a signal carrying the content of a selected column when an UPDATE is performed on this row.
* @note you need to declare the column as "notification ready" in the SQL schema, using the flag "Notify"
*
* @param table the table in which we want the row to be monitored
* @param column the monitored column
*
*/
template <typename T>
bool addValueMonitor( const T&, const QVariant& value)
{
QString processedValue = value.toString();
//remove braces in case of an uuid
if(processedValue.contains(QLatin1Char('{')) && processedValue.contains(QLatin1Char('}')))
{
processedValue.remove(QLatin1Char('{'));
processedValue.remove(QLatin1Char('}'));
}
const QString identifier = SqlUtils::createIdentifier(T::table::sqlName() + QLatin1Char( '_' ) + T::sqlName());
const QString notification = QString::fromLatin1("%1_%2")
.arg(processedValue)
.arg(identifier);
m_monitoredValues << notification; //maybe it's already registered in another instance of the monitor, just add it in the list in this case
if(subscribe(notification))
{
return true;
}
else return false;
}
/**
* @brief Subscribes again to the monitored notifications. Used after an unexpected database disconnection.
**/
void resubscribe();
/**
* @brief Unsubscribe from all "values" notifications
**/
void unsubscribeValuesNotifications();
QSqlDatabase database() const { return m_db; }
QStringList monitoredTables() const { return m_tables; }
QStringList monitoredValues() const { return m_monitoredValues; }
#ifndef SQL_MONITOR_MAX_SIZE
#define SQL_MONITOR_MAX_SIZE 15
#endif
#define CONST_REF(z, n, unused) const T ## n &
#define TABLE_NAME(z, n, unused) << T ## n ::tableName()
#define MONITOR_IMPL(z, n, unused) \
template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
void setMonitorTables( BOOST_PP_ENUM(n, CONST_REF, ~) ) { \
setMonitorTables( QStringList() BOOST_PP_REPEAT(n, TABLE_NAME, ~) ); \
}
BOOST_PP_REPEAT_FROM_TO(1, SQL_MONITOR_MAX_SIZE, MONITOR_IMPL, ~)
#undef MONITOR_IMPL
#undef CONST_REF
#undef TABLE_NAME
Q_SIGNALS:
/**
* Emitted when any of the monitored tables changed.
*/
void tablesChanged();
void notify( const QString ¬ification );
private Q_SLOTS:
void notificationReceived( const QString ¬ification );
private:
bool subscribe( const QString& notification );
QSqlDatabase m_db;
QStringList m_tables;
QStringList m_monitoredValues;
};
#endif