From b1ac23d02ef62583714dcc532464fcfdc56c21d7 Mon Sep 17 00:00:00 2001 From: Kenichi Ishigaki Date: Sun, 28 Jul 2013 17:11:16 +0900 Subject: [PATCH] supported sqlite3_open_v2 flags --- SQLite.xs | 56 +++++++++++++++++++++++++++++++++++++++++++++++ dbdimp.c | 17 ++++++++++---- lib/DBD/SQLite.pm | 11 +++++++++- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/SQLite.xs b/SQLite.xs index bac5bc7..a50a160 100644 --- a/SQLite.xs +++ b/SQLite.xs @@ -576,6 +576,62 @@ SAVEPOINT() OUTPUT: RETVAL +static int +OPEN_READONLY() + CODE: + RETVAL = SQLITE_OPEN_READONLY; + OUTPUT: + RETVAL + +static int +OPEN_READWRITE() + CODE: + RETVAL = SQLITE_OPEN_READWRITE; + OUTPUT: + RETVAL + +static int +OPEN_CREATE() + CODE: + RETVAL = SQLITE_OPEN_CREATE; + OUTPUT: + RETVAL + +static int +OPEN_NOMUTEX() + CODE: + RETVAL = SQLITE_OPEN_NOMUTEX; + OUTPUT: + RETVAL + +static int +OPEN_FULLMUTEX() + CODE: + RETVAL = SQLITE_OPEN_FULLMUTEX; + OUTPUT: + RETVAL + +static int +OPEN_SHAREDCACHE() + CODE: + RETVAL = SQLITE_OPEN_SHAREDCACHE; + OUTPUT: + RETVAL + +static int +OPEN_PRIVATECACHE() + CODE: + RETVAL = SQLITE_OPEN_PRIVATECACHE; + OUTPUT: + RETVAL + +static int +OPEN_URI() + CODE: + RETVAL = SQLITE_OPEN_URI; + OUTPUT: + RETVAL + INCLUDE: SQLite.xsi diff --git a/dbdimp.c b/dbdimp.c index 1201b54..db3de2c 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -38,7 +38,8 @@ imp_dbh_t *last_executed_dbh; /* needed by perl_tokenizer #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_exec(h,sql) _sqlite_exec(aTHX_ h, imp_dbh->db, sql) -#define sqlite_open(dbname,db) _sqlite_open(aTHX_ dbh, dbname, db) +#define sqlite_open(dbname,db) _sqlite_open(aTHX_ dbh, dbname, db, 0) +#define sqlite_open2(dbname,db,flags) _sqlite_open(aTHX_ dbh, dbname, db, flags) #define _isspace(c) (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f') static void @@ -83,10 +84,14 @@ _sqlite_exec(pTHX_ SV *h, sqlite3 *db, const char *sql) } int -_sqlite_open(pTHX_ SV *dbh, const char *dbname, sqlite3 **db) +_sqlite_open(pTHX_ SV *dbh, const char *dbname, sqlite3 **db, int flags) { int rc; - rc = sqlite3_open(dbname, db); + if (flags) { + rc = sqlite3_open_v2(dbname, db, flags, NULL); + } else { + rc = sqlite3_open(dbname, db); + } if ( rc != SQLITE_OK ) { sqlite_error(dbh, rc, sqlite3_errmsg(*db)); if (*db) sqlite3_close(*db); @@ -273,7 +278,11 @@ sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pa sqlite_trace(dbh, imp_dbh, 3, form("login '%s' (version %s)", dbname, sqlite3_version)); - rc = sqlite_open(dbname, &(imp_dbh->db)); + if (SvROK(attr) && hv_exists((HV*)SvRV(attr), "sqlite_open_flags", 17)) { + rc = sqlite_open2(dbname, &(imp_dbh->db), SvIV(*hv_fetch((HV*)SvRV(attr), "sqlite_open_flags", 17, NULL))); + } else { + rc = sqlite_open(dbname, &(imp_dbh->db)); + } if ( rc != SQLITE_OK ) { return FALSE; /* -> undef in lib/DBD/SQLite.pm */ } diff --git a/lib/DBD/SQLite.pm b/lib/DBD/SQLite.pm index 7429534..6e1defa 100644 --- a/lib/DBD/SQLite.pm +++ b/lib/DBD/SQLite.pm @@ -95,15 +95,24 @@ sub connect { my ($key, $value) = split(/=/, $attrib, 2); if ( $key =~ /^(?:db(?:name)?|database)$/ ) { $real = $value; + } elsif ( $key eq 'uri' ) { + $real = $value; + $attr->{sqlite_open_flags} |= DBD::SQLite::OPEN_URI(); } else { $attr->{$key} = $value; } } } + if (my $flags = $attr->{sqlite_open_flags}) { + unless ($flags & (DBD::SQLite::OPEN_READONLY() | DBD::SQLite::OPEN_READWRITE())) { + $attr->{sqlite_open_flags} |= DBD::SQLite::OPEN_READWRITE() | DBD::SQLite::OPEN_CREATE(); + } + } + # To avoid unicode and long file name problems on Windows, # convert to the shortname if the file (or parent directory) exists. - if ( $^O =~ /MSWin32/ and $real ne ':memory:' and $real ne '') { + if ( $^O =~ /MSWin32/ and $real ne ':memory:' and $real ne '' and $real !~ /^file:/) { require Win32; require File::Basename; my ($file, $dir, $suffix) = File::Basename::fileparse($real);