libsqlite3x  2007.10.18
sqlite3x_cursor.cpp
00001 /*
00002   Copyright (C) 2004-2005 Cory Nelson
00003 
00004   This software is provided 'as-is', without any express or implied
00005   warranty.  In no event will the authors be held liable for any damages
00006   arising from the use of this software.
00007 
00008   Permission is granted to anyone to use this software for any purpose,
00009   including commercial applications, and to alter it and redistribute it
00010   freely, subject to the following restrictions:
00011 
00012   1. The origin of this software must not be misrepresented; you must not
00013   claim that you wrote the original software. If you use this software
00014   in a product, an acknowledgment in the product documentation would be
00015   appreciated but is not required.
00016   2. Altered source versions must be plainly marked as such, and must not be
00017   misrepresented as being the original software.
00018   3. This notice may not be removed or altered from any source distribution.
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 &copy) : 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 &copy) {
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 //  char const * sqlite3_cursor::getcolname(int index) {
00148 //      READER_CHECK(string);
00149 //      char const * cn = sqlite3_column_name(this->cmd->stmt, index);
00150 //      return cn ? cn : "";
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 }