/*! \file sqlite_backend.cpp * \brief SQLite implementation of IStorageBackend. * */ #if !defined(TINYMUX_TYPES_DEFINED) #include "copyright.h" #include "autoconf.h" #include "config.h" #include "externs.h" #endif #include "sqlite_backend.h" #include CSQLiteBackend::CSQLiteBackend() { } CSQLiteBackend::~CSQLiteBackend() { Close(); } bool CSQLiteBackend::Open(const char *path) { return m_db.Open(path); } void CSQLiteBackend::Close() { m_db.Close(); } bool CSQLiteBackend::IsOpen() const { return m_db.IsOpen(); } bool CSQLiteBackend::Get(unsigned int object, unsigned int attrnum, UTF8 *buf, size_t buflen, size_t *pLen, int *owner, int *flags) { dbref db_owner; int db_flags; bool rc = m_db.GetAttribute(static_cast(object), static_cast(attrnum), buf, buflen, pLen, &db_owner, &db_flags); if (rc) { if (owner) *owner = static_cast(db_owner); if (flags) *flags = db_flags; } return rc; } bool CSQLiteBackend::Put(unsigned int object, unsigned int attrnum, const UTF8 *value, size_t len, int owner, int flags) { return m_db.PutAttribute(static_cast(object), static_cast(attrnum), value, len, static_cast(owner), flags); } bool CSQLiteBackend::Del(unsigned int object, unsigned int attrnum) { return m_db.DelAttribute(static_cast(object), static_cast(attrnum)); } bool CSQLiteBackend::DelAll(unsigned int object) { return m_db.DelAllAttributes(static_cast(object)); } bool CSQLiteBackend::GetAll(unsigned int object, AttrCallback cb) { return m_db.GetAllAttributes(static_cast(object), [&cb](int attrnum, const UTF8 *value, size_t len, dbref owner, int flags) { cb(static_cast(attrnum), value, len, static_cast(owner), flags); }); } bool CSQLiteBackend::GetBuiltin(unsigned int object, AttrCallback cb) { return m_db.GetBuiltinAttributes(static_cast(object), [&cb](int attrnum, const UTF8 *value, size_t len, dbref owner, int flags) { cb(static_cast(attrnum), value, len, static_cast(owner), flags); }); } int CSQLiteBackend::Count(unsigned int object) { return m_db.CountAttributes(static_cast(object)); } uint32_t CSQLiteBackend::GetModCount(unsigned int object, unsigned int attrnum) { return m_db.GetAttrModCount(static_cast(object), static_cast(attrnum)); } bool CSQLiteBackend::GetAllModCounts(unsigned int object, ModCountCallback cb) { m_db.GetAllAttrModCounts(static_cast(object), [&cb](int attrnum, uint32_t mc) { cb(static_cast(attrnum), mc); }); return true; } void CSQLiteBackend::Sync() { m_db.Checkpoint(); } void CSQLiteBackend::Tick() { // Write-through means SQLite is always up to date. // Periodic optimize is light maintenance. // m_db.Optimize(); } bool derive_sqlite_path(char *buf, size_t buflen, const UTF8 *indb) { if ( nullptr == buf || 0 == buflen || nullptr == indb) { return false; } static const char suffix[] = ".sqlite"; const size_t nSuffix = sizeof(suffix) - 1; const char *pIn = reinterpret_cast(indb); size_t nIn = strlen(pIn); // A trailing ".db" is replaced rather than appended to, so the base is // shorter than the input in that case. Note this still grows the path: // three characters out, seven in. // size_t nBase = nIn; if ( 3 < nIn && 0 == strcmp(pIn + nIn - 3, ".db")) { nBase = nIn - 3; } if (buflen < nBase + nSuffix + 1) { return false; } memcpy(buf, pIn, nBase); memcpy(buf + nBase, suffix, nSuffix + 1); return true; }