From d6a129143edf62528eb338a8a92af29808c0987a Mon Sep 17 00:00:00 2001 From: Bjoern Hoehrmann Date: Sun, 18 Apr 2021 00:29:54 +0200 Subject: [PATCH 1/2] Pass sqlite3_log messages on to DBI tracing --- dbdimp.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/dbdimp.c b/dbdimp.c index d30e98e..2c40554 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -175,6 +175,13 @@ _sqlite_exec(pTHX_ SV *h, sqlite3 *db, const char *sql) return rc; } +static void +_sqlite_log_callback(void *imp_dbh, int error_code, const char *message) +{ + dTHX; + sqlite_trace(NULL, imp_dbh, 3, form("sqlite3_log %d, %s", error_code, message)); +} + int _sqlite_open(pTHX_ SV *dbh, const char *dbname, sqlite3 **db, int flags, int extended) { @@ -442,6 +449,26 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa int flag = 0; int unicode = 0; +#if SQLITE_VERSION_NUMBER >= 3006023 + /* + * "The sqlite3_config() interface may only be + * invoked prior to library initialization using + * sqlite3_initialize() or after shutdown by + * sqlite3_shutdown()." + * -- https://sqlite.org/c3ref/config.html + */ + sqlite3_config(SQLITE_CONFIG_LOG, _sqlite_log_callback, imp_dbh); +#endif + + /* + * "For maximum portability, it is recommended that + * applications always invoke sqlite3_initialize() + * directly prior to using any other SQLite interface. + * Future releases of SQLite may require this." + * -- https://sqlite.org/c3ref/initialize.html + */ + sqlite3_initialize(); + sqlite_trace(dbh, imp_dbh, 3, form("login '%s' (version %s)", dbname, sqlite3_version)); if (SvROK(attr)) { From c3209f468c56ddb3d7b9168f877cb08af52dc977 Mon Sep 17 00:00:00 2001 From: Bjoern Hoehrmann Date: Sun, 18 Apr 2021 14:40:18 +0200 Subject: [PATCH 2/2] found a way to get a proper handle; add test --- dbdimp.c | 52 ++++++++++++++++++++++++++-------------------- t/68_sqlite3_log.t | 23 ++++++++++++++++++++ 2 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 t/68_sqlite3_log.t diff --git a/dbdimp.c b/dbdimp.c index 2c40554..47b17e3 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -176,10 +176,17 @@ _sqlite_exec(pTHX_ SV *h, sqlite3 *db, const char *sql) } static void -_sqlite_log_callback(void *imp_dbh, int error_code, const char *message) +_sqlite_log_callback(void *unused, int error_code, const char *message) { dTHX; - sqlite_trace(NULL, imp_dbh, 3, form("sqlite3_log %d, %s", error_code, message)); + + SV* drh = get_sv("DBD::SQLite::drh", 0); + + if (drh && SvOK(drh)) { + D_imp_drh(drh); + + sqlite_trace(NULL, imp_drh, 3, form("sqlite3_log %d, %s", error_code, message)); + } } int @@ -429,6 +436,27 @@ sqlite_init(dbistate_t *dbistate) { dTHX; DBISTATE_INIT; /* Initialize the DBI macros */ + +#if SQLITE_VERSION_NUMBER >= 3006023 + /* + * "The sqlite3_config() interface may only be + * invoked prior to library initialization using + * sqlite3_initialize() or after shutdown by + * sqlite3_shutdown()." + * -- https://sqlite.org/c3ref/config.html + */ + sqlite3_config(SQLITE_CONFIG_LOG, _sqlite_log_callback, NULL); +#endif + + /* + * "For maximum portability, it is recommended that + * applications always invoke sqlite3_initialize() + * directly prior to using any other SQLite interface. + * Future releases of SQLite may require this." + * -- https://sqlite.org/c3ref/initialize.html + */ + sqlite3_initialize(); + } int @@ -449,26 +477,6 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa int flag = 0; int unicode = 0; -#if SQLITE_VERSION_NUMBER >= 3006023 - /* - * "The sqlite3_config() interface may only be - * invoked prior to library initialization using - * sqlite3_initialize() or after shutdown by - * sqlite3_shutdown()." - * -- https://sqlite.org/c3ref/config.html - */ - sqlite3_config(SQLITE_CONFIG_LOG, _sqlite_log_callback, imp_dbh); -#endif - - /* - * "For maximum portability, it is recommended that - * applications always invoke sqlite3_initialize() - * directly prior to using any other SQLite interface. - * Future releases of SQLite may require this." - * -- https://sqlite.org/c3ref/initialize.html - */ - sqlite3_initialize(); - sqlite_trace(dbh, imp_dbh, 3, form("login '%s' (version %s)", dbname, sqlite3_version)); if (SvROK(attr)) { diff --git a/t/68_sqlite3_log.t b/t/68_sqlite3_log.t new file mode 100644 index 0000000..4e1758c --- /dev/null +++ b/t/68_sqlite3_log.t @@ -0,0 +1,23 @@ +use strict; +use warnings; +use lib "t/lib"; +use SQLiteTest qw/connect_ok requires_sqlite/; +use Test::More; +use if -d ".git", "Test::FailWarnings"; + +BEGIN { requires_sqlite('3.6.23') } + +open my $trace_fh, '>', \my $trace_string; + +DBI->trace(3, $trace_fh); + +my $dbh = connect_ok(PrintError => 0, RaiseError => 1); + +eval { + $dbh->selectrow_array(q{ SELECT FROM FROM }); +}; + +like $trace_string, qr/sqlite3_log/, + 'sqlite3_log messages forwarded to DBI tracing mechanism'; + +done_testing;