Creole.php

Go to the documentation of this file.
00001 <?php 00002 /* 00003 * $Id: Creole.php,v 1.6 2004/05/22 13:40:28 micha Exp $ 00004 * 00005 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00006 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00007 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00008 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00009 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00010 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00011 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00012 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00013 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00014 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00015 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00016 * 00017 * This software consists of voluntary contributions made by many individuals 00018 * and is licensed under the LGPL. For more information please see 00019 * <http://creole.phpdb.org>. 00020 */ 00021 00022 include_once 'creole/SQLException.php'; 00023 include_once 'creole/Connection.php'; 00024 00025 define('CREOLE_ERROR', -1); 00026 define('CREOLE_ERROR_SYNTAX', -2); 00027 define('CREOLE_ERROR_CONSTRAINT', -3); 00028 define('CREOLE_ERROR_NOT_FOUND', -4); 00029 define('CREOLE_ERROR_ALREADY_EXISTS', -5); 00030 define('CREOLE_ERROR_UNSUPPORTED', -6); 00031 define('CREOLE_ERROR_MISMATCH', -7); 00032 define('CREOLE_ERROR_INVALID', -8); 00033 define('CREOLE_ERROR_NOT_CAPABLE', -9); 00034 define('CREOLE_ERROR_TRUNCATED', -10); 00035 define('CREOLE_ERROR_INVALID_NUMBER', -11); 00036 define('CREOLE_ERROR_INVALID_DATE', -12); 00037 define('CREOLE_ERROR_DIVZERO', -13); 00038 define('CREOLE_ERROR_NODBSELECTED', -14); 00039 define('CREOLE_ERROR_CANNOT_CREATE', -15); 00040 define('CREOLE_ERROR_CANNOT_DELETE', -16); 00041 define('CREOLE_ERROR_CANNOT_DROP', -17); 00042 define('CREOLE_ERROR_NOSUCHTABLE', -18); 00043 define('CREOLE_ERROR_NOSUCHFIELD', -19); 00044 define('CREOLE_ERROR_NEED_MORE_DATA', -20); 00045 define('CREOLE_ERROR_NOT_LOCKED', -21); 00046 define('CREOLE_ERROR_VALUE_COUNT_ON_ROW', -22); 00047 define('CREOLE_ERROR_INVALID_DSN', -23); 00048 define('CREOLE_ERROR_CONNECT_FAILED', -24); 00049 define('CREOLE_ERROR_EXTENSION_NOT_FOUND',-25); 00050 define('CREOLE_ERROR_ACCESS_VIOLATION', -26); 00051 define('CREOLE_ERROR_NOSUCHDB', -27); 00052 define('CREOLE_ERROR_CONSTRAINT_NOT_NULL',-29); 00053 00054 // static: 00055 // track errors is used by drivers to get better error messages 00056 // make sure it's set. 00057 00058 @ini_set('track_errors', true); 00059 00077 class Creole 00078 { 00082 function PERSISTENT() { return 1; } 00087 function NO_ASSOC_LOWER() { return 16; } 00088 00095 var $driverMap = array 00096 ( 00097 'mysql' => 'creole.drivers.mysql.MySQLConnection', 00098 'pgsql' => 'creole.drivers.pgsql.PgSQLConnection', 00099 'mssql' => 'creole.drivers.mssql.MSSQLConnection', 00100 ); 00101 /* 00102 'sqlite' => 'creole.drivers.sqlite.SQLiteConnection', 00103 'oracle' => 'creole.drivers.oracle.OCI8Connection', 00104 */ 00105 00133 function registerDriver($phptype, $dotpath) 00134 { 00135 $self =& Creole::getInstance(); 00136 $self->driverMap[$phptype] = $dotpath; 00137 } 00138 00145 function deregisterDriver($phptype) 00146 { 00147 $self =& Creole::getInstance(); 00148 unset($self->driverMap[$phptype]); 00149 } 00150 00157 function getDriver($phptype) 00158 { 00159 $self =& Creole::getInstance(); 00160 00161 if (isset($self->driverMap[$phptype])) { 00162 return $self->driverMap[$phptype]; 00163 } else { 00164 return null; 00165 } 00166 } 00167 00181 function getConnection($dsn, $flags = 0) 00182 { 00183 if (is_array($dsn)) { 00184 $dsninfo = $dsn; 00185 } else { 00186 $dsninfo = Creole::parseDSN($dsn); 00187 } 00188 00189 $self =& Creole::getInstance(); 00190 00191 // support "catchall" drivers which will themselves handle the details of connecting 00192 // using the proper RDBMS driver. 00193 if (isset($self->driverMap['*'])) { 00194 $type = '*'; 00195 } 00196 else 00197 { 00198 $type = $dsninfo['phptype']; 00199 if (! isset($self->driverMap[$type])) { 00200 return new SQLException(CREOLE_ERROR_NOT_FOUND, "No driver has been registered to handle connection type: $type"); 00201 } 00202 } 00203 00204 // may need to make this more complex if we add support 00205 // for 'dbsyntax' 00206 $clazz = Creole::import($self->driverMap[$type]); 00207 00208 if (Creole::isError($clazz)) { 00209 return $clazz; 00210 } 00211 00212 $obj = new $clazz(); 00213 00214 if (! is_a($obj, 'Connection')) { 00215 return new SQLException(CREOLE_ERROR_NOT_FOUND, "Class does not implement creole.Connection interface: $clazz"); 00216 } 00217 00218 if (($e = $obj->connect($dsninfo, $flags)) !== true) { 00219 $e->setUserInfo($dsninfo); 00220 return $e; 00221 } 00222 00223 return $obj; 00224 } 00225 00257 function parseDSN($dsn) 00258 { 00259 if (is_array($dsn)) { 00260 return $dsn; 00261 } 00262 00263 $parsed = array( 00264 'phptype' => null, 00265 'username' => null, 00266 'password' => null, 00267 'protocol' => null, 00268 'hostspec' => null, 00269 'port' => null, 00270 'socket' => null, 00271 'database' => null 00272 ); 00273 00274 $info = parse_url($dsn); 00275 00276 if (count($info) === 1) { // if there's only one element in result, then it must be the phptype 00277 $parsed['phptype'] = array_pop($info); 00278 return $parsed; 00279 } 00280 00281 // some values can be copied directly 00282 $parsed['phptype'] = @$info['scheme']; 00283 $parsed['username'] = @$info['user']; 00284 $parsed['password'] = @$info['pass']; 00285 $parsed['port'] = @$info['port']; 00286 00287 $host = @$info['host']; 00288 if (false !== ($pluspos = strpos($host, '+'))) { 00289 $parsed['protocol'] = substr($host,0,$pluspos); 00290 if ($parsed['protocol'] === 'unix') { 00291 $parsed['socket'] = substr($host,$pluspos+1); 00292 } else { 00293 $parsed['hostspec'] = substr($host,$pluspos+1); 00294 } 00295 } else { 00296 $parsed['hostspec'] = $host; 00297 } 00298 00299 if (isset($info['path'])) { 00300 $parsed['database'] = substr($info['path'], 1); // remove first char, which is '/' 00301 } 00302 00303 if (isset($info['query'])) { 00304 $opts = explode('&', $info['query']); 00305 foreach ($opts as $opt) { 00306 list($key, $value) = explode('=', $opt); 00307 if (!isset($parsed[$key])) { // don't allow params overwrite 00308 $parsed[$key] = urldecode($value); 00309 } 00310 } 00311 } 00312 00313 return $parsed; 00314 } 00315 00325 function import($class) 00326 { 00327 if (! class_exists($class)) 00328 { 00329 $path = strtr($class, '.', DIRECTORY_SEPARATOR) . '.php'; 00330 $ret = @(include_once($path)); 00331 if ($ret === false) { 00332 return new SQLException(CREOLE_ERROR_NOT_FOUND, "Unable to load driver class: " . $class); 00333 } 00334 00335 // get just classname ('path.to.ClassName' -> 'ClassName') 00336 $pos = strrpos($class, '.'); 00337 if ($pos !== false) { 00338 $class = substr($class, $pos + 1); 00339 } 00340 00341 if (!class_exists($class)) { 00342 return new SQLException(CREOLE_ERROR_NOT_FOUND, "Unable to find loaded class: $class (Hint: make sure classname matches filename)"); 00343 } 00344 } 00345 return $class; 00346 } 00347 00355 function isError($value) 00356 { 00357 return (is_a($value, 'Exception')); 00358 } 00359 00369 function typeHint(&$value, $type, $class, $func, $param = 1) 00370 { 00371 if (! is_a($value, "$type")) { 00372 trigger_error ( 00373 "$class::$func(): parameter '$param' not of type '$type' !", 00374 E_USER_ERROR 00375 ); 00376 } 00377 } 00378 00379 /* 00380 * @private 00381 */ 00382 function & getInstance() 00383 { 00384 static $instance; 00385 00386 if ($instance === null) 00387 { 00388 $instance = new Creole(); 00389 } 00390 00391 return $instance; 00392 } 00393 00394 }

This file is part of the Creole[php4] library.


Copyright © 2004 Hans Lellelid  
Creole[php4] CVS