Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /*
- * Set tabs to 4 for best viewing.
- *
- * Latest version is available at http://php.weblogs.com
- *
- * This is the main include file for ADOdb.
- * Database specific drivers are stored in the adodb/drivers/adodb-*.inc.php
- *
- * The ADOdb files are formatted so that doxygen can be used to generate documentation.
- * Doxygen is a documentation generation tool and can be downloaded from http://doxygen.org/
- */
- /**
- \mainpage
- @version V3.40 7 April 2003 (c) 2000-2003 John Lim (jlim\@natsoft.com.my). All rights reserved.
- Released under both BSD license and Lesser GPL library license.
- Whenever there is any discrepancy between the two licenses,
- the BSD license will take precedence.
- PHP's database access functions are not standardised. This creates a need for a database
- class library to hide the differences between the different database API's (encapsulate
- the differences) so we can easily switch databases.
- We currently support MySQL, Oracle, Microsoft SQL Server, Sybase, Sybase SQL Anywhere,
- Informix, PostgreSQL, FrontBase, Interbase (Firebird and Borland variants), Foxpro, Access,
- ADO and ODBC. We have had successful reports of connecting to Progress and DB2 via ODBC.
- We hope more people will contribute drivers to support other databases.
- Latest Download at http://php.weblogs.com/adodb<br>
- Manual is at http://php.weblogs.com/adodb_manual
- */
- if (!defined('_ADODB_LAYER')) {
- define('_ADODB_LAYER',1);
- //==============================================================================================
- // CONSTANT DEFINITIONS
- //==============================================================================================
- define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>');
- define('ADODB_FETCH_DEFAULT',0);
- define('ADODB_FETCH_NUM',1);
- define('ADODB_FETCH_ASSOC',2);
- define('ADODB_FETCH_BOTH',3);
- /*
- Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names.
- This currently works only with mssql, odbc, oci8po and ibase derived drivers.
- 0 = assoc lowercase field names. $rs->fields['orderid']
- 1 = assoc uppercase field names. $rs->fields['ORDERID']
- 2 = use native-case field names. $rs->fields['OrderID']
- */
- if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
- // allow [ ] @ ` and . in table names
- define('ADODB_TABLE_REGEX','([]0-9a-z_\`\.\@\[-]*)');
- if (!defined('ADODB_PREFETCH_ROWS')) define('ADODB_PREFETCH_ROWS',10);
- /**
- * Set ADODB_DIR to the directory where this file resides...
- * This constant was formerly called $ADODB_RootPath
- */
- if (!defined('ADODB_DIR')) define('ADODB_DIR',dirname(__FILE__));
- define('TIMESTAMP_FIRST_YEAR',100);
- //==============================================================================================
- // GLOBAL VARIABLES
- //==============================================================================================
- GLOBAL
- $ADODB_vers, // database version
- $ADODB_Database, // last database driver used
- $ADODB_COUNTRECS, // count number of records returned - slows down query
- $ADODB_CACHE_DIR, // directory to cache recordsets
- $ADODB_EXTENSION, // ADODB extension installed
- $ADODB_COMPAT_PATCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF
- $ADODB_FETCH_MODE; // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default...
- //==============================================================================================
- // GLOBAL SETUP
- //==============================================================================================
- if (strnatcmp(PHP_VERSION,'4.3.0')>=0) {
- define('ADODB_PHPVER',0x4300);
- } else if (strnatcmp(PHP_VERSION,'4.2.0')>=0) {
- define('ADODB_PHPVER',0x4200);
- } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) {
- define('ADODB_PHPVER',0x4050);
- } else {
- define('ADODB_PHPVER',0x4000);
- }
- $ADODB_EXTENSION = defined('ADODB_EXTENSION');
- //if (extension_loaded('dbx')) define('ADODB_DBX',1);
- /**
- Accepts $src and $dest arrays, replacing string $data
- */
- function ADODB_str_replace($src, $dest, $data)
- {
- if (ADODB_PHPVER >= 0x4050) return str_replace($src,$dest,$data);
- $s = reset($src);
- $d = reset($dest);
- while ($s !== false) {
- $data = str_replace($s,$d,$data);
- $s = next($src);
- $d = next($dest);
- }
- return $data;
- }
- function ADODB_Setup()
- {
- GLOBAL
- $ADODB_vers, // database version
- $ADODB_Database, // last database driver used
- $ADODB_COUNTRECS, // count number of records returned - slows down query
- $ADODB_CACHE_DIR, // directory to cache recordsets
- $ADODB_FETCH_MODE;
- $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT;
- if (!isset($ADODB_CACHE_DIR)) {
- $ADODB_CACHE_DIR = '/tmp';
- } else {
- // do not accept url based paths, eg. http:/ or ftp:/
- if (strpos($ADODB_CACHE_DIR,'://') !== false)
- die("Illegal path http:// or ftp://");
- }
- // Initialize random number generator for randomizing cache flushes
- srand(((double)microtime())*1000000);
- /**
- * Name of last database driver loaded into memory. Set by ADOLoadCode().
- */
- $ADODB_Database = '';
- /**
- * ADODB version as a string.
- */
- $ADODB_vers = 'V3.40 7 April 2003 (c) 2000-2003 John Lim ([email protected]). All rights reserved. Released BSD & LGPL.';
- /**
- * Determines whether recordset->RecordCount() is used.
- * Set to false for highest performance -- RecordCount() will always return -1 then
- * for databases that provide "virtual" recordcounts...
- */
- $ADODB_COUNTRECS = true;
- }
- //==============================================================================================
- // CHANGE NOTHING BELOW UNLESS YOU ARE CODING
- //==============================================================================================
- ADODB_Setup();
- //==============================================================================================
- // CLASS ADOFieldObject
- //==============================================================================================
- /**
- * Helper class for FetchFields -- holds info on a column
- */
- class ADOFieldObject {
- var $name = '';
- var $max_length=0;
- var $type="";
- // additional fields by dannym... ([email protected])
- var $not_null = false;
- // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^
- // so we can as well make not_null standard (leaving it at "false" does not harm anyways)
- var $has_default = false; // this one I have done only in mysql and postgres for now ...
- // others to come (dannym)
- var $default_value; // default, if any, and supported. Check has_default first.
- }
- //==============================================================================================
- // CLASS ADOConnection
- //==============================================================================================
- include_once(ADODB_DIR.'/adodb-connection.inc.php');
- //==============================================================================================
- // CLASS ADOFetchObj
- //==============================================================================================
- /**
- * Internal placeholder for record objects. Used by ADORecordSet->FetchObj().
- */
- class ADOFetchObj {
- };
- //==============================================================================================
- // CLASS ADORecordSet_empty
- //==============================================================================================
- /**
- * Lightweight recordset when there are no records to be returned
- */
- class ADORecordSet_empty
- {
- var $dataProvider = 'empty';
- var $databaseType = false;
- var $EOF = true;
- var $_numOfRows = 0;
- var $fields = false;
- var $connection = false;
- function RowCount() {return 0;}
- function RecordCount() {return 0;}
- function PO_RecordCount(){return 0;}
- function Close(){return true;}
- function FetchRow() {return false;}
- function FieldCount(){ return 0;}
- }
- //==============================================================================================
- // DATE AND TIME FUNCTIONS
- //==============================================================================================
- include_once(ADODB_DIR.'/adodb-time.inc.php');
- //==============================================================================================
- // CLASS ADORecordSet
- //==============================================================================================
- include_once(ADODB_DIR.'/adodb-recordset.inc.php');
- //==============================================================================================
- // CLASS ADORecordSet_array
- //==============================================================================================
- /**
- * This class encapsulates the concept of a recordset created in memory
- * as an array. This is useful for the creation of cached recordsets.
- *
- * Note that the constructor is different from the standard ADORecordSet
- */
- class ADORecordSet_array extends ADORecordSet
- {
- var $databaseType = 'array';
- var $_array; // holds the 2-dimensional data array
- var $_types; // the array of types of each column (C B I L M)
- var $_colnames; // names of each column in array
- var $_skiprow1; // skip 1st row because it holds column names
- var $_fieldarr; // holds array of field objects
- var $canSeek = true;
- var $affectedrows = false;
- var $insertid = false;
- var $sql = '';
- var $compat = false;
- /**
- * Constructor
- *
- */
- function ADORecordSet_array($fakeid=1)
- {
- global $ADODB_FETCH_MODE,$ADODB_COMPAT_FETCH;
- // fetch() on EOF does not delete $this->fields
- $this->compat = !empty($ADODB_COMPAT_FETCH);
- $this->ADORecordSet($fakeid); // fake queryID
- $this->fetchMode = $ADODB_FETCH_MODE;
- }
- /**
- * Setup the Array. Later we will have XML-Data and CSV handlers
- *
- * @param array is a 2-dimensional array holding the data.
- * The first row should hold the column names
- * unless paramter $colnames is used.
- * @param typearr holds an array of types. These are the same types
- * used in MetaTypes (C,B,L,I,N).
- * @param [colnames] array of column names. If set, then the first row of
- * $array should not hold the column names.
- */
- function InitArray($array,$typearr,$colnames=false)
- {
- $this->_array = $array;
- $this->_types = $typearr;
- if ($colnames) {
- $this->_skiprow1 = false;
- $this->_colnames = $colnames;
- } else $this->_colnames = $array[0];
- $this->Init();
- }
- /**
- * Setup the Array and datatype file objects
- *
- * @param array is a 2-dimensional array holding the data.
- * The first row should hold the column names
- * unless paramter $colnames is used.
- * @param fieldarr holds an array of ADOFieldObject's.
- */
- function InitArrayFields($array,$fieldarr)
- {
- $this->_array = $array;
- $this->_skiprow1= false;
- if ($fieldarr) {
- $this->_fieldobjects = $fieldarr;
- }
- $this->Init();
- }
- function GetArray($nRows=-1)
- {
- if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) {
- return $this->_array;
- } else {
- return ADORecordSet::GetArray($nRows);
- }
- }
- function _initrs()
- {
- $this->_numOfRows = sizeof($this->_array);
- if ($this->_skiprow1) $this->_numOfRows -= 1;
- $this->_numOfFields =(isset($this->_fieldobjects)) ?
- sizeof($this->_fieldobjects):sizeof($this->_types);
- }
- /* Use associative array to get fields array */
- function Fields($colname)
- {
- if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
- if (!$this->bind) {
- $this->bind = array();
- for ($i=0; $i < $this->_numOfFields; $i++) {
- $o = $this->FetchField($i);
- $this->bind[strtoupper($o->name)] = $i;
- }
- }
- return $this->fields[$this->bind[strtoupper($colname)]];
- }
- function &FetchField($fieldOffset = -1)
- {
- if (isset($this->_fieldobjects)) {
- return $this->_fieldobjects[$fieldOffset];
- }
- $o = new ADOFieldObject();
- $o->name = $this->_colnames[$fieldOffset];
- $o->type = $this->_types[$fieldOffset];
- $o->max_length = -1; // length not known
- return $o;
- }
- function _seek($row)
- {
- if (sizeof($this->_array) && $row < $this->_numOfRows) {
- $this->fields = $this->_array[$row];
- return true;
- }
- return false;
- }
- function MoveNext()
- {
- if (!$this->EOF) {
- $this->_currentRow++;
- $pos = $this->_currentRow;
- if ($this->_skiprow1) $pos += 1;
- if ($this->_numOfRows <= $pos) {
- if (!$this->compat) $this->fields = false;
- } else {
- $this->fields = $this->_array[$pos];
- return true;
- }
- $this->EOF = true;
- }
- return false;
- }
- function _fetch()
- {
- $pos = $this->_currentRow;
- if ($this->_skiprow1) $pos += 1;
- if ($this->_numOfRows <= $pos) {
- if (!$this->compat) $this->fields = false;
- return false;
- }
- $this->fields = $this->_array[$pos];
- return true;
- }
- function _close()
- {
- return true;
- }
- } // ADORecordSet_array
- //==============================================================================================
- // HELPER FUNCTIONS
- //==============================================================================================
- /**
- * Synonym for ADOLoadCode.
- *
- * @deprecated
- */
- function ADOLoadDB($dbType)
- {
- return ADOLoadCode($dbType);
- }
- /**
- * Load the code for a specific database driver
- */
- function ADOLoadCode($dbType)
- {
- GLOBAL $ADODB_Database;
- if (!$dbType) return false;
- $ADODB_Database = strtolower($dbType);
- switch ($ADODB_Database) {
- case 'maxsql': $ADODB_Database = 'mysqlt'; break;
- case 'postgres':
- case 'pgsql': $ADODB_Database = 'postgres7'; break;
- }
- // Karsten Kraus <[email protected]>
- return @include_once(ADODB_DIR."/drivers/adodb-".$ADODB_Database.".inc.php");
- }
- /**
- * synonym for ADONewConnection for people like me who cannot remember the correct name
- */
- function &NewADOConnection($db='')
- {
- return ADONewConnection($db);
- }
- /**
- * Instantiate a new Connection class for a specific database driver.
- *
- * @param [db] is the database Connection object to create. If undefined,
- * use the last database driver that was loaded by ADOLoadCode().
- *
- * @return the freshly created instance of the Connection class.
- */
- function &ADONewConnection($db='')
- {
- GLOBAL $ADODB_Database;
- $rez = true;
- if ($db) {
- if ($ADODB_Database != $db) ADOLoadCode($db);
- } else {
- if (!empty($ADODB_Database)) {
- ADOLoadCode($ADODB_Database);
- } else {
- $rez = false;
- }
- }
- $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
- if (!$rez) {
- if ($errorfn) {
- // raise an error
- $errorfn('ADONewConnection', 'ADONewConnection', -998,
- "could not load the database driver for '$db",
- $dbtype);
- } else
- ADOConnection::outp( "<p>ADONewConnection: Unable to load database driver '$db'</p>",false);
- return false;
- }
- $cls = 'ADODB_'.$ADODB_Database;
- $obj = new $cls();
- if ($errorfn) {
- $obj->raiseErrorFn = $errorfn;
- }
- return $obj;
- }
- function &NewDataDictionary(&$conn)
- {
- $provider = $conn->dataProvider;
- if ($provider !== 'native' && $provider != 'odbc' && $provider != 'ado')
- $drivername = $conn->dataProvider;
- else {
- $drivername = $conn->databaseType;
- if (substr($drivername,0,5) == 'odbc_') $drivername = substr($drivername,5);
- else if (substr($drivername,0,4) == 'ado_') $drivername = substr($drivername,4);
- else if ($drivername == 'oracle') $drivername = 'oci8';
- }
- include_once(ADODB_DIR.'/adodb-lib.inc.php');
- include_once(ADODB_DIR.'/adodb-datadict.inc.php');
- $path = ADODB_DIR."/datadict/datadict-$drivername.inc.php";
- if (!file_exists($path)) {
- ADOConnection::outp("Database driver '$path' not available");
- return false;
- }
- include_once($path);
- $class = "ADODB2_$drivername";
- $dict = new $class();
- $dict->connection = &$conn;
- $dict->upperName = strtoupper($drivername);
- if (is_resource($conn->_connectionID))
- $dict->serverInfo = $conn->ServerInfo();
- return $dict;
- }
- /**
- * Save a file $filename and its $contents (normally for caching) with file locking
- */
- function adodb_write_file($filename, $contents,$debug=false)
- {
- # http://www.php.net/bugs.php?id=9203 Bug that flock fails on Windows
- # So to simulate locking, we assume that rename is an atomic operation.
- # First we delete $filename, then we create a $tempfile write to it and
- # rename to the desired $filename. If the rename works, then we successfully
- # modified the file exclusively.
- # What a stupid need - having to simulate locking.
- # Risks:
- # 1. $tempfile name is not unique -- very very low
- # 2. unlink($filename) fails -- ok, rename will fail
- # 3. adodb reads stale file because unlink fails -- ok, $rs timeout occurs
- # 4. another process creates $filename between unlink() and rename() -- ok, rename() fails and cache updated
- if (strpos(strtoupper(PHP_OS),'WIN') !== false) {
- // skip the decimal place
- $mtime = substr(str_replace(' ','_',microtime()),2);
- // unlink will let some latencies develop, so uniqid() is more random
- @unlink($filename);
- // getmypid() actually returns 0 on Win98 - never mind!
- $tmpname = $filename.uniqid($mtime).getmypid();
- if (!($fd = fopen($tmpname,'a'))) return false;
- $ok = ftruncate($fd,0);
- if (!fwrite($fd,$contents)) $ok = false;
- fclose($fd);
- chmod($tmpname,0644);
- if (!@rename($tmpname,$filename)) {
- unlink($tmpname);
- $ok = false;
- }
- if (!$ok) {
- if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed'));
- }
- return $ok;
- }
- if (!($fd = fopen($filename, 'a'))) return false;
- if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) {
- $ok = fwrite( $fd, $contents );
- fclose($fd);
- chmod($filename,0644);
- }else {
- fclose($fd);
- if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename<br>\n");
- $ok = false;
- }
- return $ok;
- }
- function adodb_backtrace($print=true)
- {
- $s = '';
- if (PHPVERSION() >= 4.3) {
- $MAXSTRLEN = 64;
- $s = '<pre align=left>';
- $traceArr = debug_backtrace();
- array_shift($traceArr);
- $tabs = sizeof($traceArr)-1;
- foreach ($traceArr as $arr) {
- for ($i=0; $i < $tabs; $i++) $s .= ' ';
- $tabs -= 1;
- $s .= '<font face="Courier New,Courier">';
- if (isset($arr['class'])) $s .= $arr['class'].'.';
- foreach($arr['args'] as $v) {
- if (is_null($v)) $args[] = 'null';
- else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
- else if (is_object($v)) $args[] = 'Object:'.get_class($v);
- else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
- else {
- $v = (string) @$v;
- $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
- if (strlen($v) > $MAXSTRLEN) $str .= '...';
- $args[] = $str;
- }
- }
- $s .= $arr['function'].'('.implode(', ',$args).')';
- $s .= sprintf("</font><font color=#808080 size=-1> # line %4d, file: <a href=\"file:/%s\">%s</a></font>",
- $arr['line'],$arr['file'],$arr['file']);
- $s .= "\n";
- }
- $s .= '</pre>';
- if ($print) print $s;
- }
- return $s;
- }
- } // defined
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement