@@ -30,11 +30,13 @@ namespace sqlite {
3030
3131 class sqlite_exception : public std ::runtime_error {
3232 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 ) {}
3535 int get_code () {return code;}
36+ std::string get_sql () {return sql;}
3637 private:
3738 int code;
39+ std::string sql;
3840 };
3941
4042 namespace exceptions {
@@ -74,34 +76,34 @@ namespace sqlite {
7476 class more_rows : public sqlite_exception { using sqlite_exception::sqlite_exception; };
7577 class no_rows : public sqlite_exception { using sqlite_exception::sqlite_exception; };
7678
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 );
105107 }
106108 }
107109
@@ -149,10 +151,20 @@ namespace sqlite {
149151 while ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {}
150152
151153 if (hresult != SQLITE_DONE) {
152- exceptions::throw_sqlite_error (hresult);
154+ exceptions::throw_sqlite_error (hresult, sql () );
153155 }
154156 used (true ); /* prevent from executing again when goes out of scope */
155157 }
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+ }
156168
157169 void used (bool state) { execution_started = state; }
158170 bool used () const { return execution_started; }
@@ -174,7 +186,7 @@ namespace sqlite {
174186 }
175187
176188 if (hresult != SQLITE_DONE) {
177- exceptions::throw_sqlite_error (hresult);
189+ exceptions::throw_sqlite_error (hresult, sql () );
178190 }
179191 reset ();
180192 }
@@ -186,15 +198,15 @@ namespace sqlite {
186198 if ((hresult = sqlite3_step (_stmt.get ())) == SQLITE_ROW) {
187199 call_back ();
188200 } 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);
190202 }
191203
192204 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);
194206 }
195207
196208 if (hresult != SQLITE_DONE) {
197- exceptions::throw_sqlite_error (hresult);
209+ exceptions::throw_sqlite_error (hresult, sql () );
198210 }
199211 reset ();
200212 }
@@ -211,7 +223,7 @@ namespace sqlite {
211223 int hresult;
212224 sqlite3_stmt* tmp = nullptr ;
213225 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 );
215227 return tmp;
216228 }
217229
@@ -416,7 +428,7 @@ namespace sqlite {
416428 inline database_binder& operator <<(database_binder& db, const int & val) {
417429 int hresult;
418430 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 () );
420432 }
421433 ++db._inx ;
422434 return db;
@@ -433,7 +445,7 @@ namespace sqlite {
433445 inline database_binder& operator <<(database_binder& db, const sqlite_int64& val) {
434446 int hresult;
435447 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 () );
437449 }
438450
439451 ++db._inx ;
@@ -451,7 +463,7 @@ namespace sqlite {
451463 inline database_binder& operator <<(database_binder& db, const float & val) {
452464 int hresult;
453465 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 () );
455467 }
456468
457469 ++db._inx ;
@@ -469,7 +481,7 @@ namespace sqlite {
469481 inline database_binder& operator <<(database_binder& db, const double & val) {
470482 int hresult;
471483 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 () );
473485 }
474486
475487 ++db._inx ;
@@ -489,7 +501,7 @@ namespace sqlite {
489501 int bytes = vec.size () * sizeof (T);
490502 int hresult;
491503 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 () );
493505 }
494506 ++db._inx ;
495507 return db;
@@ -508,7 +520,7 @@ namespace sqlite {
508520 inline database_binder& operator <<(database_binder& db, std::nullptr_t ) {
509521 int hresult;
510522 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 () );
512524 }
513525 ++db._inx ;
514526 return db;
@@ -550,7 +562,7 @@ namespace sqlite {
550562 inline database_binder& operator <<(database_binder& db, const std::string& txt) {
551563 int hresult;
552564 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 () );
554566 }
555567
556568 ++db._inx ;
@@ -570,7 +582,7 @@ namespace sqlite {
570582 inline database_binder& operator <<(database_binder& db, const std::u16string& txt) {
571583 int hresult;
572584 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 () );
574586 }
575587
576588 ++db._inx ;
@@ -584,7 +596,7 @@ namespace sqlite {
584596 }
585597 int hresult;
586598 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 () );
588600 }
589601
590602 ++db._inx ;
@@ -610,7 +622,7 @@ namespace sqlite {
610622 }
611623 int hresult;
612624 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 () );
614626 }
615627
616628 ++db._inx ;
0 commit comments