/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
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
/**
51
 * The statement class represents an SQL statement. It is the base class for
52
 * both the command and the query classes, which should be used for those
53
 * purposes. The basic_statement class its self has protected instantiation.
54
 */
55
class basic_statement
1 by edam
- initial commit
56
	:
57
	private boost::noncopyable
58
{
59
//______________________________________________________________________________
60
//                                                                 instantiation
61
protected:
62
63
	/**
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
64
	 * Constructor that provides a connection upon which to act and the SQL
1 by edam
- initial commit
65
	 * statement.
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
66
	 * @param connection a reference to a connection
1 by edam
- initial commit
67
	 * @param sql an SQL statement in UTF-8
68
	 */
2 by edam
- further initial development
69
	explicit basic_statement(
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
70
		connection &connection,
1 by edam
- initial commit
71
		const std::string &sql );
72
2 by edam
- further initial development
73
	/**
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
74
	 * Constructor that provides a connection upon which to act.
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.
88
	 * @param sql an SQL statement in UTF-8
89
	 * @returns an sqlite error code
90
	 * @see sqlite3_prepare_v2()
91
	 */
2 by edam
- further initial development
92
	virtual int prepare(
1 by edam
- initial commit
93
		const std::string &sql );
94
95
	/**
96
	 * Reset the statement, ready to re-execute it. This does not clear any of
97
	 * the values bound to the statement.
98
	 * @returns an sqlite error code
99
	 * @see sqlite3_reset()
100
	 */
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
101
	virtual int reset();
1 by edam
- initial commit
102
103
	/**
104
	 * Clears the values bound to a statement to NULL.
105
	 * @returns an sqlite error code
106
	 * @see sqlite3_clear_bindings()
107
	 */
108
	int clear_bindings();
109
110
	/**
111
	 * Bind a value to the SQL statement via it's index. This template will take
112
	 * a variety of data types and bind them as text. This is how sqlite
113
	 * internally stores the data anyway, so always binding as text just means
114
	 * we do the conversion instead of sqlite and is no less efficient.
115
	 * @param index the index of the parameter to bind to
116
	 * @param value the value to bind
117
	 * @returns an sqlite error code
118
	 * @see sqlite3_bind_text()
119
	 */
120
	template< class T >
121
	int bind(
122
		unsigned int index,
123
		T value )
124
	{
125
		std::string string_value = boost::lexical_cast< std::string >( value );
126
		return sqlite3_bind_text( _handle, index, string_value.c_str(),
127
			string_value.length(), SQLITE_TRANSIENT );
128
	}
129
130
	/**
131
	 * Bind a string value to the SQL statement via it's index where the value
132
	 * of that string will not change for the duration of the statement. This is
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
133
	 * more optimal because sqlite will not have to take it's own copy of the
1 by edam
- initial commit
134
	 * data.
135
	 * @param index the index of the parameter to bind to
136
	 * @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?)
137
	 * @param value_length the length of the string including zero-terminator
1 by edam
- initial commit
138
	 * @returns an sqlite error code
139
	 * @see sqlite3_bind_text()
140
	 */
141
	int bind_static(
142
		unsigned int index,
143
		const char *value,
144
		unsigned int value_length );
145
146
	/**
147
	 * Bind a string value to the SQL statement via it's index where the value
148
	 * of that string will not change for the duration of the statement. This is
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
149
	 * more optimal  because sqlite will not have to take it's own copy of the
1 by edam
- initial commit
150
	 * data.
151
	 * @param index the index of the parameter to bind to
152
	 * @param value the invariant string value
153
	 * @returns an sqlite error code
154
	 * @see sqlite3_bind_text()
155
	 */
156
	int bind_static(
157
		unsigned int index,
158
		const char *value );
159
160
	/**
161
	 * Bind a string value to the SQL statement via it's index where the value
162
	 * of that string will not change for the duration of the statement. This is
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
163
	 * more optimal because sqlite will not have to take it's own copy of the
1 by edam
- initial commit
164
	 * data.
165
	 * @param index the index of the parameter to bind to
166
	 * @param value the invariant string value
167
	 * @returns an sqlite error code
168
	 * @see sqlite3_bind_text()
169
	 */
170
	int bind_static(
171
		unsigned int index,
172
		const std::string &value );
173
174
	/**
175
	 * Bind a NULL value to the SQL statement via it's index.
176
	 * @param index the index of the parameter to bind to
177
	 * @returns an sqlite error code
178
	 * @see sqlite3_bind_null()
179
	 */
180
	int bind_null(
181
		unsigned int index );
182
183
	/**
184
	 * Bind a value to the SQL statement via a named parameter. This template
185
	 * will take a variety of data types and bind them as text. This is how
186
	 * sqlite internally stores the data anyway, so always binding as text just
187
	 * means we do the conversion instead of sqlite and is no less efficient.
188
	 * @param name the named parameter to bind to
189
	 * @param value the value to bind
190
	 * @returns an sqlite error code
191
	 * @see sqlite3_bind_text()
192
	 */
193
	template< class T >
194
	int bind(
195
		const std::string &name,
196
		T value )
197
	{
2 by edam
- further initial development
198
		return bind( bind_parameter_index( name ), value );
1 by edam
- initial commit
199
	}
200
201
	/**
202
	 * Bind a string value to the SQL statement via a named parameter where the
203
	 * 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?)
204
	 * prevents sqlite from taking its own copy of the string.
1 by edam
- initial commit
205
	 * @param name the named parameter to bind to
206
	 * @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?)
207
	 * @param value_length the length of the string including zero-terminator
1 by edam
- initial commit
208
	 * @returns an sqlite error code
209
	 * @see sqlite3_bind_text()
210
	 */
211
	int bind_static(
212
		const std::string &name,
213
		const char *value,
214
		unsigned int value_length );
215
216
	/**
217
	 * Bind a string value to the SQL statement via a named parameter where the
218
	 * string value will not change for the duration of the statement. This
219
	 * prevents a copy of the string being taken.
220
	 * @param name the named parameter to bind to
221
	 * @param value the invariant string value
222
	 * @returns an sqlite error code
223
	 * @see sqlite3_bind_text()
224
	 */
225
	int bind_static(
226
		const std::string &name,
227
		const char *value );
228
229
	/**
230
	 * Bind a string value to the SQL statement via a named parameter where the
231
	 * string value will not change for the duration of the statement. This
232
	 * prevents a copy of the string being taken.
233
	 * @param name the named parameter to bind to
234
	 * @param value the invariant string value
235
	 * @returns an sqlite error code
236
	 * @see sqlite3_bind_text()
237
	 */
238
	int bind_static(
239
		const std::string &name,
240
		const std::string &value );
241
242
	/**
243
	 * Bind a NULL value to the SQL statement via a named parameter.
244
	 * @param name the named parameter to bind to
245
	 * @returns an sqlite error code
246
	 * @see sqlite3_bind_null()
247
	 */
248
	int bind_null(
249
		const std::string &name );
250
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
251
	/**
252
	 * Stream operator is used to bind values to parameters automatically, in
253
	 * ascending order. In addition, the null and set_index() auto-binding
254
	 * manipulators can be used.
255
	 * @param value a value to bind
256
	 */
257
	template< class T >
258
	basic_statement &operator <<(
259
		const T &value )
260
	{
261
		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?)
262
		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
263
		_bind_index++;
264
		return *this;
265
	}
