From bfbd9f84ee0841fc176ceb0aac473e67b5f26981 Mon Sep 17 00:00:00 2001 From: "David E. Wheeler" Date: Thu, 4 Apr 2024 21:25:10 -0400 Subject: [PATCH] Update Oracle database DBI parameter generation Again. It now works as follows: - If there is not a hostname or port, just use the raw SID or service name as the database name: `dbi:Oracle:$name`. This is way 1 in the DBD::Oracle documentation - If there is a hostname or port, use the EZCONNECT syntax. This is way 3 in the DBD::Oracle documentation. - If there are query parameters, delimit them by `&` and not `;`. Use of a port without a host name may not be valid, but it seems most prudent to build an EZCONNECT that includes the port in this context and to let Oracle or DBD::Oracle reject it if appropriate. Thanks again to @vectro for the and diligence, testing, and patience with this issue (#22). --- Changes | 11 +++++++++++ lib/URI/oracle.pm | 27 +++++++++++++++++++++------ t/dbi.t | 26 ++++++++++++++++---------- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/Changes b/Changes index 708a894..ec5a11c 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,17 @@ Revision history for Perl extension URI::db. 0.22 + - Changed Oracle database DBI parameter generation as follows: + - If there is not a hostname or port, just use the raw SID or service + name as the database name: `dbi:Oracle:$name`. This is way 1 in the + DBD::Oracle documentation + - If there is a hostname or port, use the EZCONNECT syntax. This is + way 3 in the DBD::Oracle documentation. + Use of a port without a host name may not be valid, but it seems most + prudent to build an EZCONNECT that includes the port in this context + and to let Oracle or DBD::Oracle reject it if appropriate. Thanks + again to @vectro for the and diligence, testing, and patience with + this issue (#22). 0.21 2023-05-09T22:18:52Z - Changed Oracle database DBI parameter name from `sid` to diff --git a/lib/URI/oracle.pm b/lib/URI/oracle.pm index 4520c20..965de33 100644 --- a/lib/URI/oracle.pm +++ b/lib/URI/oracle.pm @@ -5,13 +5,28 @@ our $VERSION = '0.22'; sub default_port { 1521 } sub dbi_driver { 'Oracle' } -sub _dbi_param_map { +sub _dsn_params { my $self = shift; - return ( - [ host => scalar $self->host ], - [ port => scalar $self->_port ], - [ service_name => scalar $self->dbname ], - ); + my $name = $self->dbname || ''; + my $dsn = $self->host; + + if (my $p = $self->_port) { + $dsn .= ":$p"; + } + + return $name unless $dsn; + $dsn .= "/$name"; + + + if (my @p = $self->query_params) { + my @kvpairs; + while (@p) { + push @kvpairs => join '=', shift @p, shift @p; + } + $dsn .= '?' . join '&' => @kvpairs; + } + + return "//$dsn"; } 1; diff --git a/t/dbi.t b/t/dbi.t index a256fbe..0ca3ea5 100644 --- a/t/dbi.t +++ b/t/dbi.t @@ -206,34 +206,40 @@ for my $spec ( }, { uri => 'db:oracle://localhost:33/foo', - dsn => 'dbi:Oracle:host=localhost;port=33;service_name=foo', - dbi => [ [host => 'localhost'], [port => 33], [service_name => 'foo'] ], + dsn => 'dbi:Oracle://localhost:33/foo', + dbi => [ [host => 'localhost'], [port => 33], [dbname => 'foo'] ], qry => [], }, { uri => 'db:oracle://localhost/foo', - dsn => 'dbi:Oracle:host=localhost;service_name=foo', - dbi => [ [host => 'localhost'], [port => undef], [service_name => 'foo'] ], + dsn => 'dbi:Oracle://localhost/foo', + dbi => [ [host => 'localhost'], [port => undef], [dbname => 'foo'] ], qry => [], }, { uri => 'db:oracle://:42/foo', - dsn => 'dbi:Oracle:port=42;service_name=foo', - dbi => [ [host => ''], [port => 42], [service_name => 'foo'] ], + dsn => 'dbi:Oracle://:42/foo', + dbi => [ [host => ''], [port => 42], [dbname => 'foo'] ], qry => [], }, { uri => 'db:oracle:foo', - dsn => 'dbi:Oracle:service_name=foo', - dbi => [ [host => undef], [port => undef], [service_name => 'foo'] ], + dsn => 'dbi:Oracle:foo', + dbi => [ [host => undef], [port => undef], [dbname => 'foo'] ], qry => [], }, { uri => 'db:oracle:///foo', - dsn => 'dbi:Oracle:service_name=foo', - dbi => [ [host => ''], [port => undef], [service_name => 'foo'] ], + dsn => 'dbi:Oracle:foo', + dbi => [ [host => ''], [port => undef], [dbname => 'foo'] ], qry => [], }, + { + uri => 'db:oracle://:42/foo?x=y;a=b', + dsn => 'dbi:Oracle://:42/foo?x=y&a=b', + dbi => [ [host => ''], [port => 42], [dbname => 'foo'] ], + qry => [ x => 'y', a => 'b' ], + }, { uri => 'db:mssql:', dsn => 'dbi:ODBC:',