Fix parsing DSN when the driver part includes DBI attributes
Fabrice Gabolde [Fri, 1 Apr 2016 13:05:42 +0000 (15:05 +0200)]
AUTHORS
Changes
lib/DBIx/Class/Storage/DBI.pm
t/lib/DBICTest/BaseSchema.pm
t/storage/dbi_env.t

diff --git a/AUTHORS b/AUTHORS
index 5193ba8..f4f97f1 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -74,6 +74,7 @@ ether: Karen Etheridge <ether@cpan.org>
 evdb: Edmund von der Burg <evdb@ecclestoad.co.uk>
 faxm0dem: Fabien Wernli <cpan@faxm0dem.org>
 felliott: Fitz Elliott <fitz.elliott@gmail.com>
+fgabolde: Fabrice Gabolde <fgabolde@weborama.com>
 freetime: Bill Moseley <moseley@hank.org>
 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
 gbjk: Gareth Kirwan <gbjk@thermeon.com>
diff --git a/Changes b/Changes
index 5aa2ea5..8ce62d6 100644 (file)
--- a/Changes
+++ b/Changes
@@ -50,6 +50,7 @@ Revision history for DBIx::Class
           of a transaction with deferred FK checks: a guard is now inactivated
           immediately before the commit is attempted (RT#107159)
         - Fix spurious warning on MSSQL cursor invalidation retries (RT#102166)
+        - Fix parsing of DSNs containing driver arguments (GH#99)
         - Work around unreliable $sth->finish() on INSERT ... RETURNING within
           DBD::Firebird on some compiler/driver combinations (RT#110979)
         - Really fix savepoint rollbacks on older DBD::SQLite (fix in 0.082800
index 01c8dcc..adcd6b4 100644 (file)
@@ -1377,7 +1377,16 @@ sub _extract_driver_from_connect_info {
     # try to use dsn to not require being connected, the driver may still
     # force a connection later in _rebless to determine version
     # (dsn may not be supplied at all if all we do is make a mock-schema)
-    ($drv) = ($self->_dbi_connect_info->[0] || '') =~ /^dbi:([^:]+):/i;
+    #
+    # Use the same regex as the one used by DBI itself (even if the use of
+    # \w is odd given unicode):
+    # https://metacpan.org/source/TIMB/DBI-1.634/DBI.pm#L621
+    #
+    # DO NOT use https://metacpan.org/source/TIMB/DBI-1.634/DBI.pm#L559-566
+    # as there is a long-standing precedent of not loading DBI.pm until the
+    # very moment we are actually connecting
+    #
+    ($drv) = ($self->_dbi_connect_info->[0] || '') =~ /^dbi:(\w*)/i;
     $drv ||= $ENV{DBI_DRIVER};
   }
 
index 111b84b..2663530 100644 (file)
@@ -224,7 +224,7 @@ sub connection {
       and
     ref($_[0]) ne 'CODE'
       and
-    ($_[0]||'') !~ /^ (?i:dbi) \: SQLite \: (?: dbname\= )? (?: \:memory\: | t [\/\\] var [\/\\] DBIxClass\-) /x
+    ($_[0]||'') !~ /^ (?i:dbi) \: SQLite (?: \: | \W ) .*? (?: dbname\= )? (?: \:memory\: | t [\/\\] var [\/\\] DBIxClass\-) /x
   ) {
 
     my $locktype;
index 4e71ce5..7b9ccc8 100644 (file)
@@ -79,6 +79,10 @@ $schema = DBICTest::Schema->connect("dbi:SQLite:$dbname");
 lives_ok { count_sheep($schema) } 'SQLite passed to connect_info';
 isa_ok $schema->storage, 'DBIx::Class::Storage::DBI::SQLite';
 
+$schema = DBICTest::Schema->connect("dbi:SQLite(ReadOnly=1):$dbname");
+lives_ok { count_sheep($schema) } 'SQLite passed to connect_info despite extra arguments present';
+isa_ok $schema->storage, 'DBIx::Class::Storage::DBI::SQLite';
+
 $ENV{DBI_DRIVER} = 'SQLite';
 $schema = DBICTest::Schema->connect("dbi::$dbname");
 lives_ok { count_sheep($schema) } 'SQLite in DBI_DRIVER';