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
27 namespace 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 
169  return sqlite3_cursor(*this);
170  }
171 
173  this->executecursor().step();
174  }
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 }
sqlite3_cursor executecursor()
Executes the query and returns a cursor object which can be used to iterate over the results...
std::string getstring(int index)
Gets the string value at the given field number.
void executenonquery()
Executes the query and provides no way to get the results.
A type for reading results from an sqlite3_command.
Definition: sqlite3x.hpp:458
This namespace encapsulates a C++ API wrapper for sqlite3 databases.
Definition: sqlite3x.hpp:120
Represents a connection to an sqlite3 database.
Definition: sqlite3x.hpp:148
std::string executeblob()
Executes the query, which is expected to have a string or blob field as the first result field...
std::string getblob(int index)
Gets the blob value at the given field number.
int colcount()
Returns the column count of this object&#39;s query, or throws on error.
sqlite_int64 int64_t
64-bit integer type used by this code.
Definition: sqlite3x.hpp:125
bool reset()
Resets this statement using sqlite3_reset().
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...
double executedouble()
Executes the query, which is expected to have a double field as the first result field.
double getdouble(int index)
Gets the double value at the given field number.
void bind(int index)
Binds NULL to the given index.
void finalize()
Finalizes this statement.
sqlite3_stmt * handle()
Returns the underlying statement handle.
int64_t getint64(int index)
Gets the (int64_t) 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...
~sqlite3_command()
Cleans up any resources in use by this object.
Exception type used by the sqlite3x classes.
Definition: sqlite3x.hpp:777
void prepare(char const *sql, int len=-1)
Prepares this statement or throws on error.
int getint(int index)
Gets the integer value at the given field number.
sqlite3 * db() const
Returns a handle to the underlying sqlite3 database.
int executeint()
Executes the query, which is expected to have an integer field as the first result field...