SQLite event notifier

Notifier is SQLite DB event (insert, update, delete, commit, rollback)
callback wrapper.
This commit is contained in:
aleks-f
2013-02-20 16:35:21 -06:00
parent f756d995d2
commit 6943505634
16 changed files with 607 additions and 4 deletions

View File

@@ -0,0 +1,217 @@
//
// Notifier.h
//
// $Id: //poco/Main/Data/SQLite/include/Poco/Data/SQLite/Notifier.h#2 $
//
// Library: SQLite
// Package: SQLite
// Module: Notifier
//
// Definition of Notifier.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
#ifndef SQLite_Notifier_INCLUDED
#define SQLite_Notifier_INCLUDED
#include "Poco/Data/SQLite/SQLite.h"
#include "Poco/Data/SQLite/Utility.h"
#include "Poco/Data/Session.h"
#include "Poco/Mutex.h"
#include "Poco/Types.h"
#include "Poco/Dynamic/Var.h"
#include "Poco/BasicEvent.h"
#include <map>
namespace Poco {
namespace Data {
namespace SQLite {
class SQLite_API Notifier
/// Notifier is a wrapper for SQLite callback calls. It supports event callbacks
/// for insert, update, delete, commit and rollback events. While (un)registering
/// callbacks is thread-safe, execution of the callbacks themselves are not;
/// it is the user's responsibility to ensure the thread-safey of the functions
/// they provide as callback target. Additionally, commit callbacks may prevent
/// database transactions from succeeding (see sqliteCommitCallbackFn documentation
/// for details).
///
/// There can be only one set of callbacks per session (i.e. registering a new
/// callback automatically unregisters the previous one). All callbacks are
/// registered and enabled at Notifier contruction time and can be disabled
/// at a later point time.
{
public:
typedef unsigned char EnabledEventType;
/// A type definition for events-enabled bitmap.
typedef Poco::BasicEvent<void> Event;
//
// Events
//
Event update;
Event insert;
Event erase;
Event commit;
Event rollback;
// Event types.
static const EnabledEventType SQLITE_NOTIFY_UPDATE = 1;
static const EnabledEventType SQLITE_NOTIFY_COMMIT = 2;
static const EnabledEventType SQLITE_NOTIFY_ROLLBACK = 4;
Notifier(const Session& session,
EnabledEventType enabled = SQLITE_NOTIFY_UPDATE | SQLITE_NOTIFY_COMMIT | SQLITE_NOTIFY_ROLLBACK);
/// Creates a Notifier and enables all callbacks.
Notifier(const Session& session,
const Any& value,
EnabledEventType enabled = SQLITE_NOTIFY_UPDATE | SQLITE_NOTIFY_COMMIT | SQLITE_NOTIFY_ROLLBACK);
/// Creates a Notifier, assigns the value to the internal storage and and enables all callbacks.
~Notifier();
/// Disables all callbacks and destroys the Notifier.
bool enableUpdate();
/// Enables update callbacks.
bool disableUpdate();
/// Disables update callbacks.
bool updateEnabled() const;
/// Returns true if update callbacks are enabled, false otherwise.
bool enableCommit();
/// Enables commit callbacks.
bool disableCommit();
/// Disables commit callbacks.
bool commitEnabled() const;
/// Returns true if update callbacks are enabled, false otherwise.
bool enableRollback();
/// Enables rollback callbacks.
bool disableRollback();
/// Disables rollback callbacks.
bool rollbackEnabled() const;
/// Returns true if rollback callbacks are enabled, false otherwise.
bool enableAll();
/// Enables all callbacks.
bool disableAll();
/// Disables all callbacks.
static void sqliteUpdateCallbackFn(void* pVal, int opCode, const char* pDB, const char* pTable, Poco::Int64 row);
/// Update callback event dispatcher. Determines the type of the event, updates the row number
/// and triggers the event.
static int sqliteCommitCallbackFn(void* pVal);
/// Commit callback event dispatcher. If an exception occurs, it is catched inside this function,
/// non-zero value is returned, which causes SQLite engine to turn commit into a rollback.
/// Therefore, callers should check for return value - if it is zero, callback completed succesfuly
/// and transaction was committed.
static void sqliteRollbackCallbackFn(void* pVal);
/// Rollback callback event dispatcher.
bool operator == (const Notifier& other) const;
/// Equality operator. Compares value, row and database handles and
/// returns true iff all are equal.
Poco::Int64 getRow() const;
/// Returns the row number.
void setRow(Poco::Int64 row);
/// Sets the row number.
const Poco::Dynamic::Var& getValue() const;
/// Returns the value.
template <typename T>
inline void setValue(const T& val)
/// Sets the value.
{
_value = val;
}
private:
Notifier();
Notifier(const Notifier&);
Notifier& operator=(const Notifier&);
const Session& _session;
Poco::Dynamic::Var _value;
Poco::Int64 _row;
EnabledEventType _enabledEvents;
Poco::Mutex _mutex;
};
//
// inlines
//
inline bool Notifier::operator == (const Notifier& other) const
{
return _value == other._value &&
_row == other._row &&
Utility::dbHandle(_session) == Utility::dbHandle(other._session);
}
inline Poco::Int64 Notifier::getRow() const
{
return _row;
}
inline void Notifier::setRow(Poco::Int64 row)
/// Sets the row number.
{
_row = row;
}
inline const Poco::Dynamic::Var& Notifier::getValue() const
{
return _value;
}
} } } // namespace Poco::Data::SQLite
#endif // SQLite_Notifier_INCLUDED