@@ -73,23 +73,15 @@ namespace sqlite {
7373 _stmt (std::move(other._stmt)),
7474 _inx (other._inx), execution_started(other.execution_started) { }
7575
76- void reset () {
77- sqlite3_reset (_stmt.get ());
78- sqlite3_clear_bindings (_stmt.get ());
79- _inx = 1 ;
80- used (false );
81- }
82-
8376 void execute () {
77+ _start_execute ();
8478 int hresult;
85- used (true ); /* prevent from executing again when goes out of scope */
8679
8780 while ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {}
8881
8982 if (hresult != SQLITE_DONE) {
9083 errors::throw_sqlite_error (hresult, sql ());
9184 }
92-
9385 }
9486
9587 std::string sql () {
@@ -107,8 +99,10 @@ namespace sqlite {
10799 }
108100
109101 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;
112106 }
113107 execution_started = state;
114108 }
@@ -123,9 +117,22 @@ namespace sqlite {
123117
124118 bool execution_started = false ;
125119
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+
126133 void _extract (std::function<void (void )> call_back) {
127134 int hresult;
128- used ( true );
135+ _start_execute ( );
129136
130137 while ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
131138 call_back ();
@@ -138,7 +145,7 @@ namespace sqlite {
138145
139146 void _extract_single_value (std::function<void (void )> call_back) {
140147 int hresult;
141- used ( true );
148+ _start_execute ( );
142149
143150 if ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
144151 call_back ();
@@ -243,13 +250,13 @@ namespace sqlite {
243250 database_binder (std::shared_ptr<sqlite3> db, std::u16string const & sql):
244251 _db (db),
245252 _stmt (_prepare(sql), sqlite3_finalize),
246- _inx (1 ) {
253+ _inx (0 ) {
247254 }
248255
249256 database_binder (std::shared_ptr<sqlite3> db, std::string const & sql):
250257 _db (db),
251258 _stmt (_prepare(sql), sqlite3_finalize),
252- _inx (1 ) {
259+ _inx (0 ) {
253260 }
254261
255262 ~database_binder () noexcept (false ) {
@@ -515,10 +522,9 @@ namespace sqlite {
515522 // int
516523 inline database_binder& operator <<(database_binder& db, const int & val) {
517524 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) {
519526 errors::throw_sqlite_error (hresult, db.sql ());
520527 }
521- ++db._inx ;
522528 return db;
523529 }
524530 inline void store_result_in_db (sqlite3_context* db, const int & val) {
@@ -542,11 +548,10 @@ namespace sqlite {
542548 // sqlite_int64
543549 inline database_binder& operator <<(database_binder& db, const sqlite_int64& val) {
544550 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) {
546552 errors::throw_sqlite_error (hresult, db.sql ());
547553 }
548554
549- ++db._inx ;
550555 return db;
551556 }
552557 inline void store_result_in_db (sqlite3_context* db, const sqlite_int64& val) {
@@ -570,11 +575,10 @@ namespace sqlite {
570575 // float
571576 inline database_binder& operator <<(database_binder& db, const float & val) {
572577 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) {
574579 errors::throw_sqlite_error (hresult, db.sql ());
575580 }
576581
577- ++db._inx ;
578582 return db;
579583 }
580584 inline void store_result_in_db (sqlite3_context* db, const float & val) {
@@ -598,11 +602,10 @@ namespace sqlite {
598602 // double
599603 inline database_binder& operator <<(database_binder& db, const double & val) {
600604 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) {
602606 errors::throw_sqlite_error (hresult, db.sql ());
603607 }
604608
605- ++db._inx ;
606609 return db;
607610 }
608611 inline void store_result_in_db (sqlite3_context* db, const double & val) {
@@ -628,10 +631,9 @@ namespace sqlite {
628631 void const * buf = reinterpret_cast <void const *>(vec.data ());
629632 int bytes = vec.size () * sizeof (T);
630633 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) {
632635 errors::throw_sqlite_error (hresult, db.sql ());
633636 }
634- ++db._inx ;
635637 return db;
636638 }
637639 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 {
661663 /* for nullptr support */
662664 inline database_binder& operator <<(database_binder& db, std::nullptr_t ) {
663665 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) {
665667 errors::throw_sqlite_error (hresult, db.sql ());
666668 }
667- ++db._inx ;
668669 return db;
669670 }
670671 inline void store_result_in_db (sqlite3_context* db, std::nullptr_t ) {
@@ -723,11 +724,10 @@ namespace sqlite {
723724
724725 inline database_binder& operator <<(database_binder& db, const std::string& txt) {
725726 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) {
727728 errors::throw_sqlite_error (hresult, db.sql ());
728729 }
729730
730- ++db._inx ;
731731 return db;
732732 }
733733 inline void store_result_in_db (sqlite3_context* db, const std::string& val) {
@@ -754,11 +754,10 @@ namespace sqlite {
754754
755755 inline database_binder& operator <<(database_binder& db, const std::u16string& txt) {
756756 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) {
758758 errors::throw_sqlite_error (hresult, db.sql ());
759759 }
760760
761- ++db._inx ;
762761 return db;
763762 }
764763 inline void store_result_in_db (sqlite3_context* db, const std::u16string& val) {
@@ -794,11 +793,10 @@ namespace sqlite {
794793 return operator << (std::move (db), std::move (*val));
795794 }
796795 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) {
798797 errors::throw_sqlite_error (hresult, db.sql ());
799798 }
800799
801- ++db._inx ;
802800 return db;
803801 }
804802 template <typename OptionalT> inline void store_result_in_db (sqlite3_context* db, const std::optional<OptionalT>& val) {
@@ -835,11 +833,10 @@ namespace sqlite {
835833 return operator << (std::move (db), std::move (*val));
836834 }
837835 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) {
839837 errors::throw_sqlite_error (hresult, db.sql ());
840838 }
841839
842- ++db._inx ;
843840 return db;
844841 }
845842 template <typename BoostOptionalT> inline void store_result_in_db (sqlite3_context* db, const boost::optional<BoostOptionalT>& val) {
@@ -892,7 +889,7 @@ namespace sqlite {
892889#endif
893890
894891 // 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 (); }
896893
897894 // 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!)
898895 template <typename T> database_binder& operator << (database_binder&& db, const T& val) { return db << val; }
0 commit comments