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