1 | // |
2 | // Notifier.cpp |
3 | // |
4 | // Library: SQL/SQLite |
5 | // Package: SQLite |
6 | // Module: Notifier |
7 | // |
8 | // Implementation of Notifier |
9 | // |
10 | // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. |
11 | // and Contributors. |
12 | // |
13 | // SPDX-License-Identifier: BSL-1.0 |
14 | // |
15 | |
16 | |
17 | #include "Poco/SQL/SQLite/Notifier.h" |
18 | |
19 | |
20 | namespace Poco { |
21 | namespace SQL { |
22 | namespace SQLite { |
23 | |
24 | |
25 | Notifier::Notifier(const Session& session, EnabledEventType enabled): |
26 | _session(session), |
27 | _row(), |
28 | _enabledEvents() |
29 | { |
30 | if (enabled & SQLITE_NOTIFY_UPDATE) enableUpdate(); |
31 | if (enabled & SQLITE_NOTIFY_COMMIT) enableCommit(); |
32 | if (enabled & SQLITE_NOTIFY_ROLLBACK) enableRollback(); |
33 | } |
34 | |
35 | |
36 | Notifier::Notifier(const Session& session, const Any& value, EnabledEventType enabled): |
37 | _session(session), |
38 | _value(value), |
39 | _row(), |
40 | _enabledEvents() |
41 | { |
42 | if (enabled & SQLITE_NOTIFY_UPDATE) enableUpdate(); |
43 | if (enabled & SQLITE_NOTIFY_COMMIT) enableCommit(); |
44 | if (enabled & SQLITE_NOTIFY_ROLLBACK) enableRollback(); |
45 | } |
46 | |
47 | |
48 | Notifier::~Notifier() |
49 | { |
50 | try |
51 | { |
52 | disableAll(); |
53 | } |
54 | catch (...) |
55 | { |
56 | poco_unexpected(); |
57 | } |
58 | } |
59 | |
60 | |
61 | bool Notifier::enableUpdate() |
62 | { |
63 | Poco::Mutex::ScopedLock l(_mutex); |
64 | |
65 | if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteUpdateCallbackFn, this)) |
66 | _enabledEvents |= SQLITE_NOTIFY_UPDATE; |
67 | |
68 | return updateEnabled(); |
69 | } |
70 | |
71 | |
72 | bool Notifier::disableUpdate() |
73 | { |
74 | Poco::Mutex::ScopedLock l(_mutex); |
75 | |
76 | if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::UpdateCallbackType) 0, this)) |
77 | _enabledEvents &= ~SQLITE_NOTIFY_UPDATE; |
78 | |
79 | return !updateEnabled(); |
80 | } |
81 | |
82 | |
83 | bool Notifier::updateEnabled() const |
84 | { |
85 | return 0 != (_enabledEvents & SQLITE_NOTIFY_UPDATE); |
86 | } |
87 | |
88 | |
89 | bool Notifier::enableCommit() |
90 | { |
91 | Poco::Mutex::ScopedLock l(_mutex); |
92 | |
93 | if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteCommitCallbackFn, this)) |
94 | _enabledEvents |= SQLITE_NOTIFY_COMMIT; |
95 | |
96 | return commitEnabled(); |
97 | } |
98 | |
99 | |
100 | bool Notifier::disableCommit() |
101 | { |
102 | Poco::Mutex::ScopedLock l(_mutex); |
103 | |
104 | if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::CommitCallbackType) 0, this)) |
105 | _enabledEvents &= ~SQLITE_NOTIFY_COMMIT; |
106 | |
107 | return !commitEnabled(); |
108 | } |
109 | |
110 | |
111 | bool Notifier::commitEnabled() const |
112 | { |
113 | return 0 != (_enabledEvents & SQLITE_NOTIFY_COMMIT); |
114 | } |
115 | |
116 | |
117 | bool Notifier::enableRollback() |
118 | { |
119 | Poco::Mutex::ScopedLock l(_mutex); |
120 | |
121 | if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteRollbackCallbackFn, this)) |
122 | _enabledEvents |= SQLITE_NOTIFY_ROLLBACK; |
123 | |
124 | return rollbackEnabled(); |
125 | } |
126 | |
127 | |
128 | bool Notifier::disableRollback() |
129 | { |
130 | Poco::Mutex::ScopedLock l(_mutex); |
131 | |
132 | if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::RollbackCallbackType) 0, this)) |
133 | _enabledEvents &= ~SQLITE_NOTIFY_ROLLBACK; |
134 | |
135 | return !rollbackEnabled(); |
136 | } |
137 | |
138 | |
139 | bool Notifier::rollbackEnabled() const |
140 | { |
141 | return 0 != (_enabledEvents & SQLITE_NOTIFY_ROLLBACK); |
142 | } |
143 | |
144 | |
145 | bool Notifier::enableAll() |
146 | { |
147 | return enableUpdate() && enableCommit() && enableRollback(); |
148 | } |
149 | |
150 | |
151 | bool Notifier::disableAll() |
152 | { |
153 | return disableUpdate() && disableCommit() && disableRollback(); |
154 | } |
155 | |
156 | |
157 | void Notifier::sqliteUpdateCallbackFn(void* pVal, int opCode, const char* /*pDB*/, const char* pTable, Poco::Int64 row) |
158 | { |
159 | poco_check_ptr(pVal); |
160 | Notifier* pV = reinterpret_cast<Notifier*>(pVal); |
161 | if (opCode == Utility::OPERATION_INSERT) |
162 | { |
163 | pV->_row = row; |
164 | pV->_table = pTable; |
165 | pV->insert.notify(pV); |
166 | } |
167 | else if (opCode == Utility::OPERATION_UPDATE) |
168 | { |
169 | pV->_row = row; |
170 | pV->_table = pTable; |
171 | pV->update.notify(pV); |
172 | } |
173 | else if (opCode == Utility::OPERATION_DELETE) |
174 | { |
175 | pV->_row = row; |
176 | pV->_table = pTable; |
177 | pV->erase.notify(pV); |
178 | } |
179 | } |
180 | |
181 | |
182 | int Notifier::sqliteCommitCallbackFn(void* pVal) |
183 | { |
184 | Notifier* pV = reinterpret_cast<Notifier*>(pVal); |
185 | |
186 | try |
187 | { |
188 | pV->commit.notify(pV); |
189 | } |
190 | catch (...) |
191 | { |
192 | return -1; |
193 | } |
194 | |
195 | return 0; |
196 | } |
197 | |
198 | |
199 | void Notifier::sqliteRollbackCallbackFn(void* pVal) |
200 | { |
201 | Notifier* pV = reinterpret_cast<Notifier*>(pVal); |
202 | pV->rollback.notify(pV); |
203 | } |
204 | |
205 | |
206 | } } } // namespace Poco::SQL::SQLite |
207 | |