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
20namespace Poco {
21namespace SQL {
22namespace SQLite {
23
24
25Notifier::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
36Notifier::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
48Notifier::~Notifier()
49{
50 try
51 {
52 disableAll();
53 }
54 catch (...)
55 {
56 poco_unexpected();
57 }
58}
59
60
61bool 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
72bool 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
83bool Notifier::updateEnabled() const
84{
85 return 0 != (_enabledEvents & SQLITE_NOTIFY_UPDATE);
86}
87
88
89bool 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
100bool 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
111bool Notifier::commitEnabled() const
112{
113 return 0 != (_enabledEvents & SQLITE_NOTIFY_COMMIT);
114}
115
116
117bool 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
128bool 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
139bool Notifier::rollbackEnabled() const
140{
141 return 0 != (_enabledEvents & SQLITE_NOTIFY_ROLLBACK);
142}
143
144
145bool Notifier::enableAll()
146{
147 return enableUpdate() && enableCommit() && enableRollback();
148}
149
150
151bool Notifier::disableAll()
152{
153 return disableUpdate() && disableCommit() && disableRollback();
154}
155
156
157void 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
182int 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
199void 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