sqlitexx: result.hpp Source File

sqlitexx 0.0.1

result.hpp
Go to the documentation of this file.
1/*
2 * sqlite3xx - sqlite3 C++ layer, following the ideas of libpqxx
3 * Copyright (C) 2009 Andreas Baumann
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions of
7 * the GNU Lesser General Public License, as published by the Free Software
8 * Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this distribution; if not, write to:
18 * Free Software Foundation, Inc.
19 * 51 Franklin Street, Fifth Floor
20 * Boston, MA 02110-1301 USA
21 *
22 */
23
24#ifndef SQLITE3XX_RESULT_H
25#define SQLITE3XX_RESULT_H
26
27#include "sqlite3.h"
28
29#include <iostream>
30#include <map>
31#include <vector>
32#include <stdexcept>
33#include <sstream>
34
35#include "port/iterator.hpp"
36#include "port/dllexport.h"
37
38using namespace std;
39
40namespace sqlite3xx {
41
42 class SQLITEXX_LIBEXPORT result {
43 public:
44 class field;
45 class const_iterator;
46
47 typedef unsigned long size_type;
48 typedef signed long difference_type;
49
50 class SQLITEXX_LIBEXPORT tuple {
51 public:
52 typedef unsigned int size_type;
53
54 private:
55 const result *_r;
56 result::size_type _i;
57
58 public:
59 tuple( const result *r, size_type i ) :
60 _r( r ), _i( i ) { }
61 ~tuple( ) { }
62
63 size_type size( ) const {
64 return _r->columns( );
65 }
66
67 field operator[]( size_type i ) const {
68 return field( *this, i );
69 }
70 field operator[]( int i ) const {
71 return operator[]( (size_type)i );
72 }
73 field operator[]( string s ) const {
74 return field( *this, _r->column_number( s ) );
75 }
76
77 int column_type( size_type i ) const {
78 return _r->column_type( i );
79 }
80
81 int GetValueInt( size_type i ) const {
82 return _r->GetValueInt( i );
83 }
84
85 const unsigned char* GetValueText( size_type i ) const {
86 return _r->GetValueText( i );
87 }
88
89 double GetValueDouble( size_type i ) const {
90 return _r->GetValueDouble( i );
91 }
92
93 size_type rownumber( ) const throw( ) {
94 return _i;
95 }
96
97 protected:
98 tuple( );
99 };
100
101 class SQLITEXX_LIBEXPORT field {
102 private:
103 tuple _t;
104 tuple::size_type _c;
105
106 SQLITEXX_PRIVATE string type_to_str( const int type ) const {
107 switch( type ) {
108 case SQLITE_INTEGER: return "SQLITE_INTEGER";
109 case SQLITE_FLOAT: return "SQLITE_FLOAT";
110 case SQLITE_BLOB: return "SQLITE_BLOB";
111 case SQLITE_NULL: return "SQLITE_NULL";
112 case SQLITE3_TEXT: return "SQLITE_TEXT";
113 default: return "<unknown type>";
114 }
115 }
116
117 public:
118 field( const tuple& t, tuple::size_type c ) :
119 _t( t ), _c( c ) { }
120
121 SQLITEXX_LIBEXPORT friend ostream& operator<<( ostream& o, const field& f );
122
123 void GetValueOfType( int type, int& obj ) const {
124 if( type == SQLITE_INTEGER ) {
125 obj = _t.GetValueInt( _c );
126 } else if( type == SQLITE_NULL ) {
127 obj = 0;
128 } else {
129 ostringstream oss;
130 oss << "Invalid type conversion requested for integer type, type is "
131 << type_to_str( type ) << "(" << type << ")";
132 throw invalid_argument( oss.str( ) );
133 }
134 }
135
136 void GetValueOfType( int type, string& obj ) const {
137 if( type == SQLITE3_TEXT ) {
138 obj = string( (const char *)_t.GetValueText( _c ) );
139 } else if( type == SQLITE_NULL ) {
140 obj = string( );
141 } else {
142 ostringstream oss;
143 oss << "Invalid type conversion requested for string type, type is "
144 << type_to_str( type ) << "(" << type << ")";
145 throw invalid_argument( oss.str( ) );
146 }
147 }
148
149 void GetValueOfType( int type, double& obj ) const {
150 if( type == SQLITE_FLOAT ) {
151 obj = _t.GetValueDouble( _c );
152 } else if( type == SQLITE_NULL ) {
153 obj = 0.0;
154 } else {
155 ostringstream oss;
156 oss << "Invalid type conversion requested for double type, type is "
157 << type_to_str( type ) << "(" << type << ")";
158 throw invalid_argument( oss.str( ) );
159 }
160 }
161
162 template<typename T> bool to( T& obj ) const {
163 int type = _t.column_type( _c );
164 GetValueOfType( type, obj );
165 return true;
166 }
167 };
168
169 typedef sqlite3xxstd::iterator< std::random_access_iterator_tag,
170 const tuple,
171 result::difference_type,
172 const_iterator,
173 tuple>
174 const_iterator_base;
175
176 class SQLITEXX_LIBEXPORT const_iterator :
177 public const_iterator_base,
178 public tuple {
179
180 public:
181 typedef const tuple *pointer;
182
183 const_iterator( ) throw( ) : tuple( 0, 0 ) { }
184 const_iterator( const tuple& t ) throw( )
185 : tuple( t ) { }
186
187 pointer operator->( ) const { return this; }
188 const_iterator operator++( int incr );
189 bool operator<( const const_iterator& i ) const;
190
191 private:
192 int dummy;
193 friend class result;
194 SQLITEXX_PRIVATE const_iterator( const result* r, size_type i ) throw( ) :
195 tuple( r, i ) {
196 };
197 };
198
199 private:
200 sqlite3_stmt* _stmt;
201 size_type _row; /* the currently visible row from the cache */
202 size_type _crow; /* the row of the sqlite step cursor */
203 typedef map<string, size_type> ColMap;
204 ColMap _colmap;
205 typedef vector<int> ColType;
206 ColType _coltype;
207
208 enum Status {
209 st_nascent, /* created, we must call step */
210 st_nodata, /* a command without result data */
211 st_lastrow, /* a query, on the last row */
212 st_hasdata, /* a query, we must clean up in the end */
213 st_nomoredata /* a query, with no data left */
214 };
215
216 class CachedValue {
217 public:
218 int type;
219 union {
220 int i;
221 double d;
222 unsigned char *s;
223 } value;
224
225 public:
226 CachedValue( ) { type = 0; value.s = NULL; };
227 CachedValue( const CachedValue& v );
228 ~CachedValue( );
229 CachedValue& operator= ( const CachedValue& v );
230 };
231
232 typedef vector<CachedValue> ValueCache;
233 ValueCache _cache;
234
235 Status _status;
236
237 public:
238 result( sqlite3_stmt* stmt );
239 result( const result& r );
240 ~result( );
241 result& operator= ( const result& r );
242
243 size_type affected_rows( ) const;
244 size_type size( ) const;
245 size_type columns( ) const;
246
247 const tuple operator[]( size_type i ) throw( );
248
249 size_type column_number( string name ) const;
250 int column_type( size_type i ) const;
251 int column_type( string name ) const {
252 return column_type( column_number( name ) );
253 }
254
255 int GetValueInt( size_type i ) const {
256 return _cache[i].value.i;
257 }
258
259 const unsigned char* GetValueText( size_type i ) const {
260 return _cache[i].value.s;
261 }
262
263 double GetValueDouble( size_type i ) const {
264 return _cache[i].value.d;
265 }
266
267 const_iterator begin( ) const throw( ) {
268 return const_iterator( this, 0 );
269 }
270
271 /* as size( ) is not reliable, we can't create the correct
272 * tuple with the correct index here
273 */
274 const_iterator end( ) const throw( ) {
275 return const_iterator( this, size( ) );
276 }
277
278 private:
279 SQLITEXX_PRIVATE void Step( );
280 SQLITEXX_PRIVATE void BufferData( );
281 SQLITEXX_PRIVATE void FillColNameMap( );
282 SQLITEXX_PRIVATE void FillColTypeMap( );
283};
284
285}
286
287#endif /* SQLITE3XX_RESULT_H */
sqlite3xx::result::const_iterator
Definition result.hpp:178
sqlite3xx::result::const_iterator::const_iterator
const_iterator(const tuple &t)
Definition result.hpp:184
sqlite3xx::result::const_iterator::pointer
const tuple * pointer
Definition result.hpp:181
sqlite3xx::result::const_iterator::operator->
pointer operator->() const
Definition result.hpp:187
sqlite3xx::result::const_iterator::operator++
const_iterator operator++(int incr)
sqlite3xx::result::const_iterator::const_iterator
const_iterator()
Definition result.hpp:183
sqlite3xx::result::const_iterator::operator<
bool operator<(const const_iterator &i) const
sqlite3xx::result::field
Definition result.hpp:101
sqlite3xx::result::field::GetValueOfType
void GetValueOfType(int type, double &obj) const
Definition result.hpp:149
sqlite3xx::result::field::field
field(const tuple &t, tuple::size_type c)
Definition result.hpp:118
sqlite3xx::result::field::GetValueOfType
void GetValueOfType(int type, string &obj) const
Definition result.hpp:136
sqlite3xx::result::field::GetValueOfType
void GetValueOfType(int type, int &obj) const
Definition result.hpp:123
sqlite3xx::result::field::to
bool to(T &obj) const
Definition result.hpp:162
sqlite3xx::result::field::operator<<
SQLITEXX_LIBEXPORT friend ostream & operator<<(ostream &o, const field &f)
sqlite3xx::result::tuple
Definition result.hpp:50
sqlite3xx::result::tuple::GetValueInt
int GetValueInt(size_type i) const
Definition result.hpp:81
sqlite3xx::result::tuple::column_type
int column_type(size_type i) const
Definition result.hpp:77
sqlite3xx::result::tuple::size
size_type size() const
Definition result.hpp:63
sqlite3xx::result::tuple::tuple
tuple()
sqlite3xx::result::tuple::operator[]
field operator[](string s) const
Definition result.hpp:73
sqlite3xx::result::tuple::~tuple
~tuple()
Definition result.hpp:61
sqlite3xx::result::tuple::operator[]
field operator[](size_type i) const
Definition result.hpp:67
sqlite3xx::result::tuple::GetValueText
const unsigned char * GetValueText(size_type i) const
Definition result.hpp:85
sqlite3xx::result::tuple::operator[]
field operator[](int i) const
Definition result.hpp:70
sqlite3xx::result::tuple::tuple
tuple(const result *r, size_type i)
Definition result.hpp:59
sqlite3xx::result::tuple::rownumber
size_type rownumber() const
Definition result.hpp:93
sqlite3xx::result::tuple::GetValueDouble
double GetValueDouble(size_type i) const
Definition result.hpp:89
sqlite3xx::result::tuple::size_type
unsigned int size_type
Definition result.hpp:52
sqlite3xx::result
Definition result.hpp:42
sqlite3xx::result::size_type
unsigned long size_type
Definition result.hpp:47
sqlite3xx::result::operator[]
const tuple operator[](size_type i)
sqlite3xx::result::size
size_type size() const
sqlite3xx::result::~result
~result()
sqlite3xx::result::affected_rows
size_type affected_rows() const
sqlite3xx::result::end
const_iterator end() const
Definition result.hpp:274
sqlite3xx::result::result
result(sqlite3_stmt *stmt)
sqlite3xx::result::GetValueInt
int GetValueInt(size_type i) const
Definition result.hpp:255
sqlite3xx::result::const_iterator_base
sqlite3xxstd::iterator< std::random_access_iterator_tag, const tuple, result::difference_type, const_iterator, tuple > const_iterator_base
Definition result.hpp:174
sqlite3xx::result::column_number
size_type column_number(string name) const
sqlite3xx::result::GetValueDouble
double GetValueDouble(size_type i) const
Definition result.hpp:263
sqlite3xx::result::column_type
int column_type(string name) const
Definition result.hpp:251
sqlite3xx::result::columns
size_type columns() const
sqlite3xx::result::begin
const_iterator begin() const
Definition result.hpp:267
sqlite3xx::result::difference_type
signed long difference_type
Definition result.hpp:48
sqlite3xx::result::GetValueText
const unsigned char * GetValueText(size_type i) const
Definition result.hpp:259
sqlite3xx::result::column_type
int column_type(size_type i) const
sqlite3xx::result::result
result(const result &r)
dllexport.h
SQLITEXX_LIBEXPORT
#define SQLITEXX_LIBEXPORT
Definition dllexport.h:35
SQLITEXX_PRIVATE
#define SQLITEXX_PRIVATE
Definition dllexport.h:36
iterator.hpp
sqlite3xx
Definition connection.hpp:41