mirror of
https://github.com/DBD-SQLite/DBD-SQLite
synced 2025-06-07 14:19:10 -04:00
supported extended result codes
This commit is contained in:
parent
fcf0a54cab
commit
b1975f1e97
4 changed files with 81 additions and 7 deletions
1
MANIFEST
1
MANIFEST
|
@ -81,6 +81,7 @@ t/55_statistics_info.t
|
||||||
t/56_open_flags.t
|
t/56_open_flags.t
|
||||||
t/57_uri_filename.t
|
t/57_uri_filename.t
|
||||||
t/58_see_if_its_a_number_and_explicit_binding.t
|
t/58_see_if_its_a_number_and_explicit_binding.t
|
||||||
|
t/59_extended_result_codes.t
|
||||||
t/cookbook_variance.t
|
t/cookbook_variance.t
|
||||||
t/lib/Test.pm
|
t/lib/Test.pm
|
||||||
t/rt_15186_prepcached.t
|
t/rt_15186_prepcached.t
|
||||||
|
|
36
dbdimp.c
36
dbdimp.c
|
@ -37,8 +37,8 @@ static int last_dbh_is_unicode; /* see _last_dbh_is_unicode() */
|
||||||
#define sqlite_error(h,rc,what) _sqlite_error(aTHX_ __FILE__, __LINE__, h, rc, what)
|
#define sqlite_error(h,rc,what) _sqlite_error(aTHX_ __FILE__, __LINE__, h, rc, what)
|
||||||
#define sqlite_trace(h,xxh,level,what) if ( DBIc_TRACE_LEVEL((imp_xxh_t*)xxh) >= level ) _sqlite_trace(aTHX_ __FILE__, __LINE__, h, (imp_xxh_t*)xxh, what)
|
#define sqlite_trace(h,xxh,level,what) if ( DBIc_TRACE_LEVEL((imp_xxh_t*)xxh) >= level ) _sqlite_trace(aTHX_ __FILE__, __LINE__, h, (imp_xxh_t*)xxh, what)
|
||||||
#define sqlite_exec(h,sql) _sqlite_exec(aTHX_ h, imp_dbh->db, sql)
|
#define sqlite_exec(h,sql) _sqlite_exec(aTHX_ h, imp_dbh->db, sql)
|
||||||
#define sqlite_open(dbname,db) _sqlite_open(aTHX_ dbh, dbname, db, 0)
|
#define sqlite_open(dbname,db) _sqlite_open(aTHX_ dbh, dbname, db, 0, 0)
|
||||||
#define sqlite_open2(dbname,db,flags) _sqlite_open(aTHX_ dbh, dbname, db, flags)
|
#define sqlite_open2(dbname,db,flags,extended) _sqlite_open(aTHX_ dbh, dbname, db, flags, extended)
|
||||||
#define _isspace(c) (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f')
|
#define _isspace(c) (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f')
|
||||||
|
|
||||||
#define _skip_whitespaces(sql) \
|
#define _skip_whitespaces(sql) \
|
||||||
|
@ -245,7 +245,7 @@ _sqlite_exec(pTHX_ SV *h, sqlite3 *db, const char *sql)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_sqlite_open(pTHX_ SV *dbh, const char *dbname, sqlite3 **db, int flags)
|
_sqlite_open(pTHX_ SV *dbh, const char *dbname, sqlite3 **db, int flags, int extended)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
if (flags) {
|
if (flags) {
|
||||||
|
@ -254,6 +254,8 @@ _sqlite_open(pTHX_ SV *dbh, const char *dbname, sqlite3 **db, int flags)
|
||||||
rc = sqlite3_open(dbname, db);
|
rc = sqlite3_open(dbname, db);
|
||||||
}
|
}
|
||||||
if ( rc != SQLITE_OK ) {
|
if ( rc != SQLITE_OK ) {
|
||||||
|
if (extended)
|
||||||
|
rc = sqlite3_extended_errcode(*db);
|
||||||
sqlite_error(dbh, rc, sqlite3_errmsg(*db));
|
sqlite_error(dbh, rc, sqlite3_errmsg(*db));
|
||||||
if (*db) sqlite3_close(*db);
|
if (*db) sqlite3_close(*db);
|
||||||
}
|
}
|
||||||
|
@ -464,14 +466,25 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa
|
||||||
{
|
{
|
||||||
dTHX;
|
dTHX;
|
||||||
int rc;
|
int rc;
|
||||||
|
HV *hv;
|
||||||
|
SV **val;
|
||||||
|
int extended = 0;
|
||||||
|
int flag = 0;
|
||||||
|
|
||||||
sqlite_trace(dbh, imp_dbh, 3, form("login '%s' (version %s)", dbname, sqlite3_version));
|
sqlite_trace(dbh, imp_dbh, 3, form("login '%s' (version %s)", dbname, sqlite3_version));
|
||||||
|
|
||||||
if (SvROK(attr) && hv_exists((HV*)SvRV(attr), "sqlite_open_flags", 17)) {
|
if (SvROK(attr)) {
|
||||||
rc = sqlite_open2(dbname, &(imp_dbh->db), SvIV(*hv_fetch((HV*)SvRV(attr), "sqlite_open_flags", 17, 0)));
|
hv = (HV*)SvRV(attr);
|
||||||
} else {
|
if (hv_exists(hv, "sqlite_extended_result_codes", 28)) {
|
||||||
rc = sqlite_open(dbname, &(imp_dbh->db));
|
val = hv_fetch(hv, "sqlite_extended_result_codes", 28, 0);
|
||||||
|
extended = (val && SvOK(*val)) ? !(!SvTRUE(*val)) : 0;
|
||||||
|
}
|
||||||
|
if (hv_exists(hv, "sqlite_open_flags", 17)) {
|
||||||
|
val = hv_fetch(hv, "sqlite_open_flags", 17, 0);
|
||||||
|
flag = (val && SvOK(*val)) ? SvIV(*val) : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
rc = sqlite_open2(dbname, &(imp_dbh->db), flag, extended);
|
||||||
if ( rc != SQLITE_OK ) {
|
if ( rc != SQLITE_OK ) {
|
||||||
return FALSE; /* -> undef in lib/DBD/SQLite.pm */
|
return FALSE; /* -> undef in lib/DBD/SQLite.pm */
|
||||||
}
|
}
|
||||||
|
@ -486,6 +499,7 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa
|
||||||
imp_dbh->allow_multiple_statements = FALSE;
|
imp_dbh->allow_multiple_statements = FALSE;
|
||||||
imp_dbh->use_immediate_transaction = TRUE;
|
imp_dbh->use_immediate_transaction = TRUE;
|
||||||
imp_dbh->see_if_its_a_number = FALSE;
|
imp_dbh->see_if_its_a_number = FALSE;
|
||||||
|
imp_dbh->extended_result_codes = extended;
|
||||||
imp_dbh->stmt_list = NULL;
|
imp_dbh->stmt_list = NULL;
|
||||||
|
|
||||||
sqlite3_busy_timeout(imp_dbh->db, SQL_TIMEOUT);
|
sqlite3_busy_timeout(imp_dbh->db, SQL_TIMEOUT);
|
||||||
|
@ -752,6 +766,11 @@ sqlite_db_STORE_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)
|
||||||
imp_dbh->see_if_its_a_number = !(! SvTRUE(valuesv));
|
imp_dbh->see_if_its_a_number = !(! SvTRUE(valuesv));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
if (strEQ(key, "sqlite_extended_result_codes")) {
|
||||||
|
imp_dbh->extended_result_codes = !(! SvTRUE(valuesv));
|
||||||
|
sqlite3_extended_result_codes(imp_dbh->db, imp_dbh->extended_result_codes);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
if (strEQ(key, "sqlite_unicode")) {
|
if (strEQ(key, "sqlite_unicode")) {
|
||||||
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||||
sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
|
sqlite_trace(dbh, imp_dbh, 3, form("Unicode support is disabled for this version of perl."));
|
||||||
|
@ -793,6 +812,9 @@ sqlite_db_FETCH_attrib(SV *dbh, imp_dbh_t *imp_dbh, SV *keysv)
|
||||||
if (strEQ(key, "sqlite_see_if_its_a_number")) {
|
if (strEQ(key, "sqlite_see_if_its_a_number")) {
|
||||||
return sv_2mortal(newSViv(imp_dbh->see_if_its_a_number ? 1 : 0));
|
return sv_2mortal(newSViv(imp_dbh->see_if_its_a_number ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
if (strEQ(key, "sqlite_extended_result_codes")) {
|
||||||
|
return sv_2mortal(newSViv(imp_dbh->extended_result_codes ? 1 : 0));
|
||||||
|
}
|
||||||
if (strEQ(key, "sqlite_unicode")) {
|
if (strEQ(key, "sqlite_unicode")) {
|
||||||
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
#if PERL_UNICODE_DOES_NOT_WORK_WELL
|
||||||
sqlite_trace(dbh, imp_dbh, 3, "Unicode support is disabled for this version of perl.");
|
sqlite_trace(dbh, imp_dbh, 3, "Unicode support is disabled for this version of perl.");
|
||||||
|
|
1
dbdimp.h
1
dbdimp.h
|
@ -44,6 +44,7 @@ struct imp_dbh_st {
|
||||||
bool allow_multiple_statements;
|
bool allow_multiple_statements;
|
||||||
bool use_immediate_transaction;
|
bool use_immediate_transaction;
|
||||||
bool see_if_its_a_number;
|
bool see_if_its_a_number;
|
||||||
|
int extended_result_codes;
|
||||||
stmt_list_s * stmt_list;
|
stmt_list_s * stmt_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
50
t/59_extended_result_codes.t
Normal file
50
t/59_extended_result_codes.t
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
BEGIN {
|
||||||
|
$| = 1;
|
||||||
|
$^W = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
use t::lib::Test qw/connect_ok/;
|
||||||
|
use Test::More;
|
||||||
|
use Test::NoWarnings;
|
||||||
|
use DBD::SQLite::Constants qw/:extended_result_codes :result_codes/;
|
||||||
|
use File::Temp;
|
||||||
|
|
||||||
|
plan tests => 18;
|
||||||
|
|
||||||
|
my $tmpdir = File::Temp::tempdir(CLEANUP => 1);
|
||||||
|
ok -d $tmpdir;
|
||||||
|
|
||||||
|
my %expected = (
|
||||||
|
0 => SQLITE_CANTOPEN,
|
||||||
|
1 => SQLITE_CANTOPEN_ISDIR,
|
||||||
|
);
|
||||||
|
|
||||||
|
# opening a directory as a database causes SQLITE_CANTOPEN(_ISDIR)
|
||||||
|
for my $flag (0, 1) {
|
||||||
|
my $dbh = connect_ok(
|
||||||
|
RaiseError => 0,
|
||||||
|
PrintError => 0,
|
||||||
|
sqlite_extended_result_codes => $flag,
|
||||||
|
);
|
||||||
|
ok !$dbh->do(qq{attach '$tmpdir' as tmp});
|
||||||
|
is $dbh->err => $expected{$flag};
|
||||||
|
|
||||||
|
$dbh->{sqlite_extended_result_codes} = 1 - $flag;
|
||||||
|
is $dbh->{sqlite_extended_result_codes} => 1 - $flag;
|
||||||
|
ok !$dbh->do(qq{attach '$tmpdir' as tmp});
|
||||||
|
is $dbh->err => $expected{1 - $flag};
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $flag (0, 1) {
|
||||||
|
my $dbh = DBI->connect("dbi:SQLite:$tmpdir", '', '', {
|
||||||
|
RaiseError => 0,
|
||||||
|
PrintError => 0,
|
||||||
|
sqlite_extended_result_codes => $flag,
|
||||||
|
});
|
||||||
|
ok !$dbh, "Shouldn't be able to open a temporary directory as a database";
|
||||||
|
my $err = DBI->err;
|
||||||
|
is $err => $expected{$flag};
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue