aboutsummaryrefslogblamecommitdiffstats
path: root/include/sqdb.hpp
blob: b92cac6f27a1f711d55fb82ed49e6595ec14e8c7 (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;
    };

}