File: query.h

package info (click to toggle)
mysql%2B%2B 3.0.9-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 11,228 kB
  • ctags: 9,647
  • sloc: cpp: 33,154; sh: 3,098; perl: 778; makefile: 700
file content (1098 lines) | stat: -rw-r--r-- 39,908 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
/// \file query.h
/// \brief Defines a class for building and executing SQL queries.

/***********************************************************************
 Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
 (c) 2004-2008 by Educational Technology Resources, Inc.  Others may
 also hold copyrights on code in this file.  See the CREDITS.txt file
 in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#if !defined(MYSQLPP_QUERY_H)
#define MYSQLPP_QUERY_H

#include "common.h"

#include "noexceptions.h"
#include "qparms.h"
#include "querydef.h"
#include "result.h"
#include "row.h"
#include "stadapter.h"

#include <deque>
#include <iomanip>
#include <list>
#include <map>
#include <set>
#include <vector>

#ifdef HAVE_EXT_SLIST
#  include <ext/slist>
#else
#  if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST)
#      include <slist>
#  endif
#endif

namespace mysqlpp {

#if !defined(DOXYGEN_IGNORE)
// Make Doxygen ignore this
class MYSQLPP_EXPORT Connection;
#endif

/// \brief A class for building and executing SQL queries.
///
/// One does not generally create Query objects directly. Instead, call
/// mysqlpp::Connection::query() to get one tied to that connection.
///
/// There are several ways to build and execute SQL queries with this
/// class.
///
/// The way most like other database libraries is to pass a SQL
/// statement in either the form of a C or C++ string to one of the
/// \link mysqlpp::Query::execute() exec*(), \endlink
/// \link mysqlpp::Query::store() store*(), \endlink or use() methods.
/// The query is executed immediately, and any results returned.
///
/// For more complicated queries, it's often more convenient to build up
/// the query string over several C++ statements using Query's stream
/// interface. It works like any other C++ stream (\c std::cout,
/// \c std::ostringstream, etc.) in that you can just insert things
/// into the stream, building the query up piece by piece. When the
/// query string is complete, you  call the overloaded version of
/// \link mysqlpp::Query::execute() exec*(), \endlink
/// \link mysqlpp::Query::store() store*(), \endlink or
/// \link mysqlpp::Query::use() use() \endlink takes no parameters,
/// which executes the built query and returns any results.
///
/// If you are using the library's Specialized SQL Structures feature,
/// Query has several special functions for generating common SQL
/// queries from those structures. For instance, it offers the
/// \link mysqlpp::Query::insert() insert() \endlink method, which
/// builds an INSERT query to add the contents of the SSQLS to the
/// database. As with the stream interface, these methods only build
/// the query string; call one of the parameterless methods mentioned
/// previously to actually execute the query.
///
/// Finally, you can build "template queries". This is something like
/// C's \c printf() function, in that you insert a specially-formatted
/// query string into the object which contains placeholders for data.
/// You call the parse() method to tell the Query object that the query
/// string contains placeholders. Having done that, you call one of the
/// the many
/// \link mysqlpp::Query::execute(const SQLTypeAdapter&) exec*(), \endlink
/// \link mysqlpp::Query::store(const SQLTypeAdapter&) store*(), \endlink
/// or \link mysqlpp::Query::use(const SQLTypeAdapter&) use() \endlink
/// overloads that take SQLTypeAdapter objects.  There are 25 of each by
/// default, differing only in the number of STA objects they take.
/// (See \c lib/querydef.pl if you need to change the limit, or 
/// \c examples/tquery2.cpp for a way around it that doesn't require 
/// changing the library.)  Only the version taking a single STA object
/// is documented below, as to document all of them would just be
/// repetitive.  For each Query method that takes a single STA object,
/// there's a good chance there's a set of undocumented overloads that
/// take more of them for the purpose of filling out a template query.
///
/// See the user manual for more details about these options.

class MYSQLPP_EXPORT Query :
		public std::ostream,
		public OptionalExceptions
{
public:
	/// \brief Create a new query object attached to a connection.
	///
	/// This is the constructor used by mysqlpp::Connection::query().
	///
	/// \param c connection the finished query should be sent out on
	/// \param te if true, throw exceptions on errors
	/// \param qstr an optional initial query string
	Query(Connection* c, bool te = true, const char* qstr = 0);

	/// \brief Create a new query object as a copy of another.
	///
	/// This is \b not a traditional copy ctor!  Its only purpose is to
	/// make it possible to assign the return of Connection::query()
	/// to an empty Query object.  In particular, the stream buffer and
	/// template query stuff will be empty in the copy, regardless of
	/// what values they have in the original.
	Query(const Query& q);

	/// \brief Return the number of rows affected by the last query
	ulonglong affected_rows();

	/// \brief Return a SQL-escaped version of a character buffer
	///
	/// \param ps pointer to C++ string to hold escaped version; if
	/// original is 0, also holds the original data to be escaped
	/// \param original if given, pointer to the character buffer to
	/// escape instead of contents of *ps
	/// \param length if both this and original are given, number of
	/// characters to escape instead of ps->length()
	///
	/// \retval number of characters placed in *ps
	///
	/// This method has three basic operation modes:
	///
	/// - Pass just a pointer to a C++ string containing the original
	///   data to escape, plus act as receptacle for escaped version
	/// - Pass a pointer to a C++ string to receive escaped string plus
	///   a pointer to a C string to be escaped
	/// - Pass nonzero for all parameters, taking original to be a
	///   pointer to an array of char with given length; does not treat
	///   null characters as special
	///
	/// There's a degenerate fourth mode, where ps is zero: simply
	/// returns 0, because there is nowhere to store the result.
	///
	/// Note that if original is 0, we always ignore the length
	/// parameter even if it is nonzero.  Length always comes from
	/// ps->length() in this case.
	///
	/// ps is a pointer because if it were a reference, the other
	/// overload would be impossible to call: the compiler would
	/// complain that the two overloads are ambiguous because
	/// std::string has a char* conversion ctor. A nice bonus is that
	/// pointer syntax makes it clearer that the first parameter is an
	/// "out" parameter.
	///
	/// \see comments for escape_string(char*, const char*, size_t)
	/// for further details.
	size_t escape_string(std::string* ps, const char* original = 0,
			size_t length = 0) const;

	/// \brief Return a SQL-escaped version of the given character
	/// buffer
	///
	/// \param escaped character buffer to hold escaped version; must
	/// point to at least (length * 2 + 1) bytes
	/// \param original pointer to the character buffer to escape
	/// \param length number of characters to escape
	///
	/// \retval number of characters placed in escaped
	///
	/// This is part of Query because proper SQL escaping takes the
	/// database's current character set into account, which requires
	/// access to the Connection object the query will go out on.  Also,
	/// this function is very important to MySQL++'s Query stream
	/// manipulator mechanism, so it's more convenient for this method
	/// to live in Query rather than Connection.
	size_t escape_string(char* escaped, const char* original,
			size_t length) const;

	/// \brief Get the last error number that was set.
	///
	/// This just delegates to Connection::errnum().  Query has nothing
	/// extra to say, so use either, as makes sense in your program.
	int errnum() const;

	/// \brief Get the last error message that was set.
	///
	/// This just delegates to Connection::error().  Query has nothing
	/// extra to say, so use either, as makes sense in your program.
	const char* error() const;

	/// \brief Returns information about the most recently executed
	/// query.
	std::string info();

	/// \brief Get ID generated for an AUTO_INCREMENT column in the
	/// previous INSERT query.
	///
	/// \retval 0 if the previous query did not generate an ID.  Use
	/// the SQL function LAST_INSERT_ID() if you need the last ID
	/// generated by any query, not just the previous one.  This
	/// applies to stored procedure calls because this function returns
	/// the ID generated by the last query, which was a CALL statement,
	/// and CALL doesn't generate IDs.  You need to use LAST_INSERT_ID()
	/// to get the ID in this case.
	ulonglong insert_id();

	/// \brief Assign another query's state to this object
	///
	/// The same caveats apply to this operator as apply to the copy
	/// ctor.
	Query& operator=(const Query& rhs);

	/// \brief Test whether the object has experienced an error condition
	///
	/// Allows for code constructs like this:
	///
	/// \code
	///	Query q = conn.query();
	///	.... use query object
	///	if (q) {
	///	    ... no problems in using query object
	///	}
	///	else {
	///	    ... an error has occurred
	///	}
	/// \endcode
	///
	/// This method returns false if either the Query object or its
	/// associated Connection object has seen an error condition since
	/// the last operation.
	operator void*() const;

	/// \brief Treat the contents of the query string as a template
	/// query.
	///
	/// This method sets up the internal structures used by all of the
	/// other members that accept template query parameters.  See the
	/// "Template Queries" chapter in the user manual for more
	/// information.
	void parse();

	/// \brief Reset the query object so that it can be reused.
	///
	/// As of v3.0, Query objects auto-reset upon query execution unless
	/// you've set it up for making template queries.  (It can't auto-reset
	/// in that situation, because it would forget the template info.)
	/// Therefore, the only time you must call this is if you have a Query
	/// object set up for making template queries, then want to build
	/// queries using one of the other methods.  (Static strings, SSQLS,
	/// or the stream interface.)
	void reset();

	/// \brief Get built query as a C++ string
	std::string str() { return str(template_defaults); }

	/// \brief Get built query as a C++ string with template query
	/// parameter substitution.
	///
	/// \param arg0 the value to substitute for the first template query
	/// parameter; because SQLTypeAdapter implicitly converts from many
	/// different data types, this method is very flexible in what it
	/// accepts as a parameter.  You shouldn't have to use the
	/// SQLTypeAdapter data type directly in your code.
	///
	/// There many more overloads of this type (25 total, by default;
	/// see \c lib/querydef.pl), each taking one more SQLTypeAdapter object
	/// than the previous one.  See the template query overview above
	/// for more about this topic.
	std::string str(const SQLTypeAdapter& arg0)
			{ return str(SQLQueryParms() << arg0); }

	/// \brief Get built query as a null-terminated C++ string
	///
	/// \param p template query parameters to use, overriding the ones
	/// this object holds, if any
	std::string str(SQLQueryParms& p);

	/// \brief Execute a built-up query
	///
	/// Same as exec(), except that it uses the query string built up
	/// within the query object already instead of accepting a query
	/// string from the caller.
	///
	/// \return true if query was executed successfully
	///
	/// \sa exec(const std::string& str), execute(), store(),
	/// storein(), and use()
	bool exec() { return exec(str(template_defaults)); }

	/// \brief Execute a query
	///
	/// Same as execute(), except that it only returns a flag indicating
	/// whether the query succeeded or not.  It is basically a thin
	/// wrapper around the C API function \c mysql_real_query().
	///
	/// \param str the query to execute
	///
	/// \return true if query was executed successfully
	///
	/// \sa execute(), store(), storein(), and use()
	bool exec(const std::string& str);

	/// \brief Execute built-up query
	///
	/// Use one of the execute() overloads if you don't expect the
	/// server to return a result set. For instance, a DELETE query.
	/// The returned SimpleResult object contains status information from
	/// the server, such as whether the query succeeded, and if so how
	/// many rows were affected.
	///
	/// This overloaded version of execute() simply executes the query
	/// that you have built up in the object in some way. (For instance,
	/// via the insert() method, or by using the object's stream
	/// interface.)
	///
	/// \return SimpleResult status information about the query
	///
	/// \sa exec(), store(), storein(), and use()
	SimpleResult execute() { return execute(str(template_defaults)); }

	/// \brief Execute template query using given parameters.
	///
	/// This method should only be used by code that doesn't know,
	/// at compile time, how many parameters it will have.  This is
	/// useful within the library, and also for code that builds
	/// template queries dynamically, at run time.
	///
	/// \param p parameters to use in the template query.
	SimpleResult execute(SQLQueryParms& p);

	/// \brief Execute a query that returns no rows
	///
	/// \param str if this object is set up as a template query, this is
	/// the value to substitute for the first template query parameter;
	/// else, it is the SQL query string to execute
	///
	/// Because SQLTypeAdapter can be initialized from either a C string
	/// or a C++ string, this overload accepts query strings in either
	/// form.  Beware, SQLTypeAdapter also accepts many other data types
	/// (this is its \e raison \e d'etre), so it will let you write code
	/// that compiles but results in bogus SQL queries.
	///
	/// To support template queries, there many more overloads of this
	/// type (25 total, by default; see \c lib/querydef.pl), each taking
	/// one more SQLTypeAdapter object than the previous one.  See the
	/// template query overview above for more about this topic.
	SimpleResult execute(const SQLTypeAdapter& str);

	/// \brief Execute query in a known-length string of characters.
	/// This can include null characters.
	///
	/// Executes the query immediately, and returns the results.
	SimpleResult execute(const char* str, size_t len);

	/// \brief Execute a query that can return rows, with access to
	/// the rows in sequence
	/// 
	/// Use one of the use() overloads if memory efficiency is
	/// important.  They return an object that can walk through
	/// the result records one by one, without fetching the entire
	/// result set from the server.  This is superior to store()
	/// when there are a large number of results; store() would have to
	/// allocate a large block of memory to hold all those records,
	/// which could cause problems.
	///
	/// A potential downside of this method is that MySQL database
	/// resources are tied up until the result set is completely
	/// consumed.  Do your best to walk through the result set as
	/// expeditiously as possible.
	///
	/// The name of this method comes from the MySQL C API function
	/// that initiates the retrieval process, \c mysql_use_result().
	/// This method is implemented in terms of that function.
	///
	/// This function has the same set of overloads as execute().
	///
	/// \return UseQueryResult object that can walk through result set serially
	///
	/// \sa exec(), execute(), store() and storein()
	UseQueryResult use() { return use(str(template_defaults)); }

	/// \brief Execute a template query that can return rows, with
	/// access to the rows in sequence
	///
	/// This method should only be used by code that doesn't know,
	/// at compile time, how many parameters it will have.  This is
	/// useful within the library, and also for code that builds
	/// template queries dynamically, at run time.
	///
	/// \param p parameters to use in the template query.
	UseQueryResult use(SQLQueryParms& p);

	/// \brief Execute a query that can return rows, with access to
	/// the rows in sequence
	///
	/// \param str if this object is set up as a template query, this is
	/// the value to substitute for the first template query parameter;
	/// else, it is the SQL query string to execute
	///
	/// Because SQLTypeAdapter can be initialized from either a C string
	/// or a C++ string, this overload accepts query strings in either
	/// form.  Beware, SQLTypeAdapter also accepts many other data types
	/// (this is its \e raison \e d'etre), so it will let you write code
	/// that compiles but results in bogus SQL queries.
	///
	/// To support template queries, there many more overloads of this
	/// type (25 total, by default; see \c lib/querydef.pl), each taking
	/// one more SQLTypeAdapter object than the previous one.  See the
	/// template query overview above for more about this topic.
	UseQueryResult use(const SQLTypeAdapter& str);

	/// \brief Execute a query that can return rows, with access to
	/// the rows in sequence
	///
	/// This overload is for situations where you have the query in a
	/// C string and have its length already.  If you want to execute
	/// a query in a null-terminated C string or have the query string
	/// in some other form, you probably want to call
	/// use(const SQLTypeAdapter&) instead.  SQLTypeAdapter converts
	/// from plain C strings and other useful data types implicitly.
	UseQueryResult use(const char* str, size_t len);

	/// \brief Execute a query that can return a result set
	///
	/// Use one of the store() overloads to execute a query and retrieve
	/// the entire result set into memory.  This is useful if you
	/// actually need all of the records at once, but if not, consider
	/// using one of the use() methods instead, which returns the results
	/// one at a time, so they don't allocate as much memory as store().
	///
	/// You must use store(), storein() or use() for \c SELECT, \c SHOW,
	/// \c DESCRIBE and \c EXPLAIN queries.  You can use these functions
	/// with other query types, but since they don't return a result
	/// set, exec() and execute() are more efficient.
	///
	/// The name of this method comes from the MySQL C API function it
	/// is implemented in terms of, \c mysql_store_result().
	///
	/// This function has the same set of overloads as execute().
	///
	/// \return StoreQueryResult object containing entire result set
	///
	/// \sa exec(), execute(), storein(), and use()
	StoreQueryResult store() { return store(str(template_defaults)); }

	/// \brief Store results from a template query using given parameters.
	///
	/// This method should only be used by code that doesn't know,
	/// at compile time, how many parameters it will have.  This is
	/// useful within the library, and also for code that builds
	/// template queries dynamically, at run time.
	///
	/// \param p parameters to use in the template query.
	StoreQueryResult store(SQLQueryParms& p);

	/// \brief Execute a query that can return rows, returning all
	/// of the rows in a random-access container
	///
	/// \param str if this object is set up as a template query, this is
	/// the value to substitute for the first template query parameter;
	/// else, it is the SQL query string to execute
	///
	/// Because SQLTypeAdapter can be initialized from either a C string
	/// or a C++ string, this overload accepts query strings in either
	/// form.  Beware, SQLTypeAdapter also accepts many other data types
	/// (this is its \e raison \e d'etre), so it will let you write code
	/// that compiles but results in bogus SQL queries.
	///
	/// To support template queries, there many more overloads of this
	/// type (25 total, by default; see \c lib/querydef.pl), each taking
	/// one more SQLTypeAdapter object than the previous one.  See the
	/// template query overview above for more about this topic.
	StoreQueryResult store(const SQLTypeAdapter& str);

	/// \brief Execute a query that can return rows, returning all
	/// of the rows in a random-access container
	///
	/// This overload is for situations where you have the query in a
	/// C string and have its length already.  If you want to execute
	/// a query in a null-terminated C string or have the query string
	/// in some other form, you probably want to call
	/// store(const SQLTypeAdapter&) instead.  SQLTypeAdapter converts
	/// from plain C strings and other useful data types implicitly.
	StoreQueryResult store(const char* str, size_t len);

	/// \brief Execute a query, and call a functor for each returned row
	///
	/// This method wraps a use() query, calling the given functor for
	/// every returned row.  It is analogous to STL's for_each()
	/// algorithm, but instead of iterating over some range within a
	/// container, it iterates over a result set produced by a query.
	///
	/// \param query the query string
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <typename Function>
	Function for_each(const SQLTypeAdapter& query, Function fn)
	{	
		mysqlpp::UseQueryResult res = use(query);
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				fn(row);
			}
		}

		return fn;
	}

	/// \brief Execute the query, and call a functor for each returned row
	///
	/// Just like for_each(const SQLTypeAdapter&, Function), but it uses
	/// the query string held by the Query object already
	///
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <typename Function>
	Function for_each(Function fn)
	{	
		mysqlpp::UseQueryResult res = use();
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				fn(row);
			}
		}

		return fn;
	}

	/// \brief Run a functor for every row in a table
	///
	/// Just like for_each(Function), except that it builds a
	/// "select * from TABLE" query using the SQL table name from
	/// the SSQLS instance you pass.
	///
	/// \param ssqls the SSQLS instance to get a table name from
	/// \param fn the functor called for each row
	///
	/// \return a copy of the passed functor
	template <class SSQLS, typename Function>
	Function for_each(const SSQLS& ssqls, Function fn)
	{	
		std::string query("select * from ");
		query += ssqls.table();
		mysqlpp::UseQueryResult res = use(query);
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				fn(row);
			}
		}

		return fn;
	}

	/// \brief Execute a query, conditionally storing each row in a
	/// container
	///
	/// This method wraps a use() query, calling the given functor for
	/// every returned row, and storing the results in the given
	/// sequence container if the functor returns true.
	///
	/// This is analogous to the STL copy_if() algorithm, except that
	/// the source rows come from a database query instead of another
	/// container.  (copy_if() isn't a standard STL algorithm, but only
	/// due to an oversight by the standardization committee.)  This
	/// fact may help you to remember the order of the parameters: the
	/// container is the destination, the query is the source, and the
	/// functor is the predicate; it's just like an STL algorithm.
	///
	/// \param con the destination container; needs a push_back() method
	/// \param query the query string
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <class Sequence, typename Function>
	Function store_if(Sequence& con, const SQLTypeAdapter& query, Function fn)
	{	
		mysqlpp::UseQueryResult res = use(query);
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				if (fn(row)) {
					con.push_back(row);
				}
			}
		}

		return fn;
	}

	/// \brief Pulls every row in a table, conditionally storing each
	/// one in a container
	///
	/// Just like store_if(Sequence&, const SQLTypeAdapter&, Function), but
	/// it uses the SSQLS instance to construct a "select * from TABLE"
	/// query, using the table name field in the SSQLS.
	///
	/// \param con the destination container; needs a push_back() method
	/// \param ssqls the SSQLS instance to get a table name from
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <class Sequence, class SSQLS, typename Function>
	Function store_if(Sequence& con, const SSQLS& ssqls, Function fn)
	{	
		std::string query("select * from ");
		query += ssqls.table();
		mysqlpp::UseQueryResult res = use(query);
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				if (fn(row)) {
					con.push_back(row);
				}
			}
		}

		return fn;
	}

	/// \brief Execute the query, conditionally storing each row in a
	/// container
	///
	/// Just like store_if(Sequence&, const SQLTypeAdapter&, Function), but
	/// it uses the query string held by the Query object already
	///
	/// \param con the destination container; needs a push_back() method
	/// \param fn the functor called for each row
	/// \return a copy of the passed functor
	template <class Sequence, typename Function>
	Function store_if(Sequence& con, Function fn)
	{	
		mysqlpp::UseQueryResult res = use();
		if (res) {
			mysqlpp::NoExceptions ne(res);
			while (mysqlpp::Row row = res.fetch_row()) {
				if (fn(row)) {
					con.push_back(row);
				}
			}
		}

		return fn;
	}

	/// \brief Return next result set, when processing a multi-query
	///
	/// There are two cases where you'd use this function instead of
	/// the regular store() functions.
	/// 
	/// First, when handling the result of executing multiple queries
	/// at once.  (See <a
	/// href="http://dev.mysql.com/doc/mysql/en/c-api-multiple-queries.html">this
	/// page</a> in the MySQL documentation for details.) 
	///
	/// Second, when calling a stored procedure, MySQL can return the
	/// result as a set of results.
	///
	/// In either case, you must consume all results before making
	/// another MySQL query, even if you don't care about the remaining
	/// results or result sets.
	///
	/// As the MySQL documentation points out, you must set the
	/// MYSQL_OPTION_MULTI_STATEMENTS_ON flag on the connection in order
	/// to use this feature.  See Connection::set_option().
	///
	/// Multi-queries only exist in MySQL v4.1 and higher.  Therefore,
	/// this function just wraps store() when built against older API
	/// libraries.
	///
	/// \return StoreQueryResult object containing the next result set.
	StoreQueryResult store_next();

	/// \brief Return whether more results are waiting for a multi-query
	/// or stored procedure response.
	///
	/// If this function returns true, you must call store_next() to
	/// fetch the next result set before you can execute more queries.
	///
	/// Wraps mysql_more_results() in the MySQL C API.  That function
	/// only exists in MySQL v4.1 and higher.  Therefore, this function
	/// always returns false when built against older API libraries.
	///
	/// \return true if another result set exists
	bool more_results();

	/// \brief Execute a query, storing the result set in an STL
	/// sequence container.
	///
	/// This function works much like store() from the caller's
	/// perspective, because it returns the entire result set at once.
	/// It's actually implemented in terms of use(), however, so that
	/// memory for the result set doesn't need to be allocated twice.
	///
	/// There are many overloads for this function, pretty much the same
	/// as for execute(), except that there is a Container parameter at
	/// the front of the list.  So, you can pass a container and a query
	/// string, or a container and template query parameters.
	///
	/// \param con any STL sequence container, such as \c std::vector
	///
	/// \sa exec(), execute(), store(), and use()
	template <class Sequence>
	void storein_sequence(Sequence& con)
	{
		storein_sequence(con, str(template_defaults));
	}

	/// \brief Executes a query, storing the result rows in an STL
	/// sequence container.
	///
	/// \param con the container to store the results in
	///
	/// \param s if Query is set up as a template query, this is the value
	/// to substitute for the first template query parameter; else, the
	/// SQL query string
	///
	/// There many more overloads of this type (25 total, by default;
	/// see \c lib/querydef.pl), each taking one more SQLTypeAdapter object
	/// than the previous one.  See the template query overview above
	/// for more about this topic.
	template <class Sequence>
	void storein_sequence(Sequence& con, const SQLTypeAdapter& s)
	{
		UseQueryResult result = use(s);
		while (1) {
			MYSQL_ROW d = result.fetch_raw_row();
			if (!d)
				break;
			Row row(d, &result, result.fetch_lengths(),
					throw_exceptions());
			if (!row)
				break;
			con.push_back(typename Sequence::value_type(row));
		}
	}

	/// \brief Execute template query using given parameters, storing
	/// the results in a sequence type container.
	///
	/// This method should only be used by code that doesn't know,
	/// at compile time, how many parameters it will have.  This is
	/// useful within the library, and also for code that builds
	/// template queries dynamically, at run time.
	///
	/// \param con container that will receive the results
	/// \param p parameters to use in the template query.
	template <class Seq>
	void storein_sequence(Seq& con, SQLQueryParms& p)
	{
		storein_sequence(con, str(p));
	}

	/// \brief Execute a query, storing the result set in an STL
	/// associative container.
	///
	/// The same thing as storein_sequence(), except that it's used with
	/// associative STL containers, such as \c std::set.  Other than
	/// that detail, that method's comments apply equally well to this
	/// one.
	template <class Set>
	void storein_set(Set& con)
	{
		storein_set(con, str(template_defaults));
	}

	/// \brief Executes a query, storing the result rows in an STL
	/// set-associative container.
	///
	/// \param con the container to store the results in
	///
	/// \param s if Query is set up as a template query, this is the value
	/// to substitute for the first template query parameter; else, the
	/// SQL query string
	///
	/// There many more overloads of this type (25 total, by default;
	/// see \c lib/querydef.pl), each taking one more SQLTypeAdapter object
	/// than the previous one.  See the template query overview above
	/// for more about this topic.
	template <class Set>
	void storein_set(Set& con, const SQLTypeAdapter& s)
	{
		UseQueryResult result = use(s);
		while (1) {
			MYSQL_ROW d = result.fetch_raw_row();
			if (!d)
				return;
			Row row(d, &result, result.fetch_lengths(),
					throw_exceptions());
			if (!row)
				break;
			con.insert(typename Set::value_type(row));
		}
	}

	/// \brief Execute template query using given parameters, storing
	/// the results in a set type container.
	///
	/// This method should only be used by code that doesn't know,
	/// at compile time, how many parameters it will have.  This is
	/// useful within the library, and also for code that builds
	/// template queries dynamically, at run time.
	///
	/// \param con container that will receive the results
	/// \param p parameters to use in the template query.
	template <class Set>
	void storein_set(Set& con, SQLQueryParms& p)
	{
		storein_set(con, str(p));
	}

	/// \brief Execute a query, and store the entire result set
	/// in an STL container.
	///
	/// This is a set of specialized template functions that call either
	/// storein_sequence() or storein_set(), depending on the type of
	/// container you pass it. It understands \c std::vector, \c deque,
	/// \c list, \c slist (a common C++ library extension), \c set,
	/// and \c multiset.
	///
	/// Like the functions it wraps, this is actually an overloaded set
	/// of functions. See the other functions' documentation for details.
	///
	/// Use this function if you think you might someday switch your
	/// program from using a set-associative container to a sequence
	/// container for storing result sets, or vice versa.
	///
	/// See exec(), execute(), store(), and use() for alternative
	/// query execution mechanisms.
	template <class Container>
	void storein(Container& con)
	{
		storein(con, str(template_defaults));
	}

	/// \brief Store template query results into a container
	///
	/// This method is not intended to be used directly.  It is part
	/// of the call chain in processing calls to one of the many
	/// storein() overloads that take a container and one or more
	/// SQLTypeAdapter parameters.
	template <class T>
	void storein(T& con, SQLQueryParms& p)
	{
		storein(con, str(p));
	}

	/// \brief Specialization of storein_sequence() for \c std::vector
	template <class T>
	void storein(std::vector<T>& con, const SQLTypeAdapter& s)
	{
		storein_sequence(con, s);
	}

	/// \brief Specialization of storein_sequence() for \c std::deque
	template <class T>
	void storein(std::deque<T>& con, const SQLTypeAdapter& s)
	{
		storein_sequence(con, s);
	}

	/// \brief Specialization of storein_sequence() for \c std::list
	template <class T>
	void storein(std::list<T>& con, const SQLTypeAdapter& s)
	{
		storein_sequence(con, s);
	}

#if defined(HAVE_EXT_SLIST)
	/// \brief Specialization of storein_sequence() for g++ STL
	/// extension \c slist
	template <class T>
	void storein(__gnu_cxx::slist<T>& con, const SQLTypeAdapter& s)
	{
		storein_sequence(con, s);
	}
#elif defined(HAVE_GLOBAL_SLIST)
	/// \brief Specialization of storein_sequence() for STL
	/// extension \c slist
	///
	/// This is primarily for older versions of g++, which put \c slist
	/// in the global namespace.  This is a common language extension,
	/// so this may also work for other compilers.
	template <class T>
	void storein(slist<T>& con, const SQLTypeAdapter& s)
	{
		storein_sequence(con, s);
	}
#elif defined(HAVE_STD_SLIST)
	/// \brief Specialization of storein_sequence() for STL
	/// extension \c slist
	///
	/// This is for those benighted compilers that include an \c slist
	/// implementation, but erroneously put it in the \c std namespace!
	template <class T>
	void storein(std::slist<T>& con, const SQLTypeAdapter& s)
	{
		storein_sequence(con, s);
	}
#endif

	/// \brief Specialization of storein_set() for \c std::set
	template <class T>
	void storein(std::set<T>& con, const SQLTypeAdapter& s)
	{
		storein_set(con, s);
	}

	/// \brief Specialization of storein_set() for \c std::multiset
	template <class T>
	void storein(std::multiset<T>& con, const SQLTypeAdapter& s)
	{
		storein_set(con, s);
	}

	/// \brief Replace an existing row's data with new data.
	///
	/// This function builds an UPDATE SQL query using the new row data
	/// for the SET clause, and the old row data for the WHERE clause.
	/// One uses it with MySQL++'s Specialized SQL Structures mechanism.
	///
	/// \param o old row
	/// \param n new row
	///
	/// \sa insert(), replace()
	template <class T>
	Query& update(const T& o, const T& n)
	{
		reset();

		// Cast required for VC++ 2003 due to error in overloaded operator
		// lookup logic.  For an explanation of the problem, see:
		// http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
		MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
				"UPDATE " << o.table() << " SET " << n.equal_list() <<
				" WHERE " << o.equal_list(" AND ", sql_use_compare);
		return *this;
	}

	/// \brief Insert a new row.
	///
	/// This function builds an INSERT SQL query.  One uses it with
	/// MySQL++'s Specialized SQL Structures mechanism.
	///
	/// \param v new row
	///
	/// \sa replace(), update()
	template <class T>
	Query& insert(const T& v)
	{
		reset();

		MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
				"INSERT INTO " << v.table() << " (" <<
				v.field_list() << ") VALUES (" <<
				v.value_list() << ')';
		return *this;
	}

	/// \brief Insert multiple new rows.
	///
	/// Builds an INSERT SQL query using items from a range within an
	/// STL container.  Insert the entire contents of the container by
	/// using the begin() and end() iterators of the container as
	/// parameters to this function.
	///
	/// \param first iterator pointing to first element in range to
	///    insert
	/// \param last iterator pointing to one past the last element to
	///    insert
	///
	/// \sa replace(), update()
	template <class Iter>
	Query& insert(Iter first, Iter last)
	{
		reset();
		if (first == last) {
			return *this;	// empty set!
		}
		
		MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
				"INSERT INTO " << first->table() << " (" <<
				first->field_list() << ") VALUES (" <<
				first->value_list() << ')';

		Iter it = first + 1;
		while (it != last) {
			MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
			++it;
		}

		return *this;
	}

	/// \brief Insert new row unless there is an existing row that
	/// matches on a unique index, in which case we replace it.
	///
	/// This function builds a REPLACE SQL query.  One uses it with
	/// MySQL++'s Specialized SQL Structures mechanism.
	///
	/// \param v new row
	///
	/// \sa insert(), update()
	template <class T>
	Query& replace(const T& v)
	{
		reset();

		MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
				"REPLACE INTO " << v.table() << " (" <<
				v.field_list() << ") VALUES (" << v.value_list() << ')';
		return *this;
	}

#if !defined(DOXYGEN_IGNORE)
	// Declare the remaining overloads.  These are hidden down here partly
	// to keep the above code clear, but also so that we may hide them
	// from Doxygen, which gets confused by macro instantiations that look
	// like method declarations.
	mysql_query_define0(std::string, str)
	mysql_query_define0(SimpleResult, execute)
	mysql_query_define0(StoreQueryResult, store)
	mysql_query_define0(UseQueryResult, use)
	mysql_query_define1(storein_sequence)
	mysql_query_define1(storein_set)
	mysql_query_define1(storein)
#endif // !defined(DOXYGEN_IGNORE)

	/// \brief The default template parameters
	///
	/// Used for filling in parameterized queries.
	SQLQueryParms template_defaults;

private:
	friend class SQLQueryParms;

	/// \brief Connection to send queries through
	Connection* conn_;

	/// \brief If true, last query succeeded
	bool copacetic_;

	/// \brief List of template query parameters
	std::vector<SQLParseElement> parse_elems_;

	/// \brief Maps template parameter position values to the
	/// corresponding parameter name.
	std::vector<std::string> parsed_names_;

	/// \brief Maps template parameter names to their position value.
	std::map<std::string, short int> parsed_nums_;

	/// \brief String buffer for storing assembled query
	std::stringbuf sbuffer_;

	/// \brief Process a parameterized query list.
	void proc(SQLQueryParms& p);

	SQLTypeAdapter* pprepare(char option, SQLTypeAdapter& S, bool replace = true);
};


/// \brief Insert raw query string into the given stream.
///
/// This is just syntactic sugar for Query::str(void)
inline std::ostream& operator <<(std::ostream& os, Query& q)
{
	return os << q.str();
}


} // end namespace mysqlpp

#endif // !defined(MYSQLPP_QUERY_H)