From 3363414db36da1138babf6b1f5ce781c2b798ec9 Mon Sep 17 00:00:00 2001 From: Kenichi Ishigaki Date: Fri, 12 Jul 2019 02:01:41 +0900 Subject: [PATCH] expose sqlite3_get_autocommit (fix #52) --- MANIFEST | 1 + SQLite.xs | 12 +++++++++ dbdimp.c | 7 ++++++ dbdimp.h | 1 + lib/DBD/SQLite.pm | 7 ++++++ t/66_get_autocommit.t | 57 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+) create mode 100644 t/66_get_autocommit.t diff --git a/MANIFEST b/MANIFEST index c53f269..dd95132 100644 --- a/MANIFEST +++ b/MANIFEST @@ -90,6 +90,7 @@ t/62_regexp_multibyte_char_class.t t/63_param_values.t t/64_limit.t t/65_db_config.t +t/66_get_autocommit.t t/cookbook_variance.t t/lib/SQLiteTest.pm t/rt_106151_outermost_savepoint.t diff --git a/SQLite.xs b/SQLite.xs index 2e718eb..122de79 100644 --- a/SQLite.xs +++ b/SQLite.xs @@ -368,6 +368,18 @@ db_config(dbh, id, new_value = -1) OUTPUT: RETVAL +static int +get_autocommit(dbh) + SV *dbh + ALIAS: + DBD::SQLite::db::sqlite_get_autocommit = 1 + CODE: + { + RETVAL = sqlite_db_get_autocommit(aTHX_ dbh); + } + OUTPUT: + RETVAL + MODULE = DBD::SQLite PACKAGE = DBD::SQLite::st PROTOTYPES: DISABLE diff --git a/dbdimp.c b/dbdimp.c index 7d38b7c..5fabc0a 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -2801,6 +2801,13 @@ sqlite_db_config(pTHX_ SV *dbh, int id, int new_value) return ret; } +int +sqlite_db_get_autocommit(pTHX_ SV *dbh) +{ + D_imp_dbh(dbh); + return sqlite3_get_autocommit(imp_dbh->db); +} + #include "dbdimp_tokenizer.inc" #include "dbdimp_virtual_table.inc" diff --git a/dbdimp.h b/dbdimp.h index 1b46d53..3f5cc54 100644 --- a/dbdimp.h +++ b/dbdimp.h @@ -136,6 +136,7 @@ HV* _sqlite_st_status(pTHX_ SV *sth, int reset); int sqlite_db_create_module(pTHX_ SV *dbh, const char *name, const char *perl_class); int sqlite_db_limit(pTHX_ SV *dbh, int id, int new_value); int sqlite_db_config(pTHX_ SV *dbh, int id, int new_value); +int sqlite_db_get_autocommit(pTHX_ SV *dbh); int sqlite_db_do_sv(SV *dbh, imp_dbh_t *imp_dbh, SV *sv_statement); void init_cxt(); diff --git a/lib/DBD/SQLite.pm b/lib/DBD/SQLite.pm index 32c1cd2..6742b05 100644 --- a/lib/DBD/SQLite.pm +++ b/lib/DBD/SQLite.pm @@ -61,6 +61,7 @@ sub driver { DBD::SQLite::db->install_method('sqlite_create_module'); DBD::SQLite::db->install_method('sqlite_limit'); DBD::SQLite::db->install_method('sqlite_db_config'); + DBD::SQLite::db->install_method('sqlite_get_autocommit'); $methods_are_installed++; } @@ -2356,6 +2357,12 @@ If the new value is a negative number (or omitted), the limit is unchanged and just returns the current limit. Category ids (SQLITE_LIMIT_LENGTH, SQLITE_LIMIT_VARIABLE_NUMBER, etc) can be imported from DBD::SQLite::Constants. +=head2 $dbh->sqlite_get_autocommit() + +Returns true if the internal SQLite connection is in an autocommit mode. +This does not always return the same value as C<< $dbh->{AutoCommit} >>. +This returns false if you explicitly issue a C<> statement. + =head1 DRIVER FUNCTIONS =head2 DBD::SQLite::compile_options() diff --git a/t/66_get_autocommit.t b/t/66_get_autocommit.t new file mode 100644 index 0000000..a8103d4 --- /dev/null +++ b/t/66_get_autocommit.t @@ -0,0 +1,57 @@ +use strict; +use warnings; +use lib "t/lib"; +use SQLiteTest qw/connect_ok @CALL_FUNCS/; +use Test::More; +use if -d ".git", "Test::FailWarnings"; + +for my $func (@CALL_FUNCS) { + my $dbh = connect_ok(PrintError => 0, RaiseError => 1); + $dbh->do('create table foo (id)'); + + note 'begin_work does not make autocommit false'; + my $autocommit = $dbh->$func('get_autocommit'); + ok $autocommit, "internal autocommit is true"; + ok $dbh->{AutoCommit}, "AutoCommit is also true"; + + $dbh->begin_work; + $autocommit = $dbh->$func('get_autocommit'); + ok $autocommit, "internal autocommit is still true"; + ok !$dbh->{AutoCommit}, "AutoCommit gets false"; + + $dbh->do('insert into foo values (1)'); + $dbh->commit; + + $autocommit = $dbh->$func('get_autocommit'); + ok $autocommit, "internal autocommit is still true"; + ok $dbh->{AutoCommit}, "AutoCommit is true now"; + + note 'nor turning AutoCommit off does not make autocommit false'; + $dbh->{AutoCommit} = 0; + $autocommit = $dbh->$func('get_autocommit'); + ok $autocommit, "internal autocommit is still true"; + ok !$dbh->{AutoCommit}, "AutoCommit is false"; + + $dbh->do('insert into foo values (1)'); + $dbh->commit; + $dbh->{AutoCommit} = 1; + + $autocommit = $dbh->$func('get_autocommit'); + ok $autocommit, "internal autocommit is still true"; + ok $dbh->{AutoCommit}, "AutoCommit is true now"; + + note 'explicit BEGIN make autocommit false'; + $dbh->do('BEGIN'); + $autocommit = $dbh->$func('get_autocommit'); + ok !$autocommit, "internal autocommit gets false"; + ok !$dbh->{AutoCommit}, "AutoCommit is also false"; + + $dbh->do('insert into foo values (1)'); + $dbh->commit; + + $autocommit = $dbh->$func('get_autocommit'); + ok $autocommit, "internal autocommit is true now"; + ok $dbh->{AutoCommit}, "AutoCommit is true now"; +} + +done_testing;