#pragma once #include #include "sqlite3.h" #ifdef _WIN32 # include # 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 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; }; }