266
1 by edam
- initial commit
267
//______________________________________________________________________________
268
//                                                                implementation
269
protected:
270
2 by edam
- further initial development
271
	friend class row;
272
1 by edam
- initial commit
273
	/**
274
	 * Finalise an SQL statement.
275
	 * @returns an sqlite error code
276
	 * @see sqlite3_finalize()
277
	 */
278
	int finalize();
279
2 by edam
- further initial development
280
	/**
281
	 * Get the index number of a named parameter
282
	 * @param parameter name
283
	 * @return index of named parameter
284
	 */
285
	int bind_parameter_index(
286
		const std::string &name );
1 by edam
- initial commit
287
13 by edam
- made basic_statement::step() protected, for use by query and command only
288
	/**
289
	 * Perform a step
290
	 * @return sqlite error code
291
	 * @see sqlite3_step()
292
	 */
293
	int step();
294
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
295
	/** the connection upon which to act */
296
	connection &_connection;
1 by edam
- initial commit
297
298
	/** the statement handle */
299
	sqlite3_stmt *_handle;
300
301
	/** index used when auto-binding */
302
	unsigned int _bind_index;
303
304
};
305
306
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
307
// template specialisations for basic_statement::operator <<()
308
template< >
309
basic_statement &basic_statement::operator << < detail::null_t >(
310
	const detail::null_t & );
311
template< >
312
basic_statement &basic_statement::operator << < detail::set_index_t >(
313
	const detail::set_index_t &t );
314
315
16 by edam
- renamed database to connection to better identify what it is (would database_connection be better though?)
316
} // namespace detail
317
318
2 by edam
- further initial development
319
} // namespace sqlite
320
321
322
#endif /* SQLITE3CC_BASIC_STATEMENT_H_ */