@@ -73,23 +73,15 @@ namespace sqlite {
73
73
_stmt (std::move(other._stmt)),
74
74
_inx (other._inx), execution_started(other.execution_started) { }
75
75
76
- void reset () {
77
- sqlite3_reset (_stmt.get ());
78
- sqlite3_clear_bindings (_stmt.get ());
79
- _inx = 1 ;
80
- used (false );
81
- }
82
-
83
76
void execute () {
77
+ _start_execute ();
84
78
int hresult;
85
- used (true ); /* prevent from executing again when goes out of scope */
86
79
87
80
while ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {}
88
81
89
82
if (hresult != SQLITE_DONE) {
90
83
errors::throw_sqlite_error (hresult, sql ());
91
84
}
92
-
93
85
}
94
86
95
87
std::string sql () {
@@ -107,8 +99,10 @@ namespace sqlite {
107
99
}
108
100
109
101
void used (bool state) {
110
- if (execution_started == true && state == true ) {
111
- throw errors::reexecution (" Already used statement executed again! Please reset() first!" ,sql ());
102
+ if (!state) {
103
+ // We may have to reset first if we haven't done so already:
104
+ _next_index ();
105
+ --_inx;
112
106
}
113
107
execution_started = state;
114
108
}
@@ -123,9 +117,22 @@ namespace sqlite {
123
117
124
118
bool execution_started = false ;
125
119
120
+ int _next_index () {
121
+ if (execution_started && !_inx) {
122
+ sqlite3_reset (_stmt.get ());
123
+ sqlite3_clear_bindings (_stmt.get ());
124
+ }
125
+ return ++_inx;
126
+ }
127
+ void _start_execute () {
128
+ _next_index ();
129
+ _inx = 0 ;
130
+ used (true );
131
+ }
132
+
126
133
void _extract (std::function<void (void )> call_back) {
127
134
int hresult;
128
- used ( true );
135
+ _start_execute ( );
129
136
130
137
while ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
131
138
call_back ();
@@ -138,7 +145,7 @@ namespace sqlite {
138
145
139
146
void _extract_single_value (std::function<void (void )> call_back) {
140
147
int hresult;
141
- used ( true );
148
+ _start_execute ( );
142
149
143
150
if ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
144
151
call_back ();
@@ -243,13 +250,13 @@ namespace sqlite {
243
250
database_binder (std::shared_ptr<sqlite3> db, std::u16string const & sql):
244
251
_db (db),
245
252
_stmt (_prepare(sql), sqlite3_finalize),
246
- _inx (1 ) {
253
+ _inx (0 ) {
247
254
}
248
255
249
256
database_binder (std::shared_ptr<sqlite3> db, std::string const & sql):
250
257
_db (db),
251
258
_stmt (_prepare(sql), sqlite3_finalize),
252
- _inx (1 ) {
259
+ _inx (0 ) {
253
260
}
254
261
255
262
~database_binder () noexcept (false ) {
@@ -515,10 +522,9 @@ namespace sqlite {
515
522
// int
516
523
inline database_binder& operator <<(database_binder& db, const int & val) {
517
524
int hresult;
518
- if ((hresult = sqlite3_bind_int (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
525
+ if ((hresult = sqlite3_bind_int (db._stmt .get (), db._next_index () , val)) != SQLITE_OK) {
519
526
errors::throw_sqlite_error (hresult, db.sql ());
520
527
}
521
- ++db._inx ;
522
528
return db;
523
529
}
524
530
inline void store_result_in_db (sqlite3_context* db, const int & val) {
@@ -542,11 +548,10 @@ namespace sqlite {
542
548
// sqlite_int64
543
549
inline database_binder& operator <<(database_binder& db, const sqlite_int64& val) {
544
550
int hresult;
545
- if ((hresult = sqlite3_bind_int64 (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
551
+ if ((hresult = sqlite3_bind_int64 (db._stmt .get (), db._next_index () , val)) != SQLITE_OK) {
546
552
errors::throw_sqlite_error (hresult, db.sql ());
547
553
}
548
554
549
- ++db._inx ;
550
555
return db;
551
556
}
552
557
inline void store_result_in_db (sqlite3_context* db, const sqlite_int64& val) {
@@ -570,11 +575,10 @@ namespace sqlite {
570
575
// float
571
576
inline database_binder& operator <<(database_binder& db, const float & val) {
572
577
int hresult;
573
- if ((hresult = sqlite3_bind_double (db._stmt .get (), db._inx , double (val))) != SQLITE_OK) {
578
+ if ((hresult = sqlite3_bind_double (db._stmt .get (), db._next_index () , double (val))) != SQLITE_OK) {
574
579
errors::throw_sqlite_error (hresult, db.sql ());
575
580
}
576
581
577
- ++db._inx ;
578
582
return db;
579
583
}
580
584
inline void store_result_in_db (sqlite3_context* db, const float & val) {
@@ -598,11 +602,10 @@ namespace sqlite {
598
602
// double
599
603
inline database_binder& operator <<(database_binder& db, const double & val) {
600
604
int hresult;
601
- if ((hresult = sqlite3_bind_double (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
605
+ if ((hresult = sqlite3_bind_double (db._stmt .get (), db._next_index () , val)) != SQLITE_OK) {
602
606
errors::throw_sqlite_error (hresult, db.sql ());
603
607
}
604
608
605
- ++db._inx ;
606
609
return db;
607
610
}
608
611
inline void store_result_in_db (sqlite3_context* db, const double & val) {
@@ -628,10 +631,9 @@ namespace sqlite {
628
631
void const * buf = reinterpret_cast <void const *>(vec.data ());
629
632
int bytes = vec.size () * sizeof (T);
630
633
int hresult;
631
- if ((hresult = sqlite3_bind_blob (db._stmt .get (), db._inx , buf, bytes, SQLITE_TRANSIENT)) != SQLITE_OK) {
634
+ if ((hresult = sqlite3_bind_blob (db._stmt .get (), db._next_index () , buf, bytes, SQLITE_TRANSIENT)) != SQLITE_OK) {
632
635
errors::throw_sqlite_error (hresult, db.sql ());
633
636
}
634
- ++db._inx ;
635
637
return db;
636
638
}
637
639
template <typename T, typename A> inline void store_result_in_db (sqlite3_context* db, const std::vector<T, A>& vec) {
@@ -661,10 +663,9 @@ namespace sqlite {
661
663
/* for nullptr support */
662
664
inline database_binder& operator <<(database_binder& db, std::nullptr_t ) {
663
665
int hresult;
664
- if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
666
+ if ((hresult = sqlite3_bind_null (db._stmt .get (), db._next_index () )) != SQLITE_OK) {
665
667
errors::throw_sqlite_error (hresult, db.sql ());
666
668
}
667
- ++db._inx ;
668
669
return db;
669
670
}
670
671
inline void store_result_in_db (sqlite3_context* db, std::nullptr_t ) {
@@ -723,11 +724,10 @@ namespace sqlite {
723
724
724
725
inline database_binder& operator <<(database_binder& db, const std::string& txt) {
725
726
int hresult;
726
- if ((hresult = sqlite3_bind_text (db._stmt .get (), db._inx , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
727
+ if ((hresult = sqlite3_bind_text (db._stmt .get (), db._next_index () , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
727
728
errors::throw_sqlite_error (hresult, db.sql ());
728
729
}
729
730
730
- ++db._inx ;
731
731
return db;
732
732
}
733
733
inline void store_result_in_db (sqlite3_context* db, const std::string& val) {
@@ -754,11 +754,10 @@ namespace sqlite {
754
754
755
755
inline database_binder& operator <<(database_binder& db, const std::u16string& txt) {
756
756
int hresult;
757
- if ((hresult = sqlite3_bind_text16 (db._stmt .get (), db._inx , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
757
+ if ((hresult = sqlite3_bind_text16 (db._stmt .get (), db._next_index () , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
758
758
errors::throw_sqlite_error (hresult, db.sql ());
759
759
}
760
760
761
- ++db._inx ;
762
761
return db;
763
762
}
764
763
inline void store_result_in_db (sqlite3_context* db, const std::u16string& val) {
@@ -794,11 +793,10 @@ namespace sqlite {
794
793
return operator << (std::move (db), std::move (*val));
795
794
}
796
795
int hresult;
797
- if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
796
+ if ((hresult = sqlite3_bind_null (db._stmt .get (), db._next_index () )) != SQLITE_OK) {
798
797
errors::throw_sqlite_error (hresult, db.sql ());
799
798
}
800
799
801
- ++db._inx ;
802
800
return db;
803
801
}
804
802
template <typename OptionalT> inline void store_result_in_db (sqlite3_context* db, const std::optional<OptionalT>& val) {
@@ -835,11 +833,10 @@ namespace sqlite {
835
833
return operator << (std::move (db), std::move (*val));
836
834
}
837
835
int hresult;
838
- if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
836
+ if ((hresult = sqlite3_bind_null (db._stmt .get (), db._next_index () )) != SQLITE_OK) {
839
837
errors::throw_sqlite_error (hresult, db.sql ());
840
838
}
841
839
842
- ++db._inx ;
843
840
return db;
844
841
}
845
842
template <typename BoostOptionalT> inline void store_result_in_db (sqlite3_context* db, const boost::optional<BoostOptionalT>& val) {
@@ -892,7 +889,7 @@ namespace sqlite {
892
889
#endif
893
890
894
891
// Some ppl are lazy so we have a operator for proper prep. statemant handling.
895
- void inline operator ++(database_binder& db, int ) { db.execute (); db. reset (); }
892
+ void inline operator ++(database_binder& db, int ) { db.execute (); }
896
893
897
894
// Convert the rValue binder to a reference and call first op<<, its needed for the call that creates the binder (be carefull of recursion here!)
898
895
template <typename T> database_binder& operator << (database_binder&& db, const T& val) { return db << val; }
0 commit comments