libsqlite3x 2007.10.18
sqlite3x_command.cpp
1/*
2 Copyright (C) 2004-2005 Cory Nelson
3 Copyright (C) 2006 stephan beal
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20
21*/
22
23#include <sqlite3.h>
24#include "sqlite3x.hpp"
25#include <cstring> // strlen()
26#include <iostream> // only for debuggin
27namespace sqlite3x {
28
29 sqlite3_command::sqlite3_command(sqlite3_connection &con)
30 : con(con),stmt(0),refs(0),argc(0)
31 {
32 }
33
34
35 sqlite3_command::sqlite3_command(sqlite3_connection &con, const std::string &sql)
36 : con(con),stmt(0),refs(0),argc(0)
37 {
38 this->prepare( sql );
39 }
40
41 sqlite3_command::sqlite3_command(sqlite3_connection &con, char const * sql, size_t len )
42 : con(con),stmt(0),refs(0),argc(0)
43 {
44 this->prepare( sql, static_cast<int>( len ) );
45 }
46
47#if SQLITE3X_USE_WCHAR
48 sqlite3_command::sqlite3_command(sqlite3_connection &con, const std::wstring &sql) : con(con),stmt(0),refs(0),argc(0) {
49 const void *tail=NULL;
50 int rc =
51#if (SQLITE_VERSION_NUMBER >= 3003009)
52 sqlite3_prepare16_v2
53#else
54 sqlite3_prepare16
55#endif
56 (con.db(), sql.data(), (int)sql.length()*2, &this->stmt, &tail);
57 if( SQLITE_OK != rc )
58 {
59 throw database_error("sqlite3_command::prepare failed. Reason=[%s]",
60 sqlite3_errmsg( this->con.db() ) );
61 }
62 this->argc=sqlite3_column_count(this->stmt);
63 }
64#endif
65
66 void sqlite3_command::prepare( char const * sql, int len )
67 {
68 if( this->stmt ) this->finalize();
69 const char *tail=NULL;
70 int rc =
71#if (SQLITE_VERSION_NUMBER >= 3003009)
72 sqlite3_prepare_v2
73#else
74 sqlite3_prepare
75#endif
76 ( this->con.db(), sql, len, &(this->stmt), &tail );
77 if( SQLITE_OK != rc )
78 {
79 throw database_error("sqlite3_command::prepare([%s]) failed. Reason=[%s]",
80 sql, sqlite3_errmsg( this->con.db() ) );
81 }
82 this->argc=sqlite3_column_count(this->stmt);
83 }
84
85 void sqlite3_command::prepare( std::string const & sql )
86 {
87 this->prepare( sql.c_str(), static_cast<int>( sql.size()) );
88 }
89
90
92 try
93 {
94 this->finalize();
95 }
96 catch(...)
97 {
98 // std::cout << "sqlite3_command::~sqlite3_command() ignoring an exception!\n";
99 // silently ignore
100 }
101 }
102
104 {
105 if( this->stmt )
106 {
107 if(sqlite3_finalize(this->stmt)!=SQLITE_OK)
108 throw database_error(this->con);
109 this->stmt = 0;
110 }
111 }
112
113 void sqlite3_command::bind(int index) {
114 if(sqlite3_bind_null(this->stmt, index)!=SQLITE_OK)
115 throw database_error(this->con);
116 }
117
118 void sqlite3_command::bind(int index, int data) {
119 if(sqlite3_bind_int(this->stmt, index, data)!=SQLITE_OK)
120 throw database_error(this->con);
121 }
122
123 void sqlite3_command::bind(int index, int64_t data) {
124 if(sqlite3_bind_int64(this->stmt, index, data)!=SQLITE_OK)
125 throw database_error(this->con);
126 }
127
128 void sqlite3_command::bind(int index, double data) {
129 if(sqlite3_bind_double(this->stmt, index, data)!=SQLITE_OK)
130 throw database_error(this->con);
131 }
132
133 void sqlite3_command::bind(int index, const char *data, int datalen) {
134 if(sqlite3_bind_text(this->stmt, index, data,
135 static_cast<int>(
136 ((-1==datalen)
137 ? std::strlen(data)
138 : datalen)
139 ),
140 SQLITE_TRANSIENT)!=SQLITE_OK)
141 throw database_error(this->con);
142 }
143
144#if SQLITE3X_USE_WCHAR
145 void sqlite3_command::bind(int index, const wchar_t *data, int datalen) {
146 if(sqlite3_bind_text16(this->stmt, index, data, datalen, SQLITE_TRANSIENT)!=SQLITE_OK)
147 throw database_error(this->con);
148 }
149#endif
150
151 void sqlite3_command::bind(int index, const void *data, int datalen) {
152 if(sqlite3_bind_blob(this->stmt, index, data, datalen, SQLITE_TRANSIENT)!=SQLITE_OK)
153 throw database_error(this->con);
154 }
155
156 void sqlite3_command::bind(int index, const std::string &data) {
157 if(sqlite3_bind_text(this->stmt, index, data.data(), (int)data.length(), SQLITE_TRANSIENT)!=SQLITE_OK)
158 throw database_error(this->con);
159 }
160
161#if SQLITE3X_USE_WCHAR
162 void sqlite3_command::bind(int index, const std::wstring &data) {
163 if(sqlite3_bind_text16(this->stmt, index, data.data(), (int)data.length()*2, SQLITE_TRANSIENT)!=SQLITE_OK)
164 throw database_error(this->con);
165 }
166#endif
167
171
175
177 sqlite3_cursor reader=this->executecursor();
178 if(!reader.step()) throw database_error("nothing to read");
179 return reader.getint(0);
180 }
181
183 sqlite3_cursor reader=this->executecursor();
184 if(!reader.step()) throw database_error("nothing to read");
185 return reader.getint64(0);
186 }
187
189 sqlite3_cursor reader=this->executecursor();
190 if(!reader.step()) throw database_error("nothing to read");
191 return reader.getdouble(0);
192 }
193
194 char const * sqlite3_command::executestring( int & size ) {
195 sqlite3_cursor reader=this->executecursor();
196 if(!reader.step()) throw database_error("nothing to read");
197 return reader.getstring( 0, size );
198 }
199
201 sqlite3_cursor reader=this->executecursor();
202 if(!reader.step()) throw database_error("nothing to read");
203 return reader.getstring(0);
204 }
205
206#if SQLITE3X_USE_WCHAR
207 std::wstring sqlite3_command::executestring16() {
208 sqlite3_cursor reader=this->executecursor();
209 if(!reader.step()) throw database_error("nothing to read");
210 return reader.getstring16(0);
211 }
212#endif
213
215 sqlite3_cursor reader=this->executecursor();
216 if(!reader.step()) throw database_error("nothing to read");
217 return reader.getblob(0);
218 }
219
220 void const * sqlite3_command::executeblob( int & size ) {
221 sqlite3_cursor reader=this->executecursor();
222 if(!reader.step()) throw database_error("nothing to read");
223 return reader.getblob(0, size);
224 }
225
227 {
228 if( ! this->stmt )
229 {
230 throw database_error("sqlite3_command::colcount(): statement has not been prepared");
231 }
232 return sqlite3_column_count( this->stmt );
233 }
234
235
237 {
238 int rc = SQLITE_OK;
239 if( this->stmt )
240 {
241 rc = sqlite3_reset( this->stmt );
242 }
243 return rc == SQLITE_OK;
244 }
245
246 sqlite3_stmt * sqlite3_command::handle()
247 {
248 return this->stmt;
249 }
250
251
252}
Exception type used by the sqlite3x classes.
Definition sqlite3x.hpp:777
int executeint()
Executes the query, which is expected to have an integer field as the first result field.
~sqlite3_command()
Cleans up any resources in use by this object.
bool reset()
Resets this statement using sqlite3_reset().
void executenonquery()
Executes the query and provides no way to get the results.
std::string executeblob()
Executes the query, which is expected to have a string or blob field as the first result field.
void prepare(char const *sql, int len=-1)
Prepares this statement or throws on error.
void finalize()
Finalizes this statement.
int colcount()
Returns the column count of this object's query, or throws on error.
sqlite3_cursor executecursor()
Executes the query and returns a cursor object which can be used to iterate over the results.
double executedouble()
Executes the query, which is expected to have a double field as the first result field.
std::string executestring()
Executes the query, which is expected to have a string or blob field as the first result field.
int64_t executeint64()
Executes the query, which is expected to have a (int64_t) field as the first result field.
sqlite3_stmt * handle()
Returns the underlying statement handle.
void bind(int index)
Binds NULL to the given index.
Represents a connection to an sqlite3 database.
Definition sqlite3x.hpp:149
sqlite3 * db() const
Returns a handle to the underlying sqlite3 database.
A type for reading results from an sqlite3_command.
Definition sqlite3x.hpp:458
int getint(int index)
Gets the integer value at the given field number.
int64_t getint64(int index)
Gets the (int64_t) value at the given field number.
std::string getstring(int index)
Gets the string value at the given field number.
bool step()
Steps one step through the sql result set and returns true on SQLITE_ROW, false on SQLITE3_DONE,...
std::string getblob(int index)
Gets the blob value at the given field number.
double getdouble(int index)
Gets the double value at the given field number.
This namespace encapsulates a C++ API wrapper for sqlite3 databases.
Definition sqlite3x.hpp:120
sqlite_int64 int64_t
64-bit integer type used by this code.
Definition sqlite3x.hpp:125