@@ -30,11 +30,13 @@ namespace sqlite {
30
30
31
31
class sqlite_exception : public std ::runtime_error {
32
32
public:
33
- sqlite_exception (const char * msg, int code = -1 ): runtime_error(msg), code(code) {}
34
- sqlite_exception (int code): runtime_error(sqlite3_errstr(code)), code(code) {}
33
+ sqlite_exception (const char * msg, std::string sql, int code = -1 ): runtime_error(msg), code(code), sql(sql ) {}
34
+ sqlite_exception (int code, std::string sql ): runtime_error(sqlite3_errstr(code)), code(code), sql(sql ) {}
35
35
int get_code () {return code;}
36
+ std::string get_sql () {return sql;}
36
37
private:
37
38
int code;
39
+ std::string sql;
38
40
};
39
41
40
42
namespace exceptions {
@@ -74,34 +76,34 @@ namespace sqlite {
74
76
class more_rows : public sqlite_exception { using sqlite_exception::sqlite_exception; };
75
77
class no_rows : public sqlite_exception { using sqlite_exception::sqlite_exception; };
76
78
77
- static void throw_sqlite_error (const int & error_code) {
78
- if (error_code == SQLITE_ERROR) throw exceptions::error (error_code);
79
- else if (error_code == SQLITE_INTERNAL) throw exceptions::internal (error_code);
80
- else if (error_code == SQLITE_PERM) throw exceptions::perm (error_code);
81
- else if (error_code == SQLITE_ABORT) throw exceptions::abort (error_code);
82
- else if (error_code == SQLITE_BUSY) throw exceptions::busy (error_code);
83
- else if (error_code == SQLITE_LOCKED) throw exceptions::locked (error_code);
84
- else if (error_code == SQLITE_NOMEM) throw exceptions::nomem (error_code);
85
- else if (error_code == SQLITE_READONLY) throw exceptions::readonly (error_code);
86
- else if (error_code == SQLITE_INTERRUPT) throw exceptions::interrupt (error_code);
87
- else if (error_code == SQLITE_IOERR) throw exceptions::ioerr (error_code);
88
- else if (error_code == SQLITE_CORRUPT) throw exceptions::corrupt (error_code);
89
- else if (error_code == SQLITE_NOTFOUND) throw exceptions::notfound (error_code);
90
- else if (error_code == SQLITE_FULL) throw exceptions::full (error_code);
91
- else if (error_code == SQLITE_CANTOPEN) throw exceptions::cantopen (error_code);
92
- else if (error_code == SQLITE_PROTOCOL) throw exceptions::protocol (error_code);
93
- else if (error_code == SQLITE_EMPTY) throw exceptions::empty (error_code);
94
- else if (error_code == SQLITE_SCHEMA) throw exceptions::schema (error_code);
95
- else if (error_code == SQLITE_TOOBIG) throw exceptions::toobig (error_code);
96
- else if (error_code == SQLITE_CONSTRAINT) throw exceptions::constraint (error_code);
97
- else if (error_code == SQLITE_MISMATCH) throw exceptions::mismatch (error_code);
98
- else if (error_code == SQLITE_MISUSE) throw exceptions::misuse (error_code);
99
- else if (error_code == SQLITE_NOLFS) throw exceptions::nolfs (error_code);
100
- else if (error_code == SQLITE_AUTH) throw exceptions::auth (error_code);
101
- else if (error_code == SQLITE_FORMAT) throw exceptions::format (error_code);
102
- else if (error_code == SQLITE_RANGE) throw exceptions::range (error_code);
103
- else if (error_code == SQLITE_NOTADB) throw exceptions::notadb (error_code);
104
- else throw sqlite_exception (error_code);
79
+ static void throw_sqlite_error (const int & error_code, const std::string &sql = " " ) {
80
+ if (error_code == SQLITE_ERROR) throw exceptions::error (error_code, sql );
81
+ else if (error_code == SQLITE_INTERNAL) throw exceptions::internal (error_code, sql );
82
+ else if (error_code == SQLITE_PERM) throw exceptions::perm (error_code, sql );
83
+ else if (error_code == SQLITE_ABORT) throw exceptions::abort (error_code, sql );
84
+ else if (error_code == SQLITE_BUSY) throw exceptions::busy (error_code, sql );
85
+ else if (error_code == SQLITE_LOCKED) throw exceptions::locked (error_code, sql );
86
+ else if (error_code == SQLITE_NOMEM) throw exceptions::nomem (error_code, sql );
87
+ else if (error_code == SQLITE_READONLY) throw exceptions::readonly (error_code, sql );
88
+ else if (error_code == SQLITE_INTERRUPT) throw exceptions::interrupt (error_code, sql );
89
+ else if (error_code == SQLITE_IOERR) throw exceptions::ioerr (error_code, sql );
90
+ else if (error_code == SQLITE_CORRUPT) throw exceptions::corrupt (error_code, sql );
91
+ else if (error_code == SQLITE_NOTFOUND) throw exceptions::notfound (error_code, sql );
92
+ else if (error_code == SQLITE_FULL) throw exceptions::full (error_code, sql );
93
+ else if (error_code == SQLITE_CANTOPEN) throw exceptions::cantopen (error_code, sql );
94
+ else if (error_code == SQLITE_PROTOCOL) throw exceptions::protocol (error_code, sql );
95
+ else if (error_code == SQLITE_EMPTY) throw exceptions::empty (error_code, sql );
96
+ else if (error_code == SQLITE_SCHEMA) throw exceptions::schema (error_code, sql );
97
+ else if (error_code == SQLITE_TOOBIG) throw exceptions::toobig (error_code, sql );
98
+ else if (error_code == SQLITE_CONSTRAINT) throw exceptions::constraint (error_code, sql );
99
+ else if (error_code == SQLITE_MISMATCH) throw exceptions::mismatch (error_code, sql );
100
+ else if (error_code == SQLITE_MISUSE) throw exceptions::misuse (error_code, sql );
101
+ else if (error_code == SQLITE_NOLFS) throw exceptions::nolfs (error_code, sql );
102
+ else if (error_code == SQLITE_AUTH) throw exceptions::auth (error_code, sql );
103
+ else if (error_code == SQLITE_FORMAT) throw exceptions::format (error_code, sql );
104
+ else if (error_code == SQLITE_RANGE) throw exceptions::range (error_code, sql );
105
+ else if (error_code == SQLITE_NOTADB) throw exceptions::notadb (error_code, sql );
106
+ else throw sqlite_exception (error_code, sql );
105
107
}
106
108
}
107
109
@@ -149,10 +151,20 @@ namespace sqlite {
149
151
while ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {}
150
152
151
153
if (hresult != SQLITE_DONE) {
152
- exceptions::throw_sqlite_error (hresult);
154
+ exceptions::throw_sqlite_error (hresult, sql () );
153
155
}
154
156
used (true ); /* prevent from executing again when goes out of scope */
155
157
}
158
+
159
+ std::string sql () {
160
+ auto sqlite_deleter = [](void *ptr) {sqlite3_free (ptr);};
161
+ std::unique_ptr<char , decltype (sqlite_deleter)> str (sqlite3_expanded_sql (_stmt.get ()), sqlite_deleter);
162
+ return str ? str.get () : original_sql ();
163
+ }
164
+
165
+ std::string original_sql () {
166
+ return sqlite3_sql (_stmt.get ());
167
+ }
156
168
157
169
void used (bool state) { execution_started = state; }
158
170
bool used () const { return execution_started; }
@@ -174,7 +186,7 @@ namespace sqlite {
174
186
}
175
187
176
188
if (hresult != SQLITE_DONE) {
177
- exceptions::throw_sqlite_error (hresult);
189
+ exceptions::throw_sqlite_error (hresult, sql () );
178
190
}
179
191
reset ();
180
192
}
@@ -186,15 +198,15 @@ namespace sqlite {
186
198
if ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
187
199
call_back ();
188
200
} else if (hresult == SQLITE_DONE) {
189
- throw exceptions::no_rows (" no rows to extract: exactly 1 row expected" , SQLITE_DONE);
201
+ throw exceptions::no_rows (" no rows to extract: exactly 1 row expected" , sql (), SQLITE_DONE);
190
202
}
191
203
192
204
if ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
193
- throw exceptions::more_rows (" not all rows extracted" , SQLITE_ROW);
205
+ throw exceptions::more_rows (" not all rows extracted" , sql (), SQLITE_ROW);
194
206
}
195
207
196
208
if (hresult != SQLITE_DONE) {
197
- exceptions::throw_sqlite_error (hresult);
209
+ exceptions::throw_sqlite_error (hresult, sql () );
198
210
}
199
211
reset ();
200
212
}
@@ -211,7 +223,7 @@ namespace sqlite {
211
223
int hresult;
212
224
sqlite3_stmt* tmp = nullptr ;
213
225
hresult = sqlite3_prepare_v2 (_db.get (), sql.data (), -1 , &tmp, nullptr );
214
- if ((hresult) != SQLITE_OK) exceptions::throw_sqlite_error (hresult);
226
+ if ((hresult) != SQLITE_OK) exceptions::throw_sqlite_error (hresult, sql );
215
227
return tmp;
216
228
}
217
229
@@ -416,7 +428,7 @@ namespace sqlite {
416
428
inline database_binder& operator <<(database_binder& db, const int & val) {
417
429
int hresult;
418
430
if ((hresult = sqlite3_bind_int (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
419
- exceptions::throw_sqlite_error (hresult);
431
+ exceptions::throw_sqlite_error (hresult, db. sql () );
420
432
}
421
433
++db._inx ;
422
434
return db;
@@ -433,7 +445,7 @@ namespace sqlite {
433
445
inline database_binder& operator <<(database_binder& db, const sqlite_int64& val) {
434
446
int hresult;
435
447
if ((hresult = sqlite3_bind_int64 (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
436
- exceptions::throw_sqlite_error (hresult);
448
+ exceptions::throw_sqlite_error (hresult, db. sql () );
437
449
}
438
450
439
451
++db._inx ;
@@ -451,7 +463,7 @@ namespace sqlite {
451
463
inline database_binder& operator <<(database_binder& db, const float & val) {
452
464
int hresult;
453
465
if ((hresult = sqlite3_bind_double (db._stmt .get (), db._inx , double (val))) != SQLITE_OK) {
454
- exceptions::throw_sqlite_error (hresult);
466
+ exceptions::throw_sqlite_error (hresult, db. sql () );
455
467
}
456
468
457
469
++db._inx ;
@@ -469,7 +481,7 @@ namespace sqlite {
469
481
inline database_binder& operator <<(database_binder& db, const double & val) {
470
482
int hresult;
471
483
if ((hresult = sqlite3_bind_double (db._stmt .get (), db._inx , val)) != SQLITE_OK) {
472
- exceptions::throw_sqlite_error (hresult);
484
+ exceptions::throw_sqlite_error (hresult, db. sql () );
473
485
}
474
486
475
487
++db._inx ;
@@ -489,7 +501,7 @@ namespace sqlite {
489
501
int bytes = vec.size () * sizeof (T);
490
502
int hresult;
491
503
if ((hresult = sqlite3_bind_blob (db._stmt .get (), db._inx , buf, bytes, SQLITE_TRANSIENT)) != SQLITE_OK) {
492
- exceptions::throw_sqlite_error (hresult);
504
+ exceptions::throw_sqlite_error (hresult, db. sql () );
493
505
}
494
506
++db._inx ;
495
507
return db;
@@ -508,7 +520,7 @@ namespace sqlite {
508
520
inline database_binder& operator <<(database_binder& db, std::nullptr_t ) {
509
521
int hresult;
510
522
if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
511
- exceptions::throw_sqlite_error (hresult);
523
+ exceptions::throw_sqlite_error (hresult, db. sql () );
512
524
}
513
525
++db._inx ;
514
526
return db;
@@ -550,7 +562,7 @@ namespace sqlite {
550
562
inline database_binder& operator <<(database_binder& db, const std::string& txt) {
551
563
int hresult;
552
564
if ((hresult = sqlite3_bind_text (db._stmt .get (), db._inx , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
553
- exceptions::throw_sqlite_error (hresult);
565
+ exceptions::throw_sqlite_error (hresult, db. sql () );
554
566
}
555
567
556
568
++db._inx ;
@@ -570,7 +582,7 @@ namespace sqlite {
570
582
inline database_binder& operator <<(database_binder& db, const std::u16string& txt) {
571
583
int hresult;
572
584
if ((hresult = sqlite3_bind_text16 (db._stmt .get (), db._inx , txt.data (), -1 , SQLITE_TRANSIENT)) != SQLITE_OK) {
573
- exceptions::throw_sqlite_error (hresult);
585
+ exceptions::throw_sqlite_error (hresult, db. sql () );
574
586
}
575
587
576
588
++db._inx ;
@@ -584,7 +596,7 @@ namespace sqlite {
584
596
}
585
597
int hresult;
586
598
if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
587
- exceptions::throw_sqlite_error (hresult);
599
+ exceptions::throw_sqlite_error (hresult, db. sql () );
588
600
}
589
601
590
602
++db._inx ;
@@ -610,7 +622,7 @@ namespace sqlite {
610
622
}
611
623
int hresult;
612
624
if ((hresult = sqlite3_bind_null (db._stmt .get (), db._inx )) != SQLITE_OK) {
613
- exceptions::throw_sqlite_error (hresult);
625
+ exceptions::throw_sqlite_error (hresult, db. sql () );
614
626
}
615
627
616
628
++db._inx ;
0 commit comments