. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of Sebastian Bergmann nor the names of his * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @category Testing * @package PHPUnit * @author Sebastian Bergmann * @copyright 2002-2008 Sebastian Bergmann * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version SVN: $Id: PDO.php 1985 2007-12-26 18:11:55Z sb $ * @link http://www.phpunit.de/ * @since File available since Release 3.1.4 */ require_once 'PHPUnit/Util/Filter.php'; PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); /** * PDO helpers. * * @category Testing * @package PHPUnit * @author Sebastian Bergmann * @copyright 2002-2008 Sebastian Bergmann * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @version Release: 3.2.9 * @link http://www.phpunit.de/ * @since Class available since Release 3.1.4 */ class PHPUnit_Util_PDO { public static function factory($dsn) { $parsed = self::parseDSN($dsn); switch ($parsed['phptype']) { case 'mysql': { $database = null; $charset = null; $host = null; $port = null; $socket = null; $user = null; $pass = null; $driverOptions = null; foreach ($parsed as $key => $val) { switch ($key) { case 'database': case 'dbname': $database = $val; break; case 'charset': $charset = $val; break; case 'host': case 'hostspec': $host = $val; break; case 'port': $port = $val; break; case 'socket': $socket = $val; break; case 'user': case 'username': $user = $val; break; case 'pass': case 'password': $pass = $val; break; case 'driver-opts': $driverOptions = $val; break; } } if (! isset($database)) { throw new InvalidArgumentException(); } $dsn = "mysql:dbname=$database"; if (isset($host) && $host) { $dsn .= ";host=$host"; } if (isset($port) && $port) { $dsn .= ";port=$port"; } if (isset($charset) && $charset) { $dsn .= ";charset=$charset"; } if (isset($socket) && $socket) { $dsn .= ";unix_socket=$socket"; } $dbh = new PDO($dsn, $user, $pass, $driverOptions); } break; case 'sqlite': { $dbh = new PDO($dsn); } break; default: { throw new InvalidArgumentException(); } } $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $dbh; } /** * Returns the Data Source Name as a structure containing the various parts of the DSN. * * Additional keys can be added by appending a URI query string to the * end of the DSN. * * The format of the supplied DSN is in its fullest form: * * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true * * * Most variations are allowed: * * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 * phptype://username:password@hostspec/database_name * phptype://username:password@hostspec * phptype://username@hostspec * phptype://hostspec/database * phptype://hostspec * phptype(dbsyntax) * phptype * * * This function is 'borrowed' from PEAR /DB.php . * * @param string $dsn Data Source Name to be parsed * * @return array an associative array with the following keys: * + phptype: Database backend used in PHP (mysql, odbc etc.) * + dbsyntax: Database used with regards to SQL syntax etc. * + protocol: Communication protocol to use (tcp, unix etc.) * + hostspec: Host specification (hostname[:port]) * + database: Database to use on the DBMS server * + username: User name for login * + password: Password for login */ public static function parseDSN($dsn) { $parsed = array('phptype' => false, 'dbsyntax' => false, 'username' => false, 'password' => false, 'protocol' => false, 'hostspec' => false, 'port' => false, 'socket' => false, 'database' => false); if (is_array($dsn)) { $dsn = array_merge($parsed, $dsn); if (! $dsn['dbsyntax']) { $dsn['dbsyntax'] = $dsn['phptype']; } return $dsn; } // Find phptype and dbsyntax if (($pos = strpos($dsn, '://')) !== false) { $str = substr($dsn, 0, $pos); $dsn = substr($dsn, $pos + 3); } else { $str = $dsn; $dsn = null; } // Get phptype and dbsyntax // $str => phptype(dbsyntax) if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { $parsed['phptype'] = $arr[1]; $parsed['dbsyntax'] = ! $arr[2] ? $arr[1] : $arr[2]; } else { $parsed['phptype'] = $str; $parsed['dbsyntax'] = $str; } if (! count($dsn)) { return $parsed; } // Get (if found): username and password // $dsn => username:password@protocol+hostspec/database if (($at = strrpos((string)$dsn, '@')) !== false) { $str = substr($dsn, 0, $at); $dsn = substr($dsn, $at + 1); if (($pos = strpos($str, ':')) !== false) { $parsed['username'] = rawurldecode(substr($str, 0, $pos)); $parsed['password'] = rawurldecode(substr($str, $pos + 1)); } else { $parsed['username'] = rawurldecode($str); } } // Find protocol and hostspec if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { // $dsn => proto(proto_opts)/database $proto = $match[1]; $proto_opts = $match[2] ? $match[2] : false; $dsn = $match[3]; } else { // $dsn => protocol+hostspec/database (old format) if (strpos($dsn, '+') !== false) { list($proto, $dsn) = explode('+', $dsn, 2); } if (strpos($dsn, '/') !== false) { list($proto_opts, $dsn) = explode('/', $dsn, 2); } else { $proto_opts = $dsn; $dsn = null; } } // process the different protocol options $parsed['protocol'] = (! empty($proto)) ? $proto : 'tcp'; $proto_opts = rawurldecode($proto_opts); if ($parsed['protocol'] == 'tcp') { if (strpos($proto_opts, ':') !== false) { list($parsed['hostspec'], $parsed['port']) = explode(':', $proto_opts); } else { $parsed['hostspec'] = $proto_opts; } } elseif ($parsed['protocol'] == 'unix') { $parsed['socket'] = $proto_opts; } // Get dabase if any // $dsn => database if ($dsn) { if (($pos = strpos($dsn, '?')) === false) { // /database $parsed['database'] = rawurldecode($dsn); } else { // /database?param1=value1¶m2=value2 $parsed['database'] = rawurldecode(substr($dsn, 0, $pos)); $dsn = substr($dsn, $pos + 1); if (strpos($dsn, '&') !== false) { $opts = explode('&', $dsn); } else { // database?param1=value1 $opts = array($dsn); } foreach ($opts as $opt) { list($key, $value) = explode('=', $opt); if (! isset($parsed[$key])) { // don't allow params overwrite $parsed[$key] = rawurldecode($value); } } } } return $parsed; } } ?>