Skip to content

Commit 94c3a68

Browse files
authored
Merge pull request #98 from aminroosta/fix-#97
Fix 97
2 parents 558f5fa + 16907b0 commit 94c3a68

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

hdr/sqlite_modern_cpp.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ namespace sqlite {
7878
//Some additional errors are here for the C++ interface
7979
class more_rows: public sqlite_exception { using sqlite_exception::sqlite_exception; };
8080
class no_rows: public sqlite_exception { using sqlite_exception::sqlite_exception; };
81+
class reexecution: public sqlite_exception { using sqlite_exception::sqlite_exception; }; // Prepared statements need to be reset before calling them again
8182

8283
static void throw_sqlite_error(const int& error_code, const std::string &sql = "") {
8384
if(error_code == SQLITE_ERROR) throw exceptions::error(error_code, sql);
@@ -150,13 +151,14 @@ namespace sqlite {
150151

151152
void execute() {
152153
int hresult;
154+
used(true); /* prevent from executing again when goes out of scope */
153155

154156
while((hresult = sqlite3_step(_stmt.get())) == SQLITE_ROW) {}
155157

156158
if(hresult != SQLITE_DONE) {
157159
exceptions::throw_sqlite_error(hresult, sql());
158160
}
159-
used(true); /* prevent from executing again when goes out of scope */
161+
160162
}
161163

162164
std::string sql() {
@@ -173,7 +175,12 @@ namespace sqlite {
173175
return sqlite3_sql(_stmt.get());
174176
}
175177

176-
void used(bool state) { execution_started = state; }
178+
void used(bool state) {
179+
if(execution_started == true && state == true) {
180+
throw exceptions::reexecution("Already used statement executed again! Please reset() first!",sql());
181+
}
182+
execution_started = state;
183+
}
177184
bool used() const { return execution_started; }
178185

179186
private:
@@ -186,8 +193,8 @@ namespace sqlite {
186193
bool execution_started = false;
187194

188195
void _extract(std::function<void(void)> call_back) {
189-
execution_started = true;
190196
int hresult;
197+
used(true);
191198

192199
while((hresult = sqlite3_step(_stmt.get())) == SQLITE_ROW) {
193200
call_back();
@@ -196,12 +203,11 @@ namespace sqlite {
196203
if(hresult != SQLITE_DONE) {
197204
exceptions::throw_sqlite_error(hresult, sql());
198205
}
199-
reset();
200206
}
201207

202208
void _extract_single_value(std::function<void(void)> call_back) {
203-
execution_started = true;
204209
int hresult;
210+
used(true);
205211

206212
if((hresult = sqlite3_step(_stmt.get())) == SQLITE_ROW) {
207213
call_back();
@@ -216,7 +222,6 @@ namespace sqlite {
216222
if(hresult != SQLITE_DONE) {
217223
exceptions::throw_sqlite_error(hresult, sql());
218224
}
219-
reset();
220225
}
221226

222227
#ifdef _MSC_VER
@@ -307,7 +312,7 @@ namespace sqlite {
307312
~database_binder() noexcept(false) {
308313
/* Will be executed if no >>op is found, but not if an exception
309314
is in mid flight */
310-
if(!execution_started && !_has_uncaught_exception && _stmt) {
315+
if(!used() && !_has_uncaught_exception && _stmt) {
311316
execute();
312317
}
313318
}

tests/prepared_statment.cc

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ int main() {
1414
int test = 4;
1515
pps << test; // set a bound var
1616

17-
pps >> test; // execute and reset statment
17+
pps >> test; // execute statement
18+
19+
pps.reset();
1820

1921
pps << 4; // bind a rvalue
20-
pps >> test; // and execute again
22+
pps++; // and execute and reset
2123

2224
pps << 8 >> test;
2325

@@ -75,6 +77,28 @@ int main() {
7577
(pps4 << test << test << test)++;
7678
}
7779

80+
{
81+
auto prep = db << "select ?";
82+
83+
prep << 5;
84+
85+
prep.execute();
86+
try {
87+
prep.execute();
88+
exit(EXIT_FAILURE);
89+
} catch(exceptions::reexecution& ex) {
90+
// Thats ok here
91+
} catch(...) {
92+
exit(EXIT_FAILURE);
93+
}
94+
95+
prep.reset();
96+
97+
prep << 6;
98+
prep.execute();
99+
100+
}
101+
78102

79103
} catch(sqlite_exception e) {
80104
cout << "Unexpected error " << e.what() << endl;

0 commit comments

Comments
 (0)