/sqlite3cc

To get this branch, use:
bzr branch http://bzr.ed.am/sqlite3cc
1 by edam
- initial commit
1
/*
2 by edam
- further initial development
2
 * basic_statement.h
1 by edam
- initial commit
3
 *
22 by edam
updated email and web addresses
4
 * Copyright (C) 2009 Tim Marston <tim@ed.am>
1 by edam
- initial commit
5
 *
2 by edam
- further initial development
6
 * This file is part of sqlite3cc (hereafter referred to as "this program").
22 by edam
updated email and web addresses
7
 * See http://ed.am/dev/sqlite3cc for more information.
8
 *
9
 * This program is free software: you can redistribute it and/or modify it under
10
 * the terms of the GNU Lesser General Public License as published by the Free
11
 * Software Foundation, either version 3 of the License, or (at your option) any
12
 * later version.
13
 *
14
 * This program is distributed in the hope that it will be useful, but WITHOUT
15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
17
 * details.
1 by edam
- initial commit
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
2 by edam
- further initial development
23
#ifndef SQLITE3CC_BASIC_STATEMENT_H_
24
#define SQLITE3CC_BASIC_STATEMENT_H_
1 by edam
- initial commit
25
26
27
#include <sqlite3.h>
28
#include <boost/utility.hpp>
29
#include <boost/lexical_cast.hpp>
2 by edam
- further initial development
30
#include <sqlite3cc/exception.h>
1 by edam
- initial commit
31
32
33
namespace sqlite
34
{
35
36
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
37
class connection;
2 by edam
- further initial development
38
class row;
12 by edam
- moved null_t, exec_t and set_index_t to detail namespace so only their extern instantiations are in the main namespace
39
namespace detail {
40
	struct null_t;
41
	struct exec_t;
42
	struct set_index_t;
43
}
2 by edam
- further initial development
44
45
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
46
namespace detail
47
{
48
49
2 by edam
- further initial development
50
/**
22 by edam
updated email and web addresses
51
 * The statement class represents an SQL statement.  It is the base class for
2 by edam
- further initial development
52
 * both the command and the query classes, which should be used for those
22 by edam
updated email and web addresses
53
 * purposes.  The basic_statement class its self has protected instantiation.
2 by edam
- further initial development
54
 */
55
class basic_statement
1 by edam
- initial commit
56
{
57
//______________________________________________________________________________
58
//                                                                 instantiation
59
protected:
60
61
	/**
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
62
	 * Constructor that provides a connection upon which to act and the SQL
1 by edam
- initial commit
63
	 * statement.
22 by edam
updated email and web addresses
64
	 *
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
65
	 * @param connection a reference to a connection
1 by edam
- initial commit
66
	 * @param sql an SQL statement in UTF-8
67
	 */
2 by edam
- further initial development
68
	explicit basic_statement(
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
69
		connection &connection,
1 by edam
- initial commit
70
		const std::string &sql );
71
2 by edam
- further initial development
72
	/**
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
73
	 * Constructor that provides a connection upon which to act.
22 by edam
updated email and web addresses
74
	 *
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
75
	 * @param connection a reference to a connection
2 by edam
- further initial development
76
	 */
77
	explicit basic_statement(
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
78
		connection &connection );
2 by edam
- further initial development
79
9 by edam
- added NEWS
80
	virtual ~basic_statement();
1 by edam
- initial commit
81
82
//______________________________________________________________________________
83
//                                                              public interface
84
public:
85
86
	/**
87
	 * Prepare an SQL statement.
22 by edam
updated email and web addresses
88
	 *
1 by edam
- initial commit
89
	 * @param sql an SQL statement in UTF-8
90
	 * @returns an sqlite error code
91
	 * @see sqlite3_prepare_v2()
92
	 */
2 by edam
- further initial development
93
	virtual int prepare(
1 by edam
- initial commit
94
		const std::string &sql );
95
96
	/**
22 by edam
updated email and web addresses
97
	 * Reset the statement, ready to re-execute it.  This does not clear any of
1 by edam
- initial commit
98
	 * the values bound to the statement.
22 by edam
updated email and web addresses
99
	 *
1 by edam
- initial commit
100
	 * @returns an sqlite error code
101
	 * @see sqlite3_reset()
102
	 */
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
103
	virtual int reset();
1 by edam
- initial commit
104
105
	/**
106
	 * Clears the values bound to a statement to NULL.
22 by edam
updated email and web addresses
107
	 *
1 by edam
- initial commit
108
	 * @returns an sqlite error code
109
	 * @see sqlite3_clear_bindings()
110
	 */
111
	int clear_bindings();
112
113
	/**
22 by edam
updated email and web addresses
114
	 * Bind a value to the SQL statement via it's index.  This template will
115
	 * take a variety of data types and bind them as text.  This is how sqlite
1 by edam
- initial commit
116
	 * internally stores the data anyway, so always binding as text just means
117
	 * we do the conversion instead of sqlite and is no less efficient.
22 by edam
updated email and web addresses
118
	 *
1 by edam
- initial commit
119
	 * @param index the index of the parameter to bind to
120
	 * @param value the value to bind
121
	 * @returns an sqlite error code
122
	 * @see sqlite3_bind_text()
123
	 */
124
	template< class T >
125
	int bind(
126
		unsigned int index,
127
		T value )
128
	{
129
		std::string string_value = boost::lexical_cast< std::string >( value );
130
		return sqlite3_bind_text( _handle, index, string_value.c_str(),
131
			string_value.length(), SQLITE_TRANSIENT );
132
	}
133
134
	/**
135
	 * Bind a string value to the SQL statement via it's index where the value
22 by edam
updated email and web addresses
136
	 * of that string will not change for the duration of the statement.  This
137
	 * is more optimal because sqlite will not have to take it's own copy of the
1 by edam
- initial commit
138
	 * data.
22 by edam
updated email and web addresses
139
	 *
1 by edam
- initial commit
140
	 * @param index the index of the parameter to bind to
141
	 * @param value the invariant string value
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
142
	 * @param value_length the length of the string including zero-terminator
1 by edam
- initial commit
143
	 * @returns an sqlite error code
144
	 * @see sqlite3_bind_text()
145
	 */
146
	int bind_static(
147
		unsigned int index,
148
		const char *value,
149
		unsigned int value_length );
150
151
	/**
152
	 * Bind a string value to the SQL statement via it's index where the value
22 by edam
updated email and web addresses
153
	 * of that string will not change for the duration of the statement.  This
154
	 * is more optimal because sqlite will not have to take it's own copy of the
1 by edam
- initial commit
155
	 * data.
22 by edam
updated email and web addresses
156
	 *
1 by edam
- initial commit
157
	 * @param index the index of the parameter to bind to
158
	 * @param value the invariant string value
159
	 * @returns an sqlite error code
160
	 * @see sqlite3_bind_text()
161
	 */
162
	int bind_static(
163
		unsigned int index,
164
		const char *value );
165
166
	/**
167
	 * Bind a string value to the SQL statement via it's index where the value
22 by edam
updated email and web addresses
168
	 * of that string will not change for the duration of the statement.  This
169
	 * is more optimal because sqlite will not have to take it's own copy of the
1 by edam
- initial commit
170
	 * data.
22 by edam
updated email and web addresses
171
	 *
1 by edam
- initial commit
172
	 * @param index the index of the parameter to bind to
173
	 * @param value the invariant string value
174
	 * @returns an sqlite error code
175
	 * @see sqlite3_bind_text()
176
	 */
177
	int bind_static(
178
		unsigned int index,
179
		const std::string &value );
180
181
	/**
182
	 * Bind a NULL value to the SQL statement via it's index.
22 by edam
updated email and web addresses
183
	 *
1 by edam
- initial commit
184
	 * @param index the index of the parameter to bind to
185
	 * @returns an sqlite error code
186
	 * @see sqlite3_bind_null()
187
	 */
188
	int bind_null(
189
		unsigned int index );
190
191
	/**
22 by edam
updated email and web addresses
192
	 * Bind a value to the SQL statement via a named parameter.  This template
193
	 * will take a variety of data types and bind them as text.  This is how
1 by edam
- initial commit
194
	 * sqlite internally stores the data anyway, so always binding as text just
195
	 * means we do the conversion instead of sqlite and is no less efficient.
22 by edam
updated email and web addresses
196
	 *
1 by edam
- initial commit
197
	 * @param name the named parameter to bind to
198
	 * @param value the value to bind
199
	 * @returns an sqlite error code
200
	 * @see sqlite3_bind_text()
201
	 */
202
	template< class T >
203
	int bind(
204
		const std::string &name,
205
		T value )
206
	{
2 by edam
- further initial development
207
		return bind( bind_parameter_index( name ), value );
1 by edam
- initial commit
208
	}
209
210
	/**
211
	 * Bind a string value to the SQL statement via a named parameter where the
22 by edam
updated email and web addresses
212
	 * string value will not change for the duration of the statement.  This
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
213
	 * prevents sqlite from taking its own copy of the string.
22 by edam
updated email and web addresses
214
	 *
1 by edam
- initial commit
215
	 * @param name the named parameter to bind to
216
	 * @param value the invariant string value
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
217
	 * @param value_length the length of the string including zero-terminator
1 by edam
- initial commit
218
	 * @returns an sqlite error code
219
	 * @see sqlite3_bind_text()
220
	 */
221
	int bind_static(
222
		const std::string &name,
223
		const char *value,
224
		unsigned int value_length );
225
226
	/**
227
	 * Bind a string value to the SQL statement via a named parameter where the
22 by edam
updated email and web addresses
228
	 * string value will not change for the duration of the statement.  This
1 by edam
- initial commit
229
	 * prevents a copy of the string being taken.
22 by edam
updated email and web addresses
230
	 *
1 by edam
- initial commit
231
	 * @param name the named parameter to bind to
232
	 * @param value the invariant string value
233
	 * @returns an sqlite error code
234
	 * @see sqlite3_bind_text()
235
	 */
236
	int bind_static(
237
		const std::string &name,
238
		const char *value );
239
240
	/**
241
	 * Bind a string value to the SQL statement via a named parameter where the
22 by edam
updated email and web addresses
242
	 * string value will not change for the duration of the statement.  This
1 by edam
- initial commit
243
	 * prevents a copy of the string being taken.
22 by edam
updated email and web addresses
244
	 *
1 by edam
- initial commit
245
	 * @param name the named parameter to bind to
246
	 * @param value the invariant string value
247
	 * @returns an sqlite error code
248
	 * @see sqlite3_bind_text()
249
	 */
250
	int bind_static(
251
		const std::string &name,
252
		const std::string &value );
253
254
	/**
255
	 * Bind a NULL value to the SQL statement via a named parameter.
22 by edam
updated email and web addresses
256
	 *
1 by edam
- initial commit
257
	 * @param name the named parameter to bind to
258
	 * @returns an sqlite error code
259
	 * @see sqlite3_bind_null()
260
	 */
261
	int bind_null(
262
		const std::string &name );
263
14 by edam
- moved basic_statement::operator <<() back to basic_statement and just create another specialisation in command so that it can use sqlite::exec
264
	/**
265
	 * Stream operator is used to bind values to parameters automatically, in
22 by edam
updated email and web addresses
266
	 * ascending order.  In addition, the null and set_index() auto-binding
14 by edam
- moved basic_statement::operator <<() back to basic_statement and just create another specialisation in command so that it can use sqlite::exec
267
	 * manipulators can be used.
22 by edam
updated email and web addresses
268
	 *
14 by edam
- moved basic_statement::operator <<() back to basic_statement and just create another specialisation in command so that it can use sqlite::exec
269
	 * @param value a value to bind
270
	 */
271
	template< class T >
272
	basic_statement &operator <<(
273
		const T &value )
274
	{
275
		int code = bind( _bind_index, value );
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
276
		if( code != SQLITE_OK ) throw sqlite_error( _connection, code );
14 by edam
- moved basic_statement::operator <<() back to basic_statement and just create another specialisation in command so that it can use sqlite::exec
277
		_bind_index++;
278
		return *this;
279
	}
280
1 by edam
- initial commit
281
//______________________________________________________________________________
282
//                                                                implementation
283
protected:
284
2 by edam
- further initial development
285
	friend class row;
286
1 by edam
- initial commit
287
	/**
288
	 * Finalise an SQL statement.
22 by edam
updated email and web addresses
289
	 *
1 by edam
- initial commit
290
	 * @returns an sqlite error code
291
	 * @see sqlite3_finalize()
292
	 */
293
	int finalize();
294
2 by edam
- further initial development
295
	/**
22 by edam
updated email and web addresses
296
	 * Get the index number of a named parameter.
297
	 *
2 by edam
- further initial development
298
	 * @param parameter name
299
	 * @return index of named parameter
300
	 */
301
	int bind_parameter_index(
302
		const std::string &name );
1 by edam
- initial commit
303
13 by edam
- made basic_statement::step() protected, for use by query and command only
304
	/**
22 by edam
updated email and web addresses
305
	 * Perform a step.
306
	 *
13 by edam
- made basic_statement::step() protected, for use by query and command only
307
	 * @return sqlite error code
308
	 * @see sqlite3_step()
309
	 */
310
	int step();
311
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
312
	/** the connection upon which to act */
313
	connection &_connection;
1 by edam
- initial commit
314
315
	/** the statement handle */
316
	sqlite3_stmt *_handle;
317
318
	/** index used when auto-binding */
319
	unsigned int _bind_index;
320
321
};
322
323
14 by edam
- moved basic_statement::operator <<() back to basic_statement and just create another specialisation in command so that it can use sqlite::exec
324
// template specialisations for basic_statement::operator <<()
325
template< >
326
basic_statement &basic_statement::operator << < detail::null_t >(
327
	const detail::null_t & );
328
template< >
329
basic_statement &basic_statement::operator << < detail::set_index_t >(
330
	const detail::set_index_t &t );
331
332
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
333
} // namespace detail
334
335
2 by edam
- further initial development
336
} // namespace sqlite
337
338
339
#endif /* SQLITE3CC_BASIC_STATEMENT_H_ */