00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <sqlite3.h>
00023 #include "sqlite3x.hpp"
00024
00025 namespace sqlite3x {
00026
00027 sqlite3_cursor::sqlite3_cursor() : cmd(NULL) {}
00028
00029 sqlite3_cursor::sqlite3_cursor(const sqlite3_cursor ©) : cmd(copy.cmd) {
00030 if(this->cmd) ++this->cmd->refs;
00031 }
00032
00033 sqlite3_cursor::sqlite3_cursor(sqlite3_command & cmd) : cmd(&cmd) {
00034 ++this->cmd->refs;
00035 }
00036
00037 sqlite3_cursor::~sqlite3_cursor() {
00038 this->close();
00039 }
00040
00041 sqlite3_cursor& sqlite3_cursor::operator=(const sqlite3_cursor ©) {
00042 this->close();
00043
00044 this->cmd=copy.cmd;
00045 if(this->cmd) ++this->cmd->refs;
00046
00047 return *this;
00048 }
00049
00050 int sqlite3_cursor::colcount()
00051 {
00052 if( ! this->cmd )
00053 {
00054 throw database_error("sqlite3_cursor::colcount(): reader is closed");
00055 }
00056 return this->cmd->colcount();
00057 }
00058
00059 bool sqlite3_cursor::step() {
00060 if(!this->cmd) throw database_error("sqlite3_cursor::step(): reader is closed");
00061
00062 switch(sqlite3_step(this->cmd->stmt)) {
00063 case SQLITE_ROW:
00064 return true;
00065 case SQLITE_DONE:
00066 return false;
00067 default:
00068 throw database_error(this->cmd->con);
00069 }
00070 }
00071
00072 void sqlite3_cursor::reset() {
00073 if(!this->cmd) throw database_error("sqlite3_cursor::reset(): reader is closed");
00074
00075 if(! this->cmd->reset() )
00076 {
00077 throw database_error("sqlite3_cursor::reset() db error: %s", this->cmd->con.errormsg().c_str() );
00078 }
00079 }
00080
00081 void sqlite3_cursor::close() {
00082 if(this->cmd) {
00083 if(--this->cmd->refs==0) { sqlite3_reset(this->cmd->stmt); }
00084 this->cmd=NULL;
00085 }
00086 }
00087
00088 #define READER_CHECK(FUNC) \
00089 if( ! this->cmd ) throw database_error( "sqlite3_cursor::%s(%d): reader is closed", # FUNC, index ); \
00090 if( (index)>(this->cmd->argc-1)) throw database_error("sqlite3_cursor::%s(%d): index out of range", # FUNC, index );
00091
00092 bool sqlite3_cursor::isnull(int index) {
00093 READER_CHECK(isnull);
00094 return sqlite3_column_type(this->cmd->stmt, index) == SQLITE_NULL;
00095 }
00096
00097 int sqlite3_cursor::getint(int index) {
00098 READER_CHECK(getint);
00099 return sqlite3_column_int(this->cmd->stmt, index);
00100 }
00101
00102 int64_t sqlite3_cursor::getint64(int index) {
00103 READER_CHECK(getint64);
00104 return sqlite3_column_int64(this->cmd->stmt, index);
00105 }
00106
00107 double sqlite3_cursor::getdouble(int index) {
00108 READER_CHECK(getdouble);
00109 return sqlite3_column_double(this->cmd->stmt, index);
00110 }
00111
00112 std::string sqlite3_cursor::getstring(int index) {
00113 READER_CHECK(string);
00114 return std::string((const char*)sqlite3_column_text(this->cmd->stmt, index), sqlite3_column_bytes(this->cmd->stmt, index));
00115 }
00116
00117 char const * sqlite3_cursor::getstring(int index, int & size) {
00118 READER_CHECK(string);
00119 size = sqlite3_column_bytes(this->cmd->stmt, index);
00120 return (char const *)sqlite3_column_text(this->cmd->stmt, index);
00121 }
00122
00123 #if SQLITE3X_USE_WCHAR
00124 std::wstring sqlite3_cursor::getstring16(int index) {
00125 READER_CHECK(wstring);
00126 return std::wstring((const wchar_t*)sqlite3_column_text16(this->cmd->stmt, index), sqlite3_column_bytes16(this->cmd->stmt, index)/2);
00127 }
00128 #endif
00129
00130 std::string sqlite3_cursor::getblob(int index) {
00131 READER_CHECK(string);
00132 return std::string((const char*)sqlite3_column_blob(this->cmd->stmt, index), sqlite3_column_bytes(this->cmd->stmt, index));
00133 }
00134
00135 void const * sqlite3_cursor::getblob(int index, int & size ) {
00136 READER_CHECK(string);
00137 size = sqlite3_column_bytes(this->cmd->stmt, index);
00138 return sqlite3_column_blob(this->cmd->stmt, index);
00139 }
00140
00141 std::string sqlite3_cursor::getcolname(int index) {
00142 READER_CHECK(string);
00143 char const * cn = sqlite3_column_name(this->cmd->stmt, index);
00144 return cn ? cn : "";
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 #if SQLITE3X_USE_WCHAR
00154 std::wstring sqlite3_cursor::getcolname16(int index) {
00155 READER_CHECK(wstring);
00156 return (const wchar_t*)sqlite3_column_name16(this->cmd->stmt, index);
00157 }
00158 #endif
00159
00160 #undef READER_CHECK
00161 }