Skip to content

Commit 5d6b00a

Browse files
committed
Auto reset after statement execution
1 parent 0124642 commit 5d6b00a

File tree

4 files changed

+22
-35
lines changed

4 files changed

+22
-35
lines changed

README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,10 @@ ps << tmp;
117117
// But beware that it will execute on destruction if it wasn't executed!
118118
ps >> [&](int a,int b){ ... };
119119
120-
// after a successfull execution the statment needs to be reset to be execute again. This will reset the bound values too!
121-
ps.reset();
122-
120+
// after a successfull execution the statment an be executed again, but the bound values are resetted.
123121
// If you dont need the returned values you can execute it like this
124-
ps.execute(); // the statment will not be reset!
125-
126-
// there is a convinience operator to execute and reset in one go
122+
ps.execute();
123+
// or like this
127124
ps++;
128125
129126
// To disable the execution of a statment when it goes out of scope and wasn't used

hdr/sqlite_modern_cpp.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,23 +73,19 @@ 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;
76+
void reset[[deprecated]]() {
8077
used(false);
8178
}
8279

8380
void execute() {
8481
int hresult;
85-
used(true); /* prevent from executing again when goes out of scope */
82+
auto_reset helper(this);
8683

8784
while((hresult = sqlite3_step(_stmt.get())) == SQLITE_ROW) {}
8885

8986
if(hresult != SQLITE_DONE) {
9087
errors::throw_sqlite_error(hresult, sql());
9188
}
92-
9389
}
9490

9591
std::string sql() {
@@ -107,9 +103,6 @@ namespace sqlite {
107103
}
108104

109105
void used(bool state) {
110-
if(execution_started == true && state == true) {
111-
throw errors::reexecution("Already used statement executed again! Please reset() first!",sql());
112-
}
113106
execution_started = state;
114107
}
115108
bool used() const { return execution_started; }
@@ -123,9 +116,21 @@ namespace sqlite {
123116

124117
bool execution_started = false;
125118

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;
128+
}
129+
};
130+
126131
void _extract(std::function<void(void)> call_back) {
127132
int hresult;
128-
used(true);
133+
auto_reset helper(this);
129134

130135
while((hresult = sqlite3_step(_stmt.get())) == SQLITE_ROW) {
131136
call_back();
@@ -138,7 +143,7 @@ namespace sqlite {
138143

139144
void _extract_single_value(std::function<void(void)> call_back) {
140145
int hresult;
141-
used(true);
146+
auto_reset helper(this);
142147

143148
if((hresult = sqlite3_step(_stmt.get())) == SQLITE_ROW) {
144149
call_back();
@@ -892,7 +897,7 @@ namespace sqlite {
892897
#endif
893898

894899
// 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(); }
900+
void inline operator++(database_binder& db, int) { db.execute(); }
896901

897902
// 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!)
898903
template<typename T> database_binder& operator << (database_binder&& db, const T& val) { return db << val; }

hdr/sqlite_modern_cpp/errors.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace sqlite {
3737
//Some additional errors are here for the C++ interface
3838
class more_rows: public sqlite_exception { using sqlite_exception::sqlite_exception; };
3939
class no_rows: public sqlite_exception { using sqlite_exception::sqlite_exception; };
40-
class reexecution: public sqlite_exception { using sqlite_exception::sqlite_exception; }; // Prepared statements need to be reset before calling them again
40+
class [[deprecated]] reexecution: public sqlite_exception { using sqlite_exception::sqlite_exception; }; // Prepared statements needed to be reset before calling them again in older versions
4141
class more_statements: public sqlite_exception { using sqlite_exception::sqlite_exception; }; // Prepared statements can only contain one statement
4242

4343
static void throw_sqlite_error(const int& error_code, const std::string &sql = "") {

tests/prepared_statment.cc

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ int main() {
1616

1717
pps >> test; // execute statement
1818

19-
pps.reset();
20-
2119
pps << 4; // bind a rvalue
22-
pps++; // and execute and reset
20+
pps++; // and execute
2321

2422
pps << 8 >> test;
2523

@@ -81,22 +79,9 @@ int main() {
8179
auto prep = db << "select ?";
8280

8381
prep << 5;
84-
8582
prep.execute();
86-
try {
87-
prep.execute();
88-
exit(EXIT_FAILURE);
89-
} catch(errors::reexecution& ex) {
90-
// Thats ok here
91-
} catch(...) {
92-
exit(EXIT_FAILURE);
93-
}
94-
95-
prep.reset();
96-
9783
prep << 6;
9884
prep.execute();
99-
10085
}
10186

10287

0 commit comments

Comments
 (0)