Commit 2586e46d authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

SqliteConnection: Add sqlite hooks support

parent aff38c33
...@@ -60,6 +60,7 @@ SqliteConnection::Handle SqliteConnection::getConn() ...@@ -60,6 +60,7 @@ SqliteConnection::Handle SqliteConnection::getConn()
while ( s.row() != nullptr ) while ( s.row() != nullptr )
; ;
m_conns.emplace( std::this_thread::get_id(), std::move( dbConn ) ); m_conns.emplace( std::this_thread::get_id(), std::move( dbConn ) );
sqlite3_update_hook( dbConnection, &updateHook, this );
return dbConnection; return dbConnection;
} }
return it->second.get(); return it->second.get();
...@@ -79,3 +80,29 @@ SqliteConnection::WriteContext SqliteConnection::acquireWriteContext() ...@@ -79,3 +80,29 @@ SqliteConnection::WriteContext SqliteConnection::acquireWriteContext()
{ {
return WriteContext{ m_writeLock }; return WriteContext{ m_writeLock };
} }
void SqliteConnection::registerUpdateHook( const std::string& table, SqliteConnection::UpdateHookCb cb )
{
m_hooks.emplace( table, cb );
}
void SqliteConnection::updateHook( void* data, int reason, const char*,
const char* table, sqlite_int64 rowId )
{
const auto self = reinterpret_cast<SqliteConnection*>( data );
auto it = self->m_hooks.find( table );
if ( it == end( self->m_hooks ) )
return;
switch ( reason )
{
case SQLITE_INSERT:
it->second( HookReason::Insert, rowId );
break;
case SQLITE_UPDATE:
it->second( HookReason::Update, rowId );
break;
case SQLITE_DELETE:
it->second( HookReason::Delete, rowId );
break;
}
}
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#ifndef SQLITECONNECTION_H #ifndef SQLITECONNECTION_H
#define SQLITECONNECTION_H #define SQLITECONNECTION_H
#include <functional>
#include <memory> #include <memory>
#include <sqlite3.h> #include <sqlite3.h>
#include <condition_variable> #include <condition_variable>
...@@ -43,6 +44,13 @@ public: ...@@ -43,6 +44,13 @@ public:
using ReadContext = std::unique_lock<utils::ReadLocker>; using ReadContext = std::unique_lock<utils::ReadLocker>;
using WriteContext = std::unique_lock<utils::WriteLocker>; using WriteContext = std::unique_lock<utils::WriteLocker>;
using Handle = sqlite3*; using Handle = sqlite3*;
enum class HookReason
{
Insert,
Delete,
Update
};
using UpdateHookCb = std::function<void(HookReason, int64_t)>;
explicit SqliteConnection( const std::string& dbPath ); explicit SqliteConnection( const std::string& dbPath );
~SqliteConnection(); ~SqliteConnection();
...@@ -53,6 +61,12 @@ public: ...@@ -53,6 +61,12 @@ public:
ReadContext acquireReadContext(); ReadContext acquireReadContext();
WriteContext acquireWriteContext(); WriteContext acquireWriteContext();
void registerUpdateHook( const std::string& table, UpdateHookCb cb );
private:
static void updateHook( void* data, int reason, const char* database,
const char* table, sqlite_int64 rowId );
private: private:
using ConnPtr = std::unique_ptr<sqlite3, int(*)(sqlite3*)>; using ConnPtr = std::unique_ptr<sqlite3, int(*)(sqlite3*)>;
const std::string m_dbPath; const std::string m_dbPath;
...@@ -61,6 +75,7 @@ private: ...@@ -61,6 +75,7 @@ private:
utils::SWMRLock m_contextLock; utils::SWMRLock m_contextLock;
utils::ReadLocker m_readLock; utils::ReadLocker m_readLock;
utils::WriteLocker m_writeLock; utils::WriteLocker m_writeLock;
std::unordered_map<std::string, UpdateHookCb> m_hooks;
}; };
#endif // SQLITECONNECTION_H #endif // SQLITECONNECTION_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment