Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.5.0b4

Request #10018 DSN handling improvement
Submitted: 2007-02-03 12:13 UTC Modified: 2008-01-28 05:31 UTC
From: priyadi Assigned: quipo
Status: Closed Package: MDB2_Driver_oci8 (version 1.3.0)
PHP Version: 5.1.6 OS: Linux
Roadmaps: (Not assigned)    
Subscription  


 [2007-02-03 12:13 UTC] priyadi (Priyadi)
Description: ------------ several problems: - we can't specify DSN in terms of hostname, port and service name, at least not easily. - database emulation were broken (never tried this personally, though). it assumes service names and database names and usernames are the same thing. database names and usernames should be the same thing under emulation, but service names are certainly not. - the current database emulation code assumes oracle version 10 is being used, previous oracle version doesn't support 'easy connect' strings - and we still need to be compatible with people who already use oci8://user:pass@tnsname my proposed patch is below. it should allow oci8 DSN as follows: - oci8://user:pass@tnsname - oci8://user:pass@hostname/?service=servicename and under emulation: - oci8://user:pass@tnsname/dbname - oci8://user:pass@hostname/dbname?service=servicename (in both cases 'user' should get replaced by 'dbname') and I think the DSN documentation should be updated to include some oracle DSN examples. Test script: --------------- --- oci8.php.orig 2007-01-30 12:44:50.000000000 +0700 +++ oci8.php 2007-02-03 23:45:02.000000000 +0700 @@ -322,29 +322,35 @@ } $sid = ''; - if ($this->dsn['hostspec']) { - $sid = $this->dsn['hostspec']; - if (!$this->options['emulate_database'] && $this->database_name) { - $port = $service = ''; - if ($this->dsn['port']) { - $port = ':'.$this->dsn['port']; - } - $service = $this->database_name; - if (substr($service, 0, 1) !== '/') { - $service = '/'.$service; - } - $sid = '//'.$sid.$port.$service; - } - } elseif (!$this->options['emulate_database'] && $this->database_name) { - $sid = $this->database_name; - } else { - $sid = getenv('ORACLE_SID'); - } - - if (empty($sid)) { - return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, - 'it was not specified a valid Oracle Service Identifier (SID)', __FUNCTION__); - } + if ($this->dsn['service'] && $this->dsn['hostspec']) { + // oci8://username:password@foo.example.com[:port]/?service=service + // service name is given, it is assumed that hostspec is really a + // hostname, we try to construct an oracle connection + // string from this + $port = 1521; + if ($this->dsn['port']) $port = $this->dsn['port']; + $sid = sprintf("(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP) + (HOST=%s) (PORT=%s))) + (CONNECT_DATA=(SERVICE_NAME=%s)))", + $this->dsn['hostspec'], $port, + $this->dsn['service']); + } elseif ($this->dsn['hostspec']) { + // we are given something like 'oci8://username:password@foo/' + // we have hostspec but not a service name, now we assume that + // hostspec is a tnsname defined in tnsnames.ora + $sid = $this->dsn['hostspec']; + } else { + // oci://username:password@ + // if everything fails, we have to rely on environment variables + if (getenv('ORACLE_SID')) { + $sid = getenv('ORACLE_SID'); + } elseif ($sid = getenv('TWO_TASK')) { + $sid = getenv('TWO_TASK'); + } else { + return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'not a valid connection string or environment variable not set', __FUNCTION__); + } + } if (function_exists('oci_connect')) { if (isset($this->dsn['new_link'])

Comments

 [2007-02-19 11:46 UTC] quipo (Lorenzo Alberton)
This bug has been fixed in CVS. If this was a documentation problem, the fix will appear on pear.php.net by the end of next Sunday (CET). If this was a problem with the pear.php.net website, the change should be live shortly. Otherwise, the fix will appear in the package's next release. Thank you for the report and for helping us make PEAR better.
 [2008-01-28 05:23 UTC] troehr (Torsten Roehr)
I would like to see a change regarding the database name (only affects Oracle) in the MDB2::parseDSN() method. See line 891 of MDB2.php CVS R1.306: $dsn = null; This line leads to the database name not being set at all. This may not be necessary to establish a connection but when using MDB2 with DB_DataObject the latter relies on the database being set in the DSN array to be able to load the respective database schema. Therefore I would therefore like to see the following change: Replace $dsn = null; with $dsn = substr($proto_opts, strrpos($proto_opts, '/') + 1); This extracts everything after the last slash which usually should be the database name. Thanks and best regards, Torsten
 [2008-01-28 05:31 UTC] troehr (Torsten Roehr)
This bug has been fixed in CVS. If this was a documentation problem, the fix will appear on pear.php.net by the end of next Sunday (CET). If this was a problem with the pear.php.net website, the change should be live shortly. Otherwise, the fix will appear in the package's next release. Thank you for the report and for helping us make PEAR better. Sorry, made a mistake to reopen this ticket. My request is roughly but not directly related to this issue. I opened a new ticket at #12984. Torsten