aboutsummaryrefslogblamecommitdiffstats
path: root/src/Utilities/sqdb.hpp
blob: ea38787d96265b09a28c8dff9f115b199a9490ef (plain) (tree)














































































































































































































                                                                  
#pragma once

#include <string>

#include "sqlite3.h"

#ifdef _WIN32
#  include <tchar.h>
#  define SQDB_MAKE_TEXT(x) _TEXT(x)
#  define SQDB_STRLEN _tcslen
#  define SQDB_STRDUP _tcsdup
#else
#  define SQDB_MAKE_TEXT(x) (x)
#  define SQDB_STRLEN strlen
#  define SQDB_STRDUP strdup
#endif

#if !defined(SQDB_UTF16) && !defined(SQDB_UTF8)
#  ifdef _WIN32
#    if defined(UNICODE) || defined(_UNICODE)
#      define SQDB_UTF16
#    else
#      define SQDB_UTF8
#    endif
#  else
#    define SQDB_UTF8
#  endif
#endif

#ifdef SQDB_UTF8
#  define SQDB_CHAR char
#  define SQDB_STD_STRING std::string
#endif

#ifdef SQDB_UTF16
#  define SQDB_CHAR TCHAR
#  define SQDB_STD_STRING std::wstring
#endif

namespace sqdb
{

    class Exception
    {
    public:
        Exception(sqlite3* db);

        Exception(sqlite3* db, int errorCode);

        Exception(const SQDB_CHAR* errorMsg);

        ~Exception();

        int GetErrorCode() const;

        const SQDB_CHAR* GetErrorMsg() const;
    private:
        int m_errorCode;
        SQDB_CHAR* m_errorMsg;
    };

#define CHECK(db, returnCode) \
  if ( (returnCode) != SQLITE_OK ) throw Exception(db, returnCode)

    class RefCount
    {
    protected:
        RefCount();

        RefCount(const RefCount& x);
        RefCount& operator=(const RefCount& x);

        void IncRef();
        unsigned DecRef();

    private:
        unsigned* m_refCount;
    };

    class Blob : public RefCount
    {
    public:
        Blob(const void* data, int size);

        Blob(const Blob& x);
        Blob& operator=(const Blob& x);

        int GetSize() const;
        const char* GetData() const;

        ~Blob();

    private:
        char* m_data;
        int m_size;
    };

    class Convertor
    {
    public:
        Convertor(sqlite3* db, sqlite3_stmt* stmt, int field);

        operator int() const;
        operator unsigned long() const;
        operator long long() const;
        operator double() const;
        operator SQDB_STD_STRING() const;
        operator const SQDB_CHAR*() const;
        operator Blob() const;

        int GetInt() const;
        unsigned long GetUnsignedLong() const;
        long long GetLongLong() const;
        double GetDouble() const;
        SQDB_STD_STRING GetString() const;
        const SQDB_CHAR* GetText() const;
        Blob GetBlob() const;

    private:
        sqlite3* m_db;
        sqlite3_stmt* m_stmt;
        int m_field;
    };

    class Statement : public RefCount
    {
    public:
        Statement(sqlite3* db, sqlite3_stmt* stmt);

        Statement(const Statement& x);
        Statement& operator=(const Statement& x);

        bool Next();
        Convertor GetField(int field) const;

        template<class T>
        void Bind(int i, const T& value)
        {
            if ( m_needReset )
                Reset();
            DoBind(i, value);
        }

        void BindBlob(int i, const void* value, int n);
        void BindNull(int i);

        ~Statement();

    private:
        void DoBind(int i, int value);
        void DoBind(int i, long long value);
        void DoBind(int i, double value);
        void DoBind(int i, const SQDB_STD_STRING& value);
        void DoBind(int i, const SQDB_CHAR* value);

        // Bind blob.
        void DoBind(int i, const void* value, int n);

        // Bind null.
        void DoBind(int i);

        // Reset binders so that new values can be bound.
        void Reset();

        sqlite3* m_db;
        sqlite3_stmt* m_stmt;
        bool m_needReset;
    };

    class QueryStr
    {
    public:
        QueryStr();

        const SQDB_CHAR* Format(const SQDB_CHAR* fmt, ...);

        const SQDB_CHAR* Get() const;

        ~QueryStr();

    private:
        SQDB_CHAR* m_buf;
    };

    class Db : public RefCount
    {
    public:
        Db(const SQDB_CHAR* fileName);

        void BeginTransaction();
        void CommitTransaction();
        void RollbackTransaction();

        bool TableExists(const SQDB_CHAR* tableName);
        Statement Query(const SQDB_CHAR* queryStr);
        long long LastId();

        Db(const Db& x);
        Db& operator=(const Db& x);

        ~Db();

    private:
        sqlite3* m_db;
    };

}