#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;
};
}