@@ -74,12 +74,14 @@ namespace sqlite {
7474 _inx (other._inx), execution_started(other.execution_started) { }
7575
7676 void reset[[deprecated]]() {
77+ used (true );
78+ _inx = 0 ;
7779 used (false );
7880 }
7981
8082 void execute () {
83+ _start_execute ();
8184 int hresult;
82- auto_reset helper (this );
8385
8486 while ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {}
8587
@@ -103,6 +105,11 @@ namespace sqlite {
103105 }
104106
105107 void used (bool state) {
108+ if (!state) {
109+ // We may have to reset first if we haven't done so already:
110+ _next_index ();
111+ --_inx;
112+ }
106113 execution_started = state;
107114 }
108115 bool used () const { return execution_started; }
@@ -116,21 +123,22 @@ namespace sqlite {
116123
117124 bool execution_started = false ;
118125
119- struct auto_reset {
120- database_binder *binder;
121- auto_reset (database_binder *binder): binder(binder) {
122- binder->used (true );
123- }
124- ~auto_reset () {
125- sqlite3_reset (binder->_stmt .get ());
126- sqlite3_clear_bindings (binder->_stmt .get ());
127- binder->_inx = 1 ;
126+ int _next_index () {
127+ if (execution_started && !_inx) {
128+ sqlite3_reset (_stmt.get ());
129+ sqlite3_clear_bindings (_stmt.get ());
128130 }
129- };
131+ return ++_inx;
132+ }
133+ void _start_execute () {
134+ _next_index ();
135+ _inx = 0 ;
136+ used (true );
137+ }
130138
131139 void _extract (std::function<void (void )> call_back) {
132140 int hresult;
133- auto_reset helper ( this );
141+ _start_execute ( );
134142
135143 while ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
136144 call_back ();
@@ -143,7 +151,7 @@ namespace sqlite {
143151
144152 void _extract_single_value (std::function<void (void )> call_back) {
145153 int hresult;
146- auto_reset helper ( this );
154+ _start_execute ( );
147155
148156 if ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
149157 call_back ();
@@ -248,13 +256,13 @@ namespace sqlite {
248256 database_binder (std::shared_ptr<sqlite3> db, std::u16string const & sql):
249257 _db (db),
250258 _stmt (_prepare(sql), sqlite3_finalize),
251- _inx (1 ) {
259+ _inx (0 ) {
252260 }
253261
254262 database_binder (std::shared_ptr<sqlite3> db, std::string const & sql):
255263 _db (db),
256264 _stmt (_prepare(sql), sqlite3_finalize),
257- _inx (1 ) {
265+ _inx (0 ) {
258266 }
259267
260268 ~database_binder () noexcept (false ) {
@@ -520,10 +528,9 @@ namespace sqlite {
520528 // int
521529 inline database_binder& operator <<(database_binder& db, const int & val) {
522530 int hresult;
523- if ((hresult = sqlite3_bind_int (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
531+ if ((hresult = sqlite3_bind_int (db._stmt .get (), db._next_index () , val)) != SQLITE_OK) {
524532 errors::throw_sqlite_error (hresult, db.sql ());
525533 }
526- ++db._inx ;
527534 return db;
528535 }
529536 inline void store_result_in_db (sqlite3_context* db, const int & val) {
@@ -547,11 +554,10 @@ namespace sqlite {
547554 // sqlite_int64
548555 inline database_binder& operator <<(database_binder& db, const sqlite_int64& val) {
549556 int hresult;
550- if ((hresult = sqlite3_bind_int64 (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
557+ if ((hresult = sqlite3_bind_int64 (db._stmt .get (), db._next_index () , val)) != SQLITE_OK) {
551558 errors::throw_sqlite_error (hresult, db.sql ());
552559 }
553560
554- ++db._inx ;
555561 return db;
556562 }
557563 inline void store_result_in_db (sqlite3_context* db, const sqlite_int64& val) {
@@ -575,11 +581,10 @@ namespace sqlite {
575581 // float
576582 inline database_binder& operator <<(database_binder& db, const float & val) {
577583 int hresult;
578- if ((hresult = sqlite3_bind_double (db._stmt .get (), db._inx , double (val))) != SQLITE_OK) {
584+ if ((hresult = sqlite3_bind_double (db._stmt .get (), db._next_index () , double (val))) != SQLITE_OK) {
579585 errors::throw_sqlite_error (hresult, db.sql ());
580586 }
581587
582- ++db._inx ;
583588 return db;
584589 }
585590 inline void store_result_in_db (sqlite3_context* db, const float & val) {
@@ -603,11 +608,10 @@ namespace sqlite {
603608 // double
604609 inline database_binder& operator <<(database_binder& db, const double & val) {
605610 int hresult;
606- if ((hresult = sqlite3_bind_double (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
611+ if ((hresult = sqlite3_bind_double (db._stmt .get (), db._next_index () , val)) != SQLITE_OK) {
607612 errors::throw_sqlite_error (hresult, db.sql ());
608613 }
609614
610- ++db._inx ;
611615 return db;
612616 }
613617 inline void store_result_in_db (sqlite3_context* db, const double & val) {
@@ -633,10 +637,9 @@ namespace sqlite {
633637 void const * buf = reinterpret_cast <void const *>(vec.data ());
634638 int bytes = vec.size () * sizeof (T);
635639 int hresult;
636- if ((hresult = sqlite3_bind_blob (db._stmt .get (), db._inx , buf, bytes, SQLITE_TRANSIENT)) != SQLITE_OK) {
640+ if ((hresult = sqlite3_bind_blob (db._stmt .get (), db._next_index () , buf, bytes, SQLITE_TRANSIENT)) != SQLITE_OK) {
637641 errors::throw_sqlite_error (hresult, db.sql ());
638642 }
639- ++db._inx ;
640643 return db;
641644 }
642645 template <typename T, typename A> inline void store_result_in_db (sqlite3_context* db, const std::vector<T, A>& vec) {
@@ -666,10 +669,9 @@ namespace sqlite {
666669 /* for nullptr support */
667670 inline database_binder& operator <<(database_binder& db, std::nullptr_t ) {
668671 int hresult;
669- if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
672+ if ((hresult = sqlite3_bind_null (db._stmt .get (), db._next_index () )) != SQLITE_OK) {
670673 errors::throw_sqlite_error (hresult, db.sql ());
671674 }
672- ++db._inx ;
673675 return db;
674676 }
675677 inline void store_result_in_db (sqlite3_context* db, std::nullptr_t ) {
@@ -728,11 +730,10 @@ namespace sqlite {
728730
729731 inline database_binder& operator <<(database_binder& db, const std::string& txt) {
730732 int hresult;
731- if ((hresult = sqlite3_bind_text (db._stmt .get (), db._inx , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
733+ if ((hresult = sqlite3_bind_text (db._stmt .get (), db._next_index () , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
732734 errors::throw_sqlite_error (hresult, db.sql ());
733735 }
734736
735- ++db._inx ;
736737 return db;
737738 }
738739 inline void store_result_in_db (sqlite3_context* db, const std::string& val) {
@@ -759,11 +760,10 @@ namespace sqlite {
759760
760761 inline database_binder& operator <<(database_binder& db, const std::u16string& txt) {
761762 int hresult;
762- if ((hresult = sqlite3_bind_text16 (db._stmt .get (), db._inx , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
763+ if ((hresult = sqlite3_bind_text16 (db._stmt .get (), db._next_index () , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
763764 errors::throw_sqlite_error (hresult, db.sql ());
764765 }
765766
766- ++db._inx ;
767767 return db;
768768 }
769769 inline void store_result_in_db (sqlite3_context* db, const std::u16string& val) {
@@ -799,11 +799,10 @@ namespace sqlite {
799799 return operator << (std::move (db), std::move (*val));
800800 }
801801 int hresult;
802- if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
802+ if ((hresult = sqlite3_bind_null (db._stmt .get (), db._next_index () )) != SQLITE_OK) {
803803 errors::throw_sqlite_error (hresult, db.sql ());
804804 }
805805
806- ++db._inx ;
807806 return db;
808807 }
809808 template <typename OptionalT> inline void store_result_in_db (sqlite3_context* db, const std::optional<OptionalT>& val) {
@@ -840,11 +839,10 @@ namespace sqlite {
840839 return operator << (std::move (db), std::move (*val));
841840 }
842841 int hresult;
843- if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
842+ if ((hresult = sqlite3_bind_null (db._stmt .get (), db._next_index () )) != SQLITE_OK) {
844843 errors::throw_sqlite_error (hresult, db.sql ());
845844 }
846845
847- ++db._inx ;
848846 return db;
849847 }
850848 template <typename BoostOptionalT> inline void store_result_in_db (sqlite3_context* db, const boost::optional<BoostOptionalT>& val) {
0 commit comments