Thread: [Astrospaces-commits] SF.net SVN: astrospaces: [38] trunk/functions
Brought to you by:
p3net
From: <cal...@us...> - 2007-07-30 04:57:49
|
Revision: 38 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=38&view=rev Author: caleb870 Date: 2007-07-29 21:57:52 -0700 (Sun, 29 Jul 2007) Log Message: ----------- Adding ADOdb lite. Added Paths: ----------- trunk/functions/adodb-datadict.inc.php trunk/functions/adodb-error.inc.php trunk/functions/adodb-errorhandler.inc.php trunk/functions/adodb-errorpear.inc.php trunk/functions/adodb-exceptions.inc.php trunk/functions/adodb-perf-module.inc.php trunk/functions/adodb-perf.inc.php trunk/functions/adodb-time.inc.php trunk/functions/adodb-xmlschema.inc.php trunk/functions/adodb.config.php trunk/functions/adodb.inc.php trunk/functions/adodbSQL_drivers/ trunk/functions/adodbSQL_drivers/fbsql/ trunk/functions/adodbSQL_drivers/fbsql/fbsql_datadict.inc trunk/functions/adodbSQL_drivers/fbsql/fbsql_date_module.inc trunk/functions/adodbSQL_drivers/fbsql/fbsql_driver.inc trunk/functions/adodbSQL_drivers/fbsql/fbsql_extend_module.inc trunk/functions/adodbSQL_drivers/fbsql/fbsql_meta_module.inc trunk/functions/adodbSQL_drivers/fbsql/fbsql_transaction_module.inc trunk/functions/adodbSQL_drivers/gladius/ trunk/functions/adodbSQL_drivers/gladius/gladius_datadict.inc trunk/functions/adodbSQL_drivers/gladius/gladius_date_module.inc trunk/functions/adodbSQL_drivers/gladius/gladius_driver.inc trunk/functions/adodbSQL_drivers/gladius/gladius_extend_module.inc trunk/functions/adodbSQL_drivers/gladius/gladius_meta_module.inc trunk/functions/adodbSQL_drivers/gladius/gladius_transaction_module.inc trunk/functions/adodbSQL_drivers/maxdb/ trunk/functions/adodbSQL_drivers/maxdb/maxdb_datadict.inc trunk/functions/adodbSQL_drivers/maxdb/maxdb_date_module.inc trunk/functions/adodbSQL_drivers/maxdb/maxdb_driver.inc trunk/functions/adodbSQL_drivers/maxdb/maxdb_extend_module.inc trunk/functions/adodbSQL_drivers/maxdb/maxdb_meta_module.inc trunk/functions/adodbSQL_drivers/maxdb/maxdb_transaction_module.inc trunk/functions/adodbSQL_drivers/msql/ trunk/functions/adodbSQL_drivers/msql/msql_datadict.inc trunk/functions/adodbSQL_drivers/msql/msql_date_module.inc trunk/functions/adodbSQL_drivers/msql/msql_driver.inc trunk/functions/adodbSQL_drivers/msql/msql_extend_module.inc trunk/functions/adodbSQL_drivers/msql/msql_meta_module.inc trunk/functions/adodbSQL_drivers/msql/msql_transaction_module.inc trunk/functions/adodbSQL_drivers/mssql/ trunk/functions/adodbSQL_drivers/mssql/mssql_datadict.inc trunk/functions/adodbSQL_drivers/mssql/mssql_date_module.inc trunk/functions/adodbSQL_drivers/mssql/mssql_driver.inc trunk/functions/adodbSQL_drivers/mssql/mssql_extend_module.inc trunk/functions/adodbSQL_drivers/mssql/mssql_meta_module.inc trunk/functions/adodbSQL_drivers/mssql/mssql_transaction_module.inc trunk/functions/adodbSQL_drivers/mssqlpo/ trunk/functions/adodbSQL_drivers/mssqlpo/mssqlpo_datadict.inc trunk/functions/adodbSQL_drivers/mssqlpo/mssqlpo_date_module.inc trunk/functions/adodbSQL_drivers/mssqlpo/mssqlpo_driver.inc trunk/functions/adodbSQL_drivers/mssqlpo/mssqlpo_extend_module.inc trunk/functions/adodbSQL_drivers/mssqlpo/mssqlpo_meta_module.inc trunk/functions/adodbSQL_drivers/mssqlpo/mssqlpo_transaction_module.inc trunk/functions/adodbSQL_drivers/mysql/ trunk/functions/adodbSQL_drivers/mysql/mysql_datadict.inc trunk/functions/adodbSQL_drivers/mysql/mysql_date_module.inc trunk/functions/adodbSQL_drivers/mysql/mysql_driver.inc trunk/functions/adodbSQL_drivers/mysql/mysql_extend_module.inc trunk/functions/adodbSQL_drivers/mysql/mysql_meta_module.inc trunk/functions/adodbSQL_drivers/mysql/mysql_perfmon_module.inc trunk/functions/adodbSQL_drivers/mysql/mysql_transaction_module.inc trunk/functions/adodbSQL_drivers/mysqli/ trunk/functions/adodbSQL_drivers/mysqli/mysqli_datadict.inc trunk/functions/adodbSQL_drivers/mysqli/mysqli_date_module.inc trunk/functions/adodbSQL_drivers/mysqli/mysqli_driver.inc trunk/functions/adodbSQL_drivers/mysqli/mysqli_extend_module.inc trunk/functions/adodbSQL_drivers/mysqli/mysqli_meta_module.inc trunk/functions/adodbSQL_drivers/mysqli/mysqli_perfmon_module.inc trunk/functions/adodbSQL_drivers/mysqli/mysqli_transaction_module.inc trunk/functions/adodbSQL_drivers/mysqlt/ trunk/functions/adodbSQL_drivers/mysqlt/mysqlt_datadict.inc trunk/functions/adodbSQL_drivers/mysqlt/mysqlt_date_module.inc trunk/functions/adodbSQL_drivers/mysqlt/mysqlt_driver.inc trunk/functions/adodbSQL_drivers/mysqlt/mysqlt_extend_module.inc trunk/functions/adodbSQL_drivers/mysqlt/mysqlt_meta_module.inc trunk/functions/adodbSQL_drivers/mysqlt/mysqlt_perfmon_module.inc trunk/functions/adodbSQL_drivers/mysqlt/mysqlt_transaction_module.inc trunk/functions/adodbSQL_drivers/odbc/ trunk/functions/adodbSQL_drivers/odbc/odbc_datadict.inc trunk/functions/adodbSQL_drivers/odbc/odbc_date_module.inc trunk/functions/adodbSQL_drivers/odbc/odbc_driver.inc trunk/functions/adodbSQL_drivers/odbc/odbc_extend_module.inc trunk/functions/adodbSQL_drivers/odbc/odbc_meta_module.inc trunk/functions/adodbSQL_drivers/odbc/odbc_transaction_module.inc trunk/functions/adodbSQL_drivers/postgres/ trunk/functions/adodbSQL_drivers/postgres/postgres_datadict.inc trunk/functions/adodbSQL_drivers/postgres/postgres_date_module.inc trunk/functions/adodbSQL_drivers/postgres/postgres_driver.inc trunk/functions/adodbSQL_drivers/postgres/postgres_extend_module.inc trunk/functions/adodbSQL_drivers/postgres/postgres_meta_module.inc trunk/functions/adodbSQL_drivers/postgres/postgres_transaction_module.inc trunk/functions/adodbSQL_drivers/postgres64/ trunk/functions/adodbSQL_drivers/postgres64/postgres64_datadict.inc trunk/functions/adodbSQL_drivers/postgres64/postgres64_date_module.inc trunk/functions/adodbSQL_drivers/postgres64/postgres64_driver.inc trunk/functions/adodbSQL_drivers/postgres64/postgres64_extend_module.inc trunk/functions/adodbSQL_drivers/postgres64/postgres64_meta_module.inc trunk/functions/adodbSQL_drivers/postgres64/postgres64_transaction_module.inc trunk/functions/adodbSQL_drivers/postgres7/ trunk/functions/adodbSQL_drivers/postgres7/postgres7_datadict.inc trunk/functions/adodbSQL_drivers/postgres7/postgres7_date_module.inc trunk/functions/adodbSQL_drivers/postgres7/postgres7_driver.inc trunk/functions/adodbSQL_drivers/postgres7/postgres7_extend_module.inc trunk/functions/adodbSQL_drivers/postgres7/postgres7_meta_module.inc trunk/functions/adodbSQL_drivers/postgres7/postgres7_transaction_module.inc trunk/functions/adodbSQL_drivers/postgres8/ trunk/functions/adodbSQL_drivers/postgres8/postgres8_datadict.inc trunk/functions/adodbSQL_drivers/postgres8/postgres8_date_module.inc trunk/functions/adodbSQL_drivers/postgres8/postgres8_driver.inc trunk/functions/adodbSQL_drivers/postgres8/postgres8_extend_module.inc trunk/functions/adodbSQL_drivers/postgres8/postgres8_meta_module.inc trunk/functions/adodbSQL_drivers/postgres8/postgres8_transaction_module.inc trunk/functions/adodbSQL_drivers/sqlite/ trunk/functions/adodbSQL_drivers/sqlite/sqlite_datadict.inc trunk/functions/adodbSQL_drivers/sqlite/sqlite_date_module.inc trunk/functions/adodbSQL_drivers/sqlite/sqlite_driver.inc trunk/functions/adodbSQL_drivers/sqlite/sqlite_extend_module.inc trunk/functions/adodbSQL_drivers/sqlite/sqlite_meta_module.inc trunk/functions/adodbSQL_drivers/sqlite/sqlite_transaction_module.inc trunk/functions/adodbSQL_drivers/sqlitepo/ trunk/functions/adodbSQL_drivers/sqlitepo/sqlitepo_datadict.inc trunk/functions/adodbSQL_drivers/sqlitepo/sqlitepo_date_module.inc trunk/functions/adodbSQL_drivers/sqlitepo/sqlitepo_driver.inc trunk/functions/adodbSQL_drivers/sqlitepo/sqlitepo_extend_module.inc trunk/functions/adodbSQL_drivers/sqlitepo/sqlitepo_meta_module.inc trunk/functions/adodbSQL_drivers/sqlitepo/sqlitepo_transaction_module.inc trunk/functions/adodbSQL_drivers/sybase/ trunk/functions/adodbSQL_drivers/sybase/sybase_datadict.inc trunk/functions/adodbSQL_drivers/sybase/sybase_date_module.inc trunk/functions/adodbSQL_drivers/sybase/sybase_driver.inc trunk/functions/adodbSQL_drivers/sybase/sybase_extend_module.inc trunk/functions/adodbSQL_drivers/sybase/sybase_meta_module.inc trunk/functions/adodbSQL_drivers/sybase/sybase_transaction_module.inc trunk/functions/adodbSQL_drivers/sybase_ase/ trunk/functions/adodbSQL_drivers/sybase_ase/sybase_ase_datadict.inc trunk/functions/adodbSQL_drivers/sybase_ase/sybase_ase_date_module.inc trunk/functions/adodbSQL_drivers/sybase_ase/sybase_ase_driver.inc trunk/functions/adodbSQL_drivers/sybase_ase/sybase_ase_extend_module.inc trunk/functions/adodbSQL_drivers/sybase_ase/sybase_ase_meta_module.inc trunk/functions/adodbSQL_drivers/sybase_ase/sybase_ase_transaction_module.inc trunk/functions/documentation/ trunk/functions/documentation/adodb_license.txt trunk/functions/documentation/adodb_lite_commands.html trunk/functions/documentation/adodb_lite_datadictionary.html trunk/functions/documentation/adodb_lite_debugconsole.html trunk/functions/documentation/adodb_lite_errorhandling.html trunk/functions/documentation/adodb_lite_howtoinstall.html trunk/functions/documentation/adodb_lite_modulecreation.html trunk/functions/documentation/adodb_lite_modules.html trunk/functions/documentation/adodb_lite_performancemonitor.html trunk/functions/documentation/adodb_lite_sessions.html trunk/functions/documentation/changelog.txt trunk/functions/documentation/example_generic_module.inc trunk/functions/documentation/example_module.inc trunk/functions/documentation/images/ trunk/functions/documentation/images/dot_b.gif trunk/functions/documentation/images/e05.gif trunk/functions/documentation/images/fon_bar01.gif trunk/functions/documentation/images/query_de.gif trunk/functions/documentation/license.txt trunk/functions/documentation/readme.txt trunk/functions/documentation/style.css trunk/functions/generic_modules/ trunk/functions/generic_modules/adodblite_module.inc trunk/functions/generic_modules/menu_module.inc trunk/functions/generic_modules/object_module.inc trunk/functions/generic_modules/pear_module.inc trunk/functions/lang/ trunk/functions/lang/adodb-ar.inc.php trunk/functions/lang/adodb-bg.inc.php trunk/functions/lang/adodb-bgutf8.inc.php trunk/functions/lang/adodb-ca.inc.php trunk/functions/lang/adodb-cn.inc.php trunk/functions/lang/adodb-cz.inc.php trunk/functions/lang/adodb-da.inc.php trunk/functions/lang/adodb-de.inc.php trunk/functions/lang/adodb-en.inc.php trunk/functions/lang/adodb-es.inc.php trunk/functions/lang/adodb-esperanto.inc.php trunk/functions/lang/adodb-fr.inc.php trunk/functions/lang/adodb-hu.inc.php trunk/functions/lang/adodb-it.inc.php trunk/functions/lang/adodb-nl.inc.php trunk/functions/lang/adodb-pl.inc.php trunk/functions/lang/adodb-pt-br.inc.php trunk/functions/lang/adodb-ro.inc.php trunk/functions/lang/adodb-ru1251.inc.php trunk/functions/lang/adodb-sv.inc.php trunk/functions/lang/adodb-uk1251.inc.php trunk/functions/query_debug_console/ trunk/functions/query_debug_console/query_debug_console.php trunk/functions/query_debug_console/query_debug_console.tpl trunk/functions/session/ trunk/functions/session/adodb-compress-bzip2.php trunk/functions/session/adodb-compress-gzip.php trunk/functions/session/adodb-cryptsession.php trunk/functions/session/adodb-encrypt-mcrypt.php trunk/functions/session/adodb-encrypt-md5.php trunk/functions/session/adodb-encrypt-ordcrypt.php trunk/functions/session/adodb-encrypt-secret.php trunk/functions/session/adodb-encrypt-sha1.php trunk/functions/session/adodb-session.php trunk/functions/session/adodb-sessions.mysql.sql trunk/functions/session/session_schema.xml trunk/functions/tests/ trunk/functions/tests/adodblite_thumb.jpg trunk/functions/tests/pj trunk/functions/tests/test_adodb_lite.php trunk/functions/tests/test_adodb_lite_sessions.php trunk/functions/tests/test_datadictionary.php trunk/functions/tests/xmlschema.xml trunk/functions/tohtml.inc.php trunk/functions/xmlschema.dtd Added: trunk/functions/adodb-datadict.inc.php =================================================================== --- trunk/functions/adodb-datadict.inc.php (rev 0) +++ trunk/functions/adodb-datadict.inc.php 2007-07-30 04:57:52 UTC (rev 38) @@ -0,0 +1,838 @@ +<?php + +/** + V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + + Set tabs to 4 for best viewing. + + DOCUMENTATION: + + See adodb/tests/test-datadict.php for docs and examples. + + Modified 3 October, 2005 for use with ADOdb Lite by Mark Dickenson +*/ + +/* + Test script for parser +*/ + +// security - hide paths +if (!defined('ADODB_DIR')) die(); + +if (!function_exists('ctype_alnum')) { + function ctype_alnum($text) { + return preg_match('/^[a-z0-9]*$/i', $text); + } +} + +function _array_change_key_case($an_array) +{ + if (is_array($an_array)) { + $new_array = array(); + foreach($an_array as $key=>$value) + $new_array[strtoupper($key)] = $value; + + return $new_array; + } + + return $an_array; +} + +/** + Parse arguments, treat "text" (text) and 'text' as quotation marks. + To escape, use "" or '' or )) + + Will read in "abc def" sans quotes, as: abc def + Same with 'abc def'. + However if `abc def`, then will read in as `abc def` + + @param endstmtchar Character that indicates end of statement + @param tokenchars Include the following characters in tokens apart from A-Z and 0-9 + @returns 2 dimensional array containing parsed tokens. +*/ +function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-') +{ + $pos = 0; + $intoken = false; + $stmtno = 0; + $endquote = false; + $tokens = array(); + $tokens[$stmtno] = array(); + $max = strlen($args); + $quoted = false; + + while ($pos < $max) { + $ch = substr($args,$pos,1); + switch($ch) { + case ' ': + case "\t": + case "\n": + case "\r": + if (!$quoted) { + if ($intoken) { + $intoken = false; + $tokens[$stmtno][] = implode('',$tokarr); + } + break; + } + $tokarr[] = $ch; + break; + case '`': + if ($intoken) $tokarr[] = $ch; + case '(': + case ')': + case '"': + case "'": + if ($intoken) { + if (empty($endquote)) { + $tokens[$stmtno][] = implode('',$tokarr); + if ($ch == '(') $endquote = ')'; + else $endquote = $ch; + $quoted = true; + $intoken = true; + $tokarr = array(); + } else if ($endquote == $ch) { + $ch2 = substr($args,$pos+1,1); + if ($ch2 == $endquote) { + $pos += 1; + $tokarr[] = $ch2; + } else { + $quoted = false; + $intoken = false; + $tokens[$stmtno][] = implode('',$tokarr); + $endquote = ''; + } + } else + $tokarr[] = $ch; + }else { + if ($ch == '(') $endquote = ')'; + else $endquote = $ch; + $quoted = true; + $intoken = true; + $tokarr = array(); + if ($ch == '`') $tokarr[] = '`'; + } + break; + default: + if (!$intoken) { + if ($ch == $endstmtchar) { + $stmtno += 1; + $tokens[$stmtno] = array(); + break; + } + $intoken = true; + $quoted = false; + $endquote = false; + $tokarr = array(); + } + if ($quoted) $tokarr[] = $ch; + else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch; + else { + if ($ch == $endstmtchar) { + $tokens[$stmtno][] = implode('',$tokarr); + $stmtno += 1; + $tokens[$stmtno] = array(); + $intoken = false; + $tokarr = array(); + break; + } + $tokens[$stmtno][] = implode('',$tokarr); + $tokens[$stmtno][] = $ch; + $intoken = false; + } + } + $pos += 1; + } + if ($intoken) $tokens[$stmtno][] = implode('',$tokarr); + + return $tokens; +} + + +class ADODB_DataDict { + var $connection; + var $debug = false; + var $dropTable = 'DROP TABLE %s'; + var $renameTable = 'RENAME TABLE %s TO %s'; + var $dropIndex = 'DROP INDEX %s'; + var $addCol = ' ADD'; + var $alterCol = ' ALTER COLUMN'; + var $dropCol = ' DROP COLUMN'; + var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s'; // table, old-column, new-column, column-definitions (not used by default) + var $nameRegex = '\w'; + var $nameRegexBrackets = 'a-zA-Z0-9_\(\)'; + var $schema = false; + var $serverInfo = array(); + var $autoIncrement = false; + var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql + var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob + /// in other words, we use a text area for editting. + var $metaTablesSQL; + var $metaColumnsSQL; + var $debug_echo = true; + var $fetchMode; + var $raiseErrorFn; + + function SetFetchMode($mode) + { + GLOBAL $ADODB_FETCH_MODE; + $old = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = $mode; + return $old; + } + + function outp($text) + { + $this->debug_output = "<br>\n(" . $this->dbtype . "): ".htmlspecialchars($text)."<br>\n"; + if($this->debug_echo) + echo $this->debug_output; + } + + function GetCommentSQL($table,$col) + { + return false; + } + + function SetCommentSQL($table,$col,$cmt) + { + return false; + } + + /** + * @param ttype can either be 'VIEW' or 'TABLE' or false. + * If false, both views and tables are returned. + * "VIEW" returns only views + * "TABLE" returns only tables + * @param showSchema returns the schema/user with the table name, eg. USER.TABLE + * @param mask is the input mask - only supported by oci8 and postgresql + * + * @return array of tables for current database. + */ + + function MetaTables() + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaTables(); + } + + /** + * List columns in a database as an array of ADOFieldObjects. + * See top of file for definition of object. + * + * @param table table name to query + * @param upper uppercase table name (required by some databases) + * @schema is optional database schema to use - not supported by all databases. + * + * @return array of ADOFieldObjects for current table. + */ + + function MetaColumns($tab, $upper=true, $schema=false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema); + } + + /** + * @returns an array with the primary key columns in it. + */ + + function MetaPrimaryKeys($tab,$owner=false,$intkey=false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey); + } + + /** + * List indexes on a table as an array. + * @param table table name to query + * @param primary true to only show primary keys. Not actually used for most databases + * + * @return array of indexes on current table. Each element represents an index, and is itself an associative array. + + Array ( + [name_of_index] => Array + ( + [unique] => true or false + [columns] => Array + ( + [0] => firstname + [1] => lastname + ) + ) + */ + + function MetaIndexes($table, $primary = false, $owner = false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner); + } + + function MetaType($t,$len=-1,$fieldobj=false) + { + return $this->connection->MetaType($t,$len,$fieldobj); + } + + function ActualType($meta) + { + return $meta; + } + + function NameQuote($name = NULL,$allowBrackets=false) + { + if (!is_string($name)) { + return FALSE; + } + + $name = trim($name); + + if ( !is_object($this->connection) ) { + return $name; + } + + $quote = $this->connection->nameQuote; + + // if name is of the form `name`, quote it + if ( preg_match('/^`(.+)`$/', $name, $matches) ) { + return $quote . $matches[1] . $quote; + } + + // if name contains special characters, quote it + $regex = ($allowBrackets) ? $this->nameRegexBrackets : $this->nameRegex; + + if ( !preg_match('/^[' . $regex . ']+$/', $name) ) { + return $quote . $name . $quote; + } + + return $name; + } + + function TableName($name) + { + if ( $this->schema ) { + return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name); + } + return $this->NameQuote($name); + } + + // Executes the sql array returned by GetTableSQL and GetIndexSQL + function ExecuteSQLArray($sql, $continueOnError = true) + { + $rez = 2; + $conn = &$this->connection; + $saved = $conn->debug; + foreach($sql as $line) { + if ($this->debug) $conn->debug = true; + $ok = $conn->Execute($line); + $conn->debug = $saved; + if (!$ok) { + if ($this->debug) $this->outp($conn->ErrorMsg()); + if (!$continueOnError) return 0; + $rez = 1; + } + } + return $rez; + } + + function CreateDatabase($dbname,$options=false) + { + $options = $this->_Options($options); + $sql = array(); + + $s = 'CREATE DATABASE ' . $this->NameQuote($dbname); + if (isset($options[$this->upperName])) + $s .= ' '.$options[$this->upperName]; + + $sql[] = $s; + return $sql; + } + + /* + Generates the SQL to create index. Returns an array of sql strings. + */ + + function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false) + { + if (!is_array($flds)) { + $flds = explode(',',$flds); + } + foreach($flds as $key => $fld) { + # some indexes can use partial fields, eg. index first 32 chars of "name" with NAME(32) + $flds[$key] = $this->NameQuote($fld,$allowBrackets=true); + } + return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions)); + } + + function DropIndexSQL ($idxname, $tabname = NULL) + { + return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname))); + } + + function SetSchema($schema) + { + $this->schema = $schema; + } + + function AddColumnSQL($tabname, $flds) + { + $tabname = $this->TableName ($tabname); + $sql = array(); + list($lines,$pkey) = $this->_GenFields($flds); + $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' '; + foreach($lines as $v) { + $sql[] = $alter . $v; + } + return $sql; + } + + /** + * Change the definition of one column + * + * As some DBM's can't do that on there own, you need to supply the complete defintion of the new table, + * to allow, recreating the table and copying the content over to the new table + * @param string $tabname table-name + * @param string $flds column-name and type for the changed column + * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' + * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' + * @return array with SQL strings + */ + + function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + $tabname = $this->TableName ($tabname); + $sql = array(); + list($lines,$pkey) = $this->_GenFields($flds); + $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; + foreach($lines as $v) { + $sql[] = $alter . $v; + } + return $sql; + } + + /** + * Rename one column + * + * Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql) + * @param string $tabname table-name + * @param string $oldcolumn column-name to be renamed + * @param string $newcolumn new column-name + * @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default='' + * @return array with SQL strings + */ + + function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='') + { + $tabname = $this->TableName ($tabname); + if ($flds) { + list($lines,$pkey) = $this->_GenFields($flds); + list(,$first) = each($lines); + list(,$column_def) = split("[\t ]+",$first,2); + } + return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def)); + } + + /** + * Drop one column + * + * Some DBM's can't do that on there own, you need to supply the complete defintion of the new table, + * to allow, recreating the table and copying the content over to the new table + * @param string $tabname table-name + * @param string $flds column-name and type for the changed column + * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' + * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' + * @return array with SQL strings + */ + + function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + $tabname = $this->TableName ($tabname); + if (!is_array($flds)) $flds = explode(',',$flds); + $sql = array(); + $alter = 'ALTER TABLE ' . $tabname . $this->dropCol . ' '; + foreach($flds as $v) { + $sql[] = $alter . $this->NameQuote($v); + } + return $sql; + } + + function DropTableSQL($tabname) + { + return array (sprintf($this->dropTable, $this->TableName($tabname))); + } + + function RenameTableSQL($tabname,$newname) + { + return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname))); + } + + /* + Generate the SQL to create table. Returns an array of sql strings. + */ + + function CreateTableSQL($tabname, $flds, $tableoptions=false) + { + if (!$tableoptions) $tableoptions = array(); + + list($lines,$pkey) = $this->_GenFields($flds, true); + + $taboptions = $this->_Options($tableoptions); + $tabname = $this->TableName ($tabname); + $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions); + $tsql = $this->_Triggers($tabname,$taboptions); + foreach($tsql as $s) $sql[] = $s; + + return $sql; + } + + function _GenFields($flds,$widespacing=false) + { + if (is_string($flds)) { + $padding = ' '; + $txt = $flds.$padding; + $flds = array(); + $flds0 = Lens_ParseArgs($txt,','); + $hasparam = false; + foreach($flds0 as $f0) { + $f1 = array(); + foreach($f0 as $token) { + switch (strtoupper($token)) { + case 'CONSTRAINT': + case 'DEFAULT': + $hasparam = $token; + break; + default: + if ($hasparam) $f1[$hasparam] = $token; + else $f1[] = $token; + $hasparam = false; + break; + } + } + $flds[] = $f1; + + } + } + $this->autoIncrement = false; + $lines = array(); + $pkey = array(); + foreach($flds as $fld) { + $fld = _array_change_key_case($fld); + $fname = false; + $fdefault = false; + $fautoinc = false; + $ftype = false; + $fsize = false; + $fprec = false; + $fprimary = false; + $fnoquote = false; + $fdefts = false; + $fdefdate = false; + $fconstraint = false; + $fnotnull = false; + $funsigned = false; + + //----------------- + // Parse attributes + foreach($fld as $attr => $v) { + if ($attr == 2 && is_numeric($v)) $attr = 'SIZE'; + else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v); + switch($attr) { + case '0': + case 'NAME': + $fname = $v; + break; + case '1': + case 'TYPE': + $ty = $v; $ftype = $this->ActualType(strtoupper($v)); + break; + case 'SIZE': + $dotat = strpos($v,'.'); + if ($dotat === false) $dotat = strpos($v,','); + if ($dotat === false) $fsize = $v; + else { + $fsize = substr($v,0,$dotat); + $fprec = substr($v,$dotat+1); + } + break; + case 'UNSIGNED': + $funsigned = true; + break; + case 'AUTOINCREMENT': + case 'AUTO': + $fautoinc = true; + $fnotnull = true; + break; + case 'KEY': + case 'PRIMARY': + $fprimary = $v; + $fnotnull = true; + break; + case 'DEF': + case 'DEFAULT': + $fdefault = $v; + break; + case 'NOTNULL': + $fnotnull = $v; + break; + case 'NOQUOTE': + $fnoquote = $v; + break; + case 'DEFDATE': + $fdefdate = $v; + break; + case 'DEFTIMESTAMP': + $fdefts = $v; + break; + case 'CONSTRAINT': + $fconstraint = $v; + break; + } + } + + //-------------------- + // VALIDATE FIELD INFO + if (!strlen($fname)) { + if ($this->debug) $this->outp("Undefined NAME"); + return false; + } + + $fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname)); + $fname = $this->NameQuote($fname); + + if (!strlen($ftype)) { + if ($this->debug) $this->outp("Undefined TYPE for field '$fname'"); + return false; + } else { + $ftype = strtoupper($ftype); + } + + $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec); + + if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls + + if ($fprimary) $pkey[] = $fname; + + // some databases do not allow blobs to have defaults + if ($ty == 'X') $fdefault = false; + + //-------------------- + // CONSTRUCT FIELD SQL + if ($fdefts) { + if (substr($this->dbtype,0,5) == 'mysql') { + $ftype = 'TIMESTAMP'; + } else { + $fdefault = $this->connection->sysTimeStamp; + } + } else if ($fdefdate) { + if (substr($this->dbtype,0,5) == 'mysql') { + $ftype = 'TIMESTAMP'; + } else { + $fdefault = $this->connection->sysDate; + } + } else if ($fdefault !== false && !$fnoquote) + if ($ty == 'C' or $ty == 'X' or + ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault))) + if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ') + $fdefault = trim($fdefault); + else if (strtolower($fdefault) != 'null') + $fdefault = $this->connection->qstr($fdefault); + $suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned); + + if ($widespacing) $fname = str_pad($fname,24); + $lines[$fid] = $fname.' '.$ftype.$suffix; + + if ($fautoinc) $this->autoIncrement = true; + } // foreach $flds + return array($lines,$pkey); + } + + /* + GENERATE THE SIZE PART OF THE DATATYPE + $ftype is the actual type + $ty is the type defined originally in the DDL + */ + + function _GetSize($ftype, $ty, $fsize, $fprec) + { + if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) { + $ftype .= "(".$fsize; + if (strlen($fprec)) $ftype .= ",".$fprec; + $ftype .= ')'; + } + return $ftype; + } + + // return string must begin with space + function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint) + { + $suffix = ''; + if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault"; + if ($fnotnull) $suffix .= ' NOT NULL'; + if ($fconstraint) $suffix .= ' '.$fconstraint; + return $suffix; + } + + function _IndexSQL($idxname, $tabname, $flds, $idxoptions) + { + $sql = array(); + + if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) { + $sql[] = sprintf ($this->dropIndex, $idxname); + if ( isset($idxoptions['DROP']) ) + return $sql; + } + + if ( empty ($flds) ) { + return $sql; + } + + $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : ''; + + $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' '; + + if ( isset($idxoptions[$this->upperName]) ) + $s .= $idxoptions[$this->upperName]; + + if ( is_array($flds) ) + $flds = implode(', ',$flds); + $s .= '(' . $flds . ')'; + $sql[] = $s; + + return $sql; + } + + function _DropAutoIncrement($tabname) + { + return false; + } + + function _TableSQL($tabname,$lines,$pkey,$tableoptions) + { + $sql = array(); + + if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) { + $sql[] = sprintf($this->dropTable,$tabname); + if ($this->autoIncrement) { + $sInc = $this->_DropAutoIncrement($tabname); + if ($sInc) $sql[] = $sInc; + } + if ( isset ($tableoptions['DROP']) ) { + return $sql; + } + } + $s = "CREATE TABLE $tabname (\n"; + $s .= implode(",\n", $lines); + if (sizeof($pkey)>0) { + $s .= ",\n PRIMARY KEY ("; + $s .= implode(", ",$pkey).")"; + } + if (isset($tableoptions['CONSTRAINTS'])) + $s .= "\n".$tableoptions['CONSTRAINTS']; + + if (isset($tableoptions[$this->upperName.'_CONSTRAINTS'])) + $s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS']; + + $s .= "\n)"; + if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName]; + $sql[] = $s; + + return $sql; + } + + /* + GENERATE TRIGGERS IF NEEDED + used when table has auto-incrementing field that is emulated using triggers + */ + + function _Triggers($tabname,$taboptions) + { + return array(); + } + + /* + Sanitize options, so that array elements with no keys are promoted to keys + */ + + function _Options($opts) + { + if (!is_array($opts)) return array(); + $newopts = array(); + foreach($opts as $k => $v) { + if (is_numeric($k)) $newopts[strtoupper($v)] = $v; + else $newopts[strtoupper($k)] = $v; + } + return $newopts; + } + + /* + "Florian Buzin [ easywe ]" <florian.buzin#easywe.de> + + This function changes/adds new fields to your table. You don't + have to know if the col is new or not. It will check on its own. + */ + + function ChangeTableSQL($tablename, $flds, $tableoptions = false) + { + global $ADODB_FETCH_MODE; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; + if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); + + // check table exists + $save_handler = $this->raiseErrorFn; + $this->raiseErrorFn = ''; + $cols = $this->MetaColumns($tablename); + $this->raiseErrorFn = $save_handler; + + if (isset($savem)) $this->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + + if ( empty($cols)) { + return $this->CreateTableSQL($tablename, $flds, $tableoptions); + } + + if (is_array($flds)) { + // Cycle through the update fields, comparing + // existing fields to fields to update. + // if the Metatype and size is exactly the + // same, ignore - by Mark Newham + $holdflds = array(); + foreach($flds as $k=>$v) { + if ( isset($cols[$k]) && is_object($cols[$k]) ) { + $c = $cols[$k]; + $ml = $c->max_length; + $mt = &$this->MetaType($c->type,$ml); + if ($ml == -1) $ml = ''; + if ($mt == 'X') $ml = $v['SIZE']; + if (($mt != $v['TYPE']) || $ml != $v['SIZE']) { + $holdflds[$k] = $v; + } + } else { + $holdflds[$k] = $v; + } + } + $flds = $holdflds; + } + + // already exists, alter table instead + list($lines,$pkey) = $this->_GenFields($flds); + $alter = 'ALTER TABLE ' . $this->TableName($tablename); + $sql = array(); + + foreach ( $lines as $id => $v ) { + if ( isset($cols[$id]) && is_object($cols[$id]) ) { + $flds = Lens_ParseArgs($v,','); + // We are trying to change the size of the field, if not allowed, simply ignore the request. + if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) continue; + + $sql[] = $alter . $this->alterCol . ' ' . $v; + } else { + $sql[] = $alter . $this->addCol . ' ' . $v; + } + } + return $sql; + } +} + +?> \ No newline at end of file Added: trunk/functions/adodb-error.inc.php =================================================================== --- trunk/functions/adodb-error.inc.php (rev 0) +++ trunk/functions/adodb-error.inc.php 2007-07-30 04:57:52 UTC (rev 38) @@ -0,0 +1,277 @@ +<?php +/** + * @version V4.93 10 Oct 2006 (c) 2000-2006 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. + * + * Set tabs to 4 for best viewing. + * + * The following code is adapted from the PEAR DB error handling code. + * Portions (c)1997-2002 The PHP Group. + */ + + +if (!defined("DB_ERROR")) define("DB_ERROR",-1); + +if (!defined("DB_ERROR_SYNTAX")) { + define("DB_ERROR_SYNTAX", -2); + define("DB_ERROR_CONSTRAINT", -3); + define("DB_ERROR_NOT_FOUND", -4); + define("DB_ERROR_ALREADY_EXISTS", -5); + define("DB_ERROR_UNSUPPORTED", -6); + define("DB_ERROR_MISMATCH", -7); + define("DB_ERROR_INVALID", -8); + define("DB_ERROR_NOT_CAPABLE", -9); + define("DB_ERROR_TRUNCATED", -10); + define("DB_ERROR_INVALID_NUMBER", -11); + define("DB_ERROR_INVALID_DATE", -12); + define("DB_ERROR_DIVZERO", -13); + define("DB_ERROR_NODBSELECTED", -14); + define("DB_ERROR_CANNOT_CREATE", -15); + define("DB_ERROR_CANNOT_DELETE", -16); + define("DB_ERROR_CANNOT_DROP", -17); + define("DB_ERROR_NOSUCHTABLE", -18); + define("DB_ERROR_NOSUCHFIELD", -19); + define("DB_ERROR_NEED_MORE_DATA", -20); + define("DB_ERROR_NOT_LOCKED", -21); + define("DB_ERROR_VALUE_COUNT_ON_ROW", -22); + define("DB_ERROR_INVALID_DSN", -23); + define("DB_ERROR_CONNECT_FAILED", -24); + define("DB_ERROR_EXTENSION_NOT_FOUND",-25); + define("DB_ERROR_NOSUCHDB", -25); + define("DB_ERROR_ACCESS_VIOLATION", -26); +} + +function adodb_errormsg($value) +{ + global $ADODB_LANG,$ADODB_LANG_ARRAY; + + if (empty($ADODB_LANG)) + $ADODB_LANG = 'en'; + if (isset($ADODB_LANG_ARRAY['LANG']) && $ADODB_LANG_ARRAY['LANG'] == $ADODB_LANG) ; + else + { + include_once(ADODB_DIR."/lang/adodb-$ADODB_LANG.inc.php"); + } + return isset($ADODB_LANG_ARRAY[$value]) ? $ADODB_LANG_ARRAY[$value] : $ADODB_LANG_ARRAY[DB_ERROR]; +} + +function adodb_error($provider,$dbType,$errno) +{ + //var_dump($errno); + if (is_numeric($errno) && $errno == 0) + return 0; + + switch($provider) { + case 'mysql': + $map = adodb_error_mysql(); + break; + + case 'oracle': + case 'oci8': + $map = adodb_error_oci8(); + break; + + case 'ibase': + $map = adodb_error_ibase(); + break; + + case 'odbc': + $map = adodb_error_odbc(); + break; + + case 'mssql': + case 'sybase': + $map = adodb_error_mssql(); + break; + + case 'informix': + $map = adodb_error_ifx(); + break; + + case 'postgres': + return adodb_error_pg($errno); + break; + + case 'sqlite': + return $map = adodb_error_sqlite(); + break; + default: + return DB_ERROR; + } + //print_r($map); + //var_dump($errno); + if (isset($map[$errno])) + return $map[$errno]; + return DB_ERROR; +} + +//************************************************************************************** + +function adodb_error_pg($errormsg) +{ + if (is_numeric($errormsg)) + return (integer) $errormsg; + + static $error_regexps = array( + '/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/' => DB_ERROR_NOSUCHTABLE, + '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS, + '/divide by zero$/' => DB_ERROR_DIVZERO, + '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER, + '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD, + '/parser: parse error at or near \"/' => DB_ERROR_SYNTAX, + '/referential integrity violation/' => DB_ERROR_CONSTRAINT, + '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/' + => DB_ERROR_ALREADY_EXISTS + ); + reset($error_regexps); + while (list($regexp,$code) = each($error_regexps)) + { + if (preg_match($regexp, $errormsg)) + { + return $code; + } + } + // Fall back to DB_ERROR if there was no mapping. + return DB_ERROR; +} + +function adodb_error_odbc() +{ + static $MAP = array( + '01004' => DB_ERROR_TRUNCATED, + '07001' => DB_ERROR_MISMATCH, + '21S01' => DB_ERROR_MISMATCH, + '21S02' => DB_ERROR_MISMATCH, + '22003' => DB_ERROR_INVALID_NUMBER, + '22008' => DB_ERROR_INVALID_DATE, + '22012' => DB_ERROR_DIVZERO, + '23000' => DB_ERROR_CONSTRAINT, + '24000' => DB_ERROR_INVALID, + '34000' => DB_ERROR_INVALID, + '37000' => DB_ERROR_SYNTAX, + '42000' => DB_ERROR_SYNTAX, + 'IM001' => DB_ERROR_UNSUPPORTED, + 'S0000' => DB_ERROR_NOSUCHTABLE, + 'S0001' => DB_ERROR_NOT_FOUND, + 'S0002' => DB_ERROR_NOSUCHTABLE, + 'S0011' => DB_ERROR_ALREADY_EXISTS, + 'S0012' => DB_ERROR_NOT_FOUND, + 'S0021' => DB_ERROR_ALREADY_EXISTS, + 'S0022' => DB_ERROR_NOT_FOUND, + 'S1000' => DB_ERROR_NOSUCHTABLE, + 'S1009' => DB_ERROR_INVALID, + 'S1090' => DB_ERROR_INVALID, + 'S1C00' => DB_ERROR_NOT_CAPABLE + ); + return $MAP; +} + +function adodb_error_ibase() +{ + static $MAP = array( + -104 => DB_ERROR_SYNTAX, + -150 => DB_ERROR_ACCESS_VIOLATION, + -151 => DB_ERROR_ACCESS_VIOLATION, + -155 => DB_ERROR_NOSUCHTABLE, + -157 => DB_ERROR_NOSUCHFIELD, + -158 => DB_ERROR_VALUE_COUNT_ON_ROW, + -170 => DB_ERROR_MISMATCH, + -171 => DB_ERROR_MISMATCH, + -172 => DB_ERROR_INVALID, + -204 => DB_ERROR_INVALID, + -205 => DB_ERROR_NOSUCHFIELD, + -206 => DB_ERROR_NOSUCHFIELD, + -208 => DB_ERROR_INVALID, + -219 => DB_ERROR_NOSUCHTABLE, + -297 => DB_ERROR_CONSTRAINT, + -530 => DB_ERROR_CONSTRAINT, + -803 => DB_ERROR_CONSTRAINT, + -551 => DB_ERROR_ACCESS_VIOLATION, + -552 => DB_ERROR_ACCESS_VIOLATION, + -922 => DB_ERROR_NOSUCHDB, + -923 => DB_ERROR_CONNECT_FAILED, + -924 => DB_ERROR_CONNECT_FAILED + ); + return $MAP; +} + +function adodb_error_ifx() +{ + static $MAP = array( + '-201' => DB_ERROR_SYNTAX, + '-206' => DB_ERROR_NOSUCHTABLE, + '-217' => DB_ERROR_NOSUCHFIELD, + '-329' => DB_ERROR_NODBSELECTED, + '-1204' => DB_ERROR_INVALID_DATE, + '-1205' => DB_ERROR_INVALID_DATE, + '-1206' => DB_ERROR_INVALID_DATE, + '-1209' => DB_ERROR_INVALID_DATE, + '-1210' => DB_ERROR_INVALID_DATE, + '-1212' => DB_ERROR_INVALID_DATE + ); + return $MAP; +} + +function adodb_error_oci8() +{ + static $MAP = array( + 1 => DB_ERROR_ALREADY_EXISTS, + 900 => DB_ERROR_SYNTAX, + 904 => DB_ERROR_NOSUCHFIELD, + 923 => DB_ERROR_SYNTAX, + 942 => DB_ERROR_NOSUCHTABLE, + 955 => DB_ERROR_ALREADY_EXISTS, + 1476 => DB_ERROR_DIVZERO, + 1722 => DB_ERROR_INVALID_NUMBER, + 2289 => DB_ERROR_NOSUCHTABLE, + 2291 => DB_ERROR_CONSTRAINT, + 2449 => DB_ERROR_CONSTRAINT + ); + return $MAP; +} + +function adodb_error_mssql() +{ + static $MAP = array( + 208 => DB_ERROR_NOSUCHTABLE, + 2601 => DB_ERROR_ALREADY_EXISTS + ); + return $MAP; +} + +function adodb_error_sqlite() +{ + static $MAP = array( + 1 => DB_ERROR_SYNTAX + ); + return $MAP; +} + +function adodb_error_mysql() +{ + static $MAP = array( + 1004 => DB_ERROR_CANNOT_CREATE, + 1005 => DB_ERROR_CANNOT_CREATE, + 1006 => DB_ERROR_CANNOT_CREATE, + 1007 => DB_ERROR_ALREADY_EXISTS, + 1008 => DB_ERROR_CANNOT_DROP, + 1045 => DB_ERROR_ACCESS_VIOLATION, + 1046 => DB_ERROR_NODBSELECTED, + 1049 => DB_ERROR_NOSUCHDB, + 1050 => DB_ERROR_ALREADY_EXISTS, + 1051 => DB_ERROR_NOSUCHTABLE, + 1054 => DB_ERROR_NOSUCHFIELD, + 1062 => DB_ERROR_ALREADY_EXISTS, + 1064 => DB_ERROR_SYNTAX, + 1100 => DB_ERROR_NOT_LOCKED, + 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, + 1146 => DB_ERROR_NOSUCHTABLE, + 1048 => DB_ERROR_CONSTRAINT, + 2002 => DB_ERROR_CONNECT_FAILED, + 2005 => DB_ERROR_CONNECT_FAILED + ); + return $MAP; +} +?> \ No newline at end of file Added: trunk/functions/adodb-errorhandler.inc.php =================================================================== --- trunk/functions/adodb-errorhandler.inc.php (rev 0) +++ trunk/functions/adodb-errorhandler.inc.php 2007-07-30 04:57:52 UTC (rev 38) @@ -0,0 +1,79 @@ +<?php +/** + * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + * + * Set tabs to 4 for best viewing. + * + * Latest version is available at http://php.weblogs.com + * +*/ + +// added Claudio Bustos clbustos#entelchile.net +if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR); + +if (!defined('ADODB_ERROR_HANDLER')) define('ADODB_ERROR_HANDLER','ADODB_Error_Handler'); + +/** +* Default Error Handler. This will be called with the following params +* +* @param $dbms the RDBMS you are connecting to +* @param $fn the name of the calling function (in uppercase) +* @param $errno the native error number from the database +* @param $errmsg the native error msg from the database +* @param $p1 $fn specific parameter - see below +* @param $p2 $fn specific parameter - see below +* @param $thisConn $current connection object - can be false if no connection object created +*/ + +function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) +{ + if (error_reporting() == 0) + return; // obey @ protocol + + switch($fn) { + case 'EXECUTE': + $sql = $p1; + $inputparams = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")\n"; + break; + + case 'PCONNECT': + case 'CONNECT': + $host = $p1; + $database = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn($host, '****', '****', $database)\n"; + break; + + default: + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n"; + break; + } + /* + * Log connection error somewhere + * 0 message is sent to PHP's system logger, using the Operating System's system + * logging mechanism or a file, depending on what the error_log configuration + * directive is set to. + * 1 message is sent by email to the address in the destination parameter. + * This is the only message type where the fourth parameter, extra_headers is used. + * This message type uses the same internal function as mail() does. + * 2 message is sent through the PHP debugging connection. + * This option is only available if remote debugging has been enabled. + * In this case, the destination parameter specifies the host name or IP address + * and optionally, port number, of the socket receiving the debug information. + * 3 message is appended to the file destination + */ + if (defined('ADODB_ERROR_LOG_TYPE')) { + $t = date('Y-m-d H:i:s'); + if (defined('ADODB_ERROR_LOG_DEST')) + error_log("($t) $s", ADODB_ERROR_LOG_TYPE, ADODB_ERROR_LOG_DEST); + else + error_log("($t) $s", ADODB_ERROR_LOG_TYPE); + } + + //print "<p>$s</p>"; + trigger_error($s, ADODB_ERROR_HANDLER_TYPE); +} +?> Added: trunk/functions/adodb-errorpear.inc.php =================================================================== --- trunk/functions/adodb-errorpear.inc.php (rev 0) +++ trunk/functions/adodb-errorpear.inc.php 2007-07-30 04:57:52 UTC (rev 38) @@ -0,0 +1,87 @@ +<?php +/** + * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + * + * Set tabs to 4 for best viewing. + * + * Latest version is available at http://php.weblogs.com + * +*/ +include_once('PEAR.php'); + +if (!defined('ADODB_ERROR_HANDLER')) + define('ADODB_ERROR_HANDLER','ADODB_Error_PEAR'); + +/* +* Enabled the following if you want to terminate scripts when an error occurs +*/ +//PEAR::setErrorHandling (PEAR_ERROR_DIE); + +/* +* Name of the PEAR_Error derived class to call. +*/ +if (!defined('ADODB_PEAR_ERROR_CLASS')) + define('ADODB_PEAR_ERROR_CLASS','PEAR_Error'); + +/* +* Store the last PEAR_Error object here +*/ +global $ADODB_Last_PEAR_Error; + +$ADODB_Last_PEAR_Error = false; + + /** +* Error Handler with PEAR support. This will be called with the following params +* +* @param $dbms the RDBMS you are connecting to +* @param $fn the name of the calling function (in uppercase) +* @param $errno the native error number from the database +* @param $errmsg the native error msg from the database +* @param $p1 $fn specific parameter - see below +* @param $P2 $fn specific parameter - see below + */ +function ADODB_Error_PEAR($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false) +{ + global $ADODB_Last_PEAR_Error; + + if (error_reporting() == 0) + return; // obey @ protocol + + switch($fn) { + case 'EXECUTE': + $sql = $p1; + $inputparams = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")"; + break; + + case 'PCONNECT': + case 'CONNECT': + $host = $p1; + $database = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn('$host', ?, ?, '$database')"; + break; + + default: + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)"; + break; + } + + $class = ADODB_PEAR_ERROR_CLASS; + $ADODB_Last_PEAR_Error = new $class($s, $errno, $GLOBALS['_PEAR_default_error_mode'], $GLOBALS['_PEAR_default_error_options'], $errmsg); + //print "<p>!$s</p>"; +} + +/** +* Returns last PEAR_Error object. This error might be for an error that +* occured several sql statements ago. +*/ +function &ADODB_PEAR_Error() +{ + global $ADODB_Last_PEAR_Error; + + return $ADODB_Last_PEAR_Error; +} +?> \ No newline at end of file Added: trunk/functions/adodb-exceptions.inc.php =================================================================== --- trunk/functions/adodb-exceptions.inc.php (rev 0) +++ trunk/functions/adodb-exceptions.inc.php 2007-07-30 04:57:52 UTC (rev 38) @@ -0,0 +1,86 @@ +<?php + +/** + * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + * + * Set tabs to 4 for best viewing. + * + * Latest version is available at http://php.weblogs.com + * + * Exception-handling code using PHP5 exceptions (try-catch-throw). + */ + +if (!defined('ADODB_ERROR_HANDLER_TYPE')) + define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR); + +define('ADODB_ERROR_HANDLER','adodb_throw'); + +class ADODB_Exception extends Exception { + var $dbms; + var $fn; + var $sql = ''; + var $params = ''; + var $host = ''; + var $database = ''; + + function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) + { + switch($fn) { + case 'EXECUTE': + $this->sql = $p1; + $this->params = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn(\"$p1\")\n"; + break; + + case 'PCONNECT': + case 'CONNECT': + $user = $thisConnection->username; + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)\n"; + break; + + default: + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n"; + break; + } + + $this->dbms = $dbms; + $this->host = $thisConnection->host; + $this->database = $thisConnection->database; + $this->fn = $fn; + $this->msg = $errmsg; + + if (!is_numeric($errno)) + $errno = -1; + + parent::__construct($s,$errno); + } +} + +/** +* Default Error Handler. This will be called with the following params +* +* @param $dbms the RDBMS you are connecting to +* @param $fn the name of the calling function (in uppercase) +* @param $errno the native error number from the database +* @param $errmsg the native error msg from the database +* @param $p1 $fn specific parameter - see below +* @param $P2 $fn specific parameter - see below +*/ + +function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) +{ + global $ADODB_EXCEPTION; + + if (error_reporting() == 0) + return; // obey @ protocol + + if (is_string($ADODB_EXCEPTION)) + $errfn = $ADODB_EXCEPTION; + else $errfn = 'ADODB_EXCEPTION'; + + throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection); +} +?> \ No newline at end of file Added: trunk/functions/adodb-perf-module.inc.php =================================================================== --- trunk/functions/adodb-perf-module.inc.php (rev 0) +++ trunk/functions/adodb-perf-module.inc.php 2007-07-30 04:57:52 UTC (rev 38) @@ -0,0 +1,974 @@ +<?php +/* +V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. See License.txt. + + Library for basic performance monitoring and tuning. + + Modified 23 April 2006 for use with ADOdb Lite by Pádraic Brady + Such modifications as listed (c) 2006 Pádraic Brady (mau...@ho...) + + Modifications: + - Moved below methods from adodb_perf class to create a common parent from which all driver + specific perfmon modules will extend to prevent duplicate code. + - See specific driver module files for other changes + +*/ + +eval('class perfmon_parent_EXTENDER extends ' . $last_module . '_ADOConnection { }'); + +class perfmon_parent_ADOConnection extends perfmon_parent_EXTENDER +{ + + var $color = '#F0F0F0'; + var $table = '<table style="border: 2px groove #000000; background-color: #FFFFFF;">'; + var $titles = '<tr><td><strong>Parameter</strong></td><td><strong>Value</strong></td><td><strong>Description</strong></td></tr>'; + var $warnRatio = 90; + var $tablesSQL = false; + var $cliFormat = "%32s => %s \r\n"; + var $sql1 = 'sql1'; // used for casting sql1 to text for mssql + var $explain = true; + var $helpurl = '<a href="javascript:void();">LogSQL help</a>'; + var $createTableSQL = false; + var $maxLength = 2000; + var $settings = false; + var $_logsql = false; + var $_lastload; + + /** + * Sets the table name to use for SQL logging. Returns value of current table when called. + * Usage: perfmon_parent_ADOConnection::table('custom_log_sql'); + * $currentTable = perfmon_parent_ADOConnection::table(); + * + * @access public + * @param string $newtable The name for the table to use; optional. + * @return string + */ + function table($newtable = false) + { + static $_table; + if (!empty($newtable)) $_table = $newtable; + if (empty($_table)) $_table = 'adodb_logsql'; + return $_table; + } + + /** + * Enables SQL logging to database for Performance Monitor use. + * Usage: $oldValue = $db->LogSQL( $enable ); + * $enable is optional; defaults to TRUE enabling logging. FALSE disables logging. + * + * @access public + * @param bool $enable + * @return bool + */ + function LogSQL($enable=true) + { + $old = $this->_logsql; + $this->_logsql = $enable; + return $old; + } + + /** + * Returns an array with information to calculate CPU Load + * + * @access private + * @return mixed + */ + function _CPULoad() { + // Algorithm is taken from + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/example__obtaining_raw_performance_data.asp + if (strncmp(PHP_OS,'WIN',3)==0) + { + if (PHP_VERSION == '5.0.0') return false; + if (PHP_VERSION == '5.0.1') return false; + if (PHP_VERSION == '5.0.2') return false; + if (PHP_VERSION == '5.0.3') return false; + if (PHP_VERSION == '4.3.10') return false; # see http://bugs.php.net/bug.php?id=31737 + + @$c = new COM("WinMgmts:{impersonationLevel=impersonate}!Win32_PerfRawData_PerfOS_Processor.Name='_Total'"); + if (!$c) return false; + + $info[0] = $c->PercentProcessorTime; + $info[1] = 0; + $info[2] = 0; + $info[3] = $c->TimeStamp_Sys100NS; + return $info; + } + + // Algorithm - Steve Blinch (BlitzAffe Online, http://www.blitzaffe.com) + $statfile = '/proc/stat'; + if (!file_exists($statfile)) return false; + + $fd = fopen($statfile,"r"); + if (!$fd) return false; + + $statinfo = explode("\n",fgets($fd, 1024)); + fclose($fd); + foreach($statinfo as $line) + { + $info = explode(" ",$line); + if($info[0]=="cpu") + { + array_shift($info); // pop off "cpu" + if(!$info[0]) array_shift($info); // pop off blank space (if any) + return $info; + } + } + + return false; + } + + /* NOT IMPLEMENTED */ + function MemInfo() + { + + } + + + /** + * Returns CPU Load + * + * @access public + * @return mixed + */ + function CPULoad() + { + $info = $this->_CPULoad(); + if (!$info) return false; + + if (empty($this->_lastLoad)) + { + sleep(1); + $this->_lastLoad = $info; + $info = $this->_CPULoad(); + } + + $last = $this->_lastLoad; + $this->_lastLoad = $info; + + $d_user = $info[0] - $last[0]; + $d_nice = $info[1] - $last[1]; + $d_system = $info[2] - $last[2]; + $d_idle = $info[3] - $last[3]; + + if (strncmp(PHP_OS,'WIN',3)==0) + { + if ($d_idle < 1) $d_idle = 1; + return 100*(1-$d_user/$d_idle); + } + else + { + $total=$d_user+$d_nice+$d_system+$d_idle; + if ($total<1) $total=1; + return 100*($d_user+$d_nice+$d_system)/$total; + } + } + + function Tracer($sql) + { + $perf_table = perfmon_parent_ADOConnection::table(); + $saveE = $this->LogSQL(false); + + global $ADODB_FETCH_MODE; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + $sqlq = $this->qstr($sql); + $arr = $this->GetArray( + "select count(*),tracer + from $perf_table where sql1=$sqlq + group by tracer + order by 1 desc" + ); + $s = ''; + if ($arr) + { + $s .= '\n<h3>Scripts Affected</h3>\n'; + foreach($arr as $k) + { + $s .= sprintf("%4d",$k[0]).' '.strip_tags($k[1]).'<br />'; + } + } + $this->LogSQL($saveE); + return $s; + } + + /* + Explain Plan for $sql. + If only a snippet of the $sql is passed in, then $partial will hold the crc32 of the + actual sql. + */ + function Explain($sql, $partial=false) + { + return false; + } + + function InvalidSQL($numsql = 10) + { + + if (isset($_GET['sql'])) return; + $s = '<h3>Invalid SQL</h3>'; + $saveE = $this->LogSQL(false); + $perf_table = perfmon_parent_ADOConnection::table(); + $rs =& $this->SelectLimit( + "select distinct count(*), sql1, tracer as error_msg + from $perf_table + where tracer like 'ERROR:%' + group by sql1, tracer + order by 1 desc" + ,$numsql + ); + $this->LogSQL($saveE); + if ($rs) + { + $s .= rs2html($rs,false,false,false,false); + } + else + { + return "\n<p>$this->helpurl. ".$this->ErrorMsg()."</p>\n"; + } + return $s; + } + + + /* + This script identifies the longest running SQL + */ + function _SuspiciousSQL($numsql = 10) + { + global $ADODB_FETCH_MODE; + + $perf_table = perfmon_parent_ADOConnection::table(); + $saveE = $this->LogSQL(false); + + if (isset($_GET['exps']) && isset($_GET['sql'])) + { + $partial = !empty($_GET['part']); + echo '<a name="explain"></a>' . $this->Explain($_GET['sql'], $partial) . "\n"; + } + + if (isset($_GET['sql'])) return; + $sql1 = $this->sql1; + + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + $rs =& $this->SelectLimit( + "select avg(timer) as avg_timer, $sql1, count(*), max(timer) as max_timer, min(timer) as min_timer + from $perf_table + where {$this->upperCase}({$this->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT') + and (tracer is null or tracer not l... [truncated message content] |
From: <cal...@us...> - 2007-07-31 00:49:58
|
Revision: 51 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=51&view=rev Author: caleb870 Date: 2007-07-30 17:50:00 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodbSQL_drivers/ Removed Paths: ------------- trunk/functions/adodbSQL_drivers/ Copied: trunk/functions/adodb/adodbSQL_drivers (from rev 50, trunk/functions/adodbSQL_drivers) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:50:23
|
Revision: 52 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=52&view=rev Author: caleb870 Date: 2007-07-30 17:50:23 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/documentation/ Removed Paths: ------------- trunk/functions/documentation/ Copied: trunk/functions/adodb/documentation (from rev 51, trunk/functions/documentation) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:50:35
|
Revision: 53 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=53&view=rev Author: caleb870 Date: 2007-07-30 17:50:38 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/generic_modules/ Removed Paths: ------------- trunk/functions/generic_modules/ Copied: trunk/functions/adodb/generic_modules (from rev 52, trunk/functions/generic_modules) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:51:00
|
Revision: 54 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=54&view=rev Author: caleb870 Date: 2007-07-30 17:51:01 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/lang/ Removed Paths: ------------- trunk/functions/lang/ Copied: trunk/functions/adodb/lang (from rev 53, trunk/functions/lang) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:51:10
|
Revision: 55 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=55&view=rev Author: caleb870 Date: 2007-07-30 17:51:13 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/query_debug_console/ Removed Paths: ------------- trunk/functions/query_debug_console/ Copied: trunk/functions/adodb/query_debug_console (from rev 54, trunk/functions/query_debug_console) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:51:24
|
Revision: 56 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=56&view=rev Author: caleb870 Date: 2007-07-30 17:51:27 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/session/ Removed Paths: ------------- trunk/functions/session/ Copied: trunk/functions/adodb/session (from rev 55, trunk/functions/session) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:51:50
|
Revision: 57 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=57&view=rev Author: caleb870 Date: 2007-07-30 17:51:52 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/tests/ Removed Paths: ------------- trunk/functions/tests/ Copied: trunk/functions/adodb/tests (from rev 56, trunk/functions/tests) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:52:16
|
Revision: 58 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=58&view=rev Author: caleb870 Date: 2007-07-30 17:52:18 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb.config.php Removed Paths: ------------- trunk/functions/adodb.config.php Copied: trunk/functions/adodb/adodb.config.php (from rev 57, trunk/functions/adodb.config.php) =================================================================== --- trunk/functions/adodb/adodb.config.php (rev 0) +++ trunk/functions/adodb/adodb.config.php 2007-07-31 00:52:18 UTC (rev 58) @@ -0,0 +1,52 @@ +<?php +/** + * ADOdb Lite Configuration File + */ + +/** +* Set the $dbtype variable to the database designator. +* If this variable is enabled it will override the database designator +* entered in the ADONewConnection( $dbtype ) function. The database +* designator in a DSN string will be overridden but the rest of the DSN +* string will be used. +* +* You can place a DSN entry in the $dbtype variable if you would like to +* auto connect to your database. +* +* Example: +* +* $dbtype = "driver://username:password@hostname/database?options[=value]#modules"; +* +* driver = Databasetype Designator listed in the table at the start of this page. +* username = The Username needed to access the database +* password = Optional password for accessing the database +* hostname = localhost or url/ip address IE: http://0.0.0.0 or http://www.dbserver.com +* database = The name of the database you will be accessing +* options = All Drivers - 'persist', 'persistent', 'debug', 'fetchmode' +* Mysql (all) - 'port', 'clientflags' +* Mysqli - 'socket' +* Postgress (all) - 'port' +* modules = The modules that should be loaded. IE: pear, cache, extend, ect. +* +*/ + +// $dbtype = "mysql"; + +/** +* If you want to maintain compatability with the ADOdb ADONewConnection( $dbtype ) +* function you should designate the modules you need loaded below. If you designate +* the modules below you do not need to designate them in +* ADONewConnection( $dbtype, $modules ). +* +* If you would like more than one module loaded at the same time concatinate the +* module names using a colon (:). +* +* Example: +* $modules = "pear:transaction:extend"; +* +* The above example would load the Pear, Transaction and Extend modules +* automatically. +*/ + +// $modules = "pear"; +?> \ No newline at end of file Deleted: trunk/functions/adodb.config.php =================================================================== --- trunk/functions/adodb.config.php 2007-07-31 00:51:52 UTC (rev 57) +++ trunk/functions/adodb.config.php 2007-07-31 00:52:18 UTC (rev 58) @@ -1,52 +0,0 @@ -<?php -/** - * ADOdb Lite Configuration File - */ - -/** -* Set the $dbtype variable to the database designator. -* If this variable is enabled it will override the database designator -* entered in the ADONewConnection( $dbtype ) function. The database -* designator in a DSN string will be overridden but the rest of the DSN -* string will be used. -* -* You can place a DSN entry in the $dbtype variable if you would like to -* auto connect to your database. -* -* Example: -* -* $dbtype = "driver://username:password@hostname/database?options[=value]#modules"; -* -* driver = Databasetype Designator listed in the table at the start of this page. -* username = The Username needed to access the database -* password = Optional password for accessing the database -* hostname = localhost or url/ip address IE: http://0.0.0.0 or http://www.dbserver.com -* database = The name of the database you will be accessing -* options = All Drivers - 'persist', 'persistent', 'debug', 'fetchmode' -* Mysql (all) - 'port', 'clientflags' -* Mysqli - 'socket' -* Postgress (all) - 'port' -* modules = The modules that should be loaded. IE: pear, cache, extend, ect. -* -*/ - -// $dbtype = "mysql"; - -/** -* If you want to maintain compatability with the ADOdb ADONewConnection( $dbtype ) -* function you should designate the modules you need loaded below. If you designate -* the modules below you do not need to designate them in -* ADONewConnection( $dbtype, $modules ). -* -* If you would like more than one module loaded at the same time concatinate the -* module names using a colon (:). -* -* Example: -* $modules = "pear:transaction:extend"; -* -* The above example would load the Pear, Transaction and Extend modules -* automatically. -*/ - -// $modules = "pear"; -?> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:53:08
|
Revision: 59 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=59&view=rev Author: caleb870 Date: 2007-07-30 17:53:08 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb.inc.php Removed Paths: ------------- trunk/functions/adodb.inc.php Copied: trunk/functions/adodb/adodb.inc.php (from rev 58, trunk/functions/adodb.inc.php) =================================================================== --- trunk/functions/adodb/adodb.inc.php (rev 0) +++ trunk/functions/adodb/adodb.inc.php 2007-07-31 00:53:08 UTC (rev 59) @@ -0,0 +1,392 @@ +<?php + +/** + * ADOdb Lite is a PHP class to encapsulate multiple database APIs and is compatible with + * a subset of the ADODB Command Syntax. + * Currently supports Frontbase, MaxDB, miniSQL, MSSQL, MSSQL Pro, MySQLi, MySQLt, MySQL, PostgresSQL, + * PostgresSQL64, PostgresSQL7, PostgresSQL8, SqLite, SqLite Pro, Sybase and Sybase ASE. + * + */ + +if (!defined('_ADODB_LAYER')) + define('_ADODB_LAYER',1); + +if (!defined('ADODB_DIR')) + define('ADODB_DIR', dirname(__FILE__)); + +$ADODB_vers = 'V1.42 ADOdb Lite 11 January 2007 (c) 2005-2007 Mark Dickenson. All rights reserved. Released LGPL.'; + +define('ADODB_FETCH_DEFAULT',0); +define('ADODB_FETCH_NUM',1); +define('ADODB_FETCH_ASSOC',2); +define('ADODB_FETCH_BOTH',3); + +GLOBAL $ADODB_FETCH_MODE; +$ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT; // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default... + +/** + * Database connection + * Usage: $db = new ADONewConnection('dbtype'); + * + * @access public + * @param string $dbtype + */ + +function &ADONewConnection( $dbtype = 'mysql', $modules = '' ) +{ + global $ADODB_FETCH_MODE; + $false = false; + + @include( ADODB_DIR . '/adodb.config.php' ); + + if (strpos($dbtype,'://')) { + $dsn_array = @parse_url(rawurldecode($dbtype)); + + if (!$dsn_array || !$dsn_array['scheme']) + return $false; + + $dbtype = $dsn_array['scheme']; + $modules = (!empty($dsn_array['fragment'])) ? $dsn_array['fragment'] : $modules; + } else $dsn_array = array('scheme'=>''); + + $dbtype = strtolower($dbtype); + include_once ADODB_DIR . '/adodbSQL_drivers/' . $dbtype . '/' . $dbtype . '_driver.inc'; + $last_module = $dbtype . '_' . 'driver'; + if(!empty($modules)) + { + $module_list = explode(":", strtolower($modules)); + $generic_modules = array(); + foreach($module_list as $mod) { + $mod = trim($mod); + if(is_file(ADODB_DIR . '/generic_modules/' . $mod . '_module.inc')) + { + $generic_modules[] = $mod; + } + else + { + include_once ADODB_DIR . '/adodbSQL_drivers/' . $dbtype . '/' . $dbtype . '_' . $mod . '_module.inc'; + $last_module = $dbtype . '_' . $mod; + } + } + + if(count($generic_modules)) + { + foreach($generic_modules as $mod) { + include_once ADODB_DIR . '/generic_modules/' . $mod . '_module.inc'; + $last_module = $mod; + } + } + } + + $extention = $last_module . '_ADOConnection'; + + $object = new $extention(); + $object->last_module_name = $last_module; + $object->raiseErrorFn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false; + $object->query_count = 0; + $object->query_time_total = 0; + + if(!empty($dsn_array['scheme'])) + { + if (isset($dsn_array['port'])) $object->port = $dsn_array['port']; + $persistent = false; + $forcenew = false; + if (isset($dsn_array['query'])) { + $option_array = explode('&', $dsn_array['query']); + foreach($option_array as $element => $value) { + $array = explode('=', $value); + $data = isset($array[1]) ? $array[1] : 1; + switch(strtolower($array[0])) { + case 'persist': + case 'persistent': + $persistent = $data; + break; + case 'debug': + $object->debug = (integer) $data; + break; + case 'fetchmode': + $ADODB_FETCH_MODE = constant($data); + break; + case 'clientflags': + $object->clientFlags = $data; + break; + case 'port': + $object->port = $data; + break; + case 'socket': + $object->socket = $data; + break; + case 'forcenew': + $forcenew = $data; + break; + } + } + } + + $dsn_array['host'] = isset($dsn_array['host']) ? $dsn_array['host'] : ''; + $dsn_array['user'] = isset($dsn_array['user']) ? $dsn_array['user'] : ''; + $dsn_array['pass'] = isset($dsn_array['pass']) ? $dsn_array['pass'] : ''; + $dsn_array['path'] = isset($dsn_array['path']) ? substr($dsn_array['path'], 1) : ''; + + $result = $object->_connect($dsn_array['host'], $dsn_array['user'], $dsn_array['pass'], $dsn_array['path'], $persistent, $forcenew); + + if (!$result) return $false; + } + + return $object; +} + +/** + * Alternative Database connection + * Usage: $db = new NewADOConnection('dbtype'); + * + * @access public + * @param string $dbtype + */ + +function &NewADOConnection($dbtype='', $module = '' ) +{ + $tmp =& ADONewConnection($dbtype, $module); + return $tmp; +} + +function &NewDataDictionary(&$connection, $dbtype=false) +{ + if(!$dbtype) + $dbtype = $connection->dbtype; + include_once ADODB_DIR . '/adodb-datadict.inc.php'; + include_once ADODB_DIR . '/adodbSQL_drivers/' . $dbtype . '/' . $dbtype . '_datadict.inc'; + + $class = "ADODB2_$dbtype"; + $dict = new $class(); + $dict->connection = &$connection; + $dict->upperName = strtoupper($dbtype); + $dict->quote = $connection->nameQuote; + $dict->debug_echo = $connection->debug_echo; + + return $dict; +} + +/** + * Backwards compatible with ADOdb usage of NewPerfMonitor + * Change to module basis for PerfMon mean we need only return a reference to $connection object. + * Usage: $perf =& NewPerfMonitor($conn); - $perf is a reference to $conn + * + * @access public + * @param ADOConnection $connection + * @param string $dbtype This is an optional parameter with no actual use in ADOdb-Lite; for BC only. + */ +function &NewPerfMonitor(&$connection, $dbtype=false) +{ + return $connection; +} + +class ADOConnection +{ + var $connectionId = false; + var $record_set = false; + var $database; + var $dbtype; + var $dataProvider; + var $host; + var $open; + var $password; + var $username; + var $persistent; + var $debug = false; + var $debug_console = false; + var $debug_echo = true; + var $debug_output; + var $forcenewconnection = false; + var $createdatabase = false; + var $last_module_name; + var $socket = false; + var $port = false; + var $clientFlags = 0; + var $nameQuote = '"'; + var $sysDate = false; /// name of function that returns the current date + var $sysTimeStamp = false; /// name of function that returns the current timestamp + var $sql; + var $raiseErrorFn = false; + var $query_count = 0; + var $query_time_total = 0; + var $query_list = array(); + var $query_list_time = array(); + var $query_list_errors = array(); + var $_logsql = false; + + function ADOConnection() + { + } + + /** + * Returns floating point version number of ADOdb Lite + * Usage: $db->Version(); + * + * @access public + */ + + function Version() + { + global $ADODB_vers; + return (float) substr($ADODB_vers,1); + } + + /** + * Returns true if connected to database + * Usage: $db->IsConnected(); + * + * @access public + */ + + function IsConnected() + { + if($this->connectionId === false || $this->connectionId == false) + return false; + else return true; + } + + /** + * Normal Database connection + * Usage: $result = $db->Connect('host', 'username', 'password', 'database'); + * + * @access public + * @param string $database + * @param string $host + * @param string $password + * @param string $username + * @param string $forcenew // private + */ + + function Connect( $host = "", $username = "", $password = "", $database = "", $forcenew = false) + { + return $this->_connect($host, $username, $password, $database, false, $forcenew); + } + + /** + * Persistent Database connection + * Usage: $result = $db->PConnect('host', 'username', 'password', 'database'); + * + * @access public + * @param string $database + * @param string $host + * @param string $password + * @param string $username + */ + + function PConnect( $host = "", $username = "", $password = "", $database = "") + { + return $this->_connect($host, $username, $password, $database, true, false); + } + + /** + * Force New Database connection + * Usage: $result = $db->NConnect('host', 'username', 'password', 'database'); + * + * @access public + * @param string $database + * @param string $host + * @param string $password + * @param string $username + */ + + function NConnect( $host = "", $username = "", $password = "", $database = "") + { + return $this->_connect($host, $username, $password, $database, false, true); + } + + /** + * Returns SQL query and instantiates sql statement & resultset driver + * Usage: $linkId =& $db->execute( 'SELECT * FROM foo ORDER BY id' ); + * + * @access public + * @param string $sql + * @return mixed Resource ID, Array + */ + + function &Execute( $sql, $inputarr = false ) + { + // adodb_log_sql will time the query execution and log the sql query + // note: the later $this->do_query() should not run since adodb_log_sql() independently executes the query itself. + if($this->_logsql === true) + { + $ret =& adodb_log_sql($this, $sql, $inputarr); + if (isset($ret)) return $ret; + } + $rs =& $this->do_query($sql, -1, -1, $inputarr); + return $rs; + } + + /** + * Returns SQL query and instantiates sql statement & resultset driver + * Usage: $linkId =& $db->SelectLimit( 'SELECT * FROM foo ORDER BY id', $nrows, $offset ); + * $nrows and $offset are optional + * + * @access public + * @param string $sql + * @param string $nrows + * @param string $offset + * @return mixed Resource ID, Array + */ + + function &SelectLimit( $sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0 ) + { + $rs =& $this->do_query( $sql, $offset, $nrows, $inputarr); + return $rs; + } + + /** + * Display debug output and database error. + * + * @access private + */ + + function outp($text, $newline = true) + { + global $ADODB_OUTP; + $this->debug_output = "<br>\n(" . $this->dbtype . "): ".htmlspecialchars($text)."<br>\n Error (" . $this->ErrorNo() .'): '. $this->ErrorMsg() . "<br>\n"; + + if(defined('ADODB_OUTP')) + { + $fn = ADODB_OUTP; + } else if(isset($ADODB_OUTP)) + { + $fn = $ADODB_OUTP; + } + + if(defined('ADODB_OUTP') || isset($ADODB_OUTP)) + { + $fn($this->debug_output, $newline); + return; + } + + if($this->debug_echo) + echo $this->debug_output; + } + +} + +/** + * Empty result record set for updates, inserts, ect + * + * @access private + */ + +class ADORecordSet_empty +{ + var $fields = false; + var $EOF = true; + function MoveNext() {return;} + function RecordCount() {return 0;} + function FieldCount() {return 0;} + function EOF(){return TRUE;} + function Close(){return true;} +} + +class ADOFieldObject { + var $name = ''; + var $max_length=0; + var $type=""; +} + +?> \ No newline at end of file Deleted: trunk/functions/adodb.inc.php =================================================================== --- trunk/functions/adodb.inc.php 2007-07-31 00:52:18 UTC (rev 58) +++ trunk/functions/adodb.inc.php 2007-07-31 00:53:08 UTC (rev 59) @@ -1,392 +0,0 @@ -<?php - -/** - * ADOdb Lite is a PHP class to encapsulate multiple database APIs and is compatible with - * a subset of the ADODB Command Syntax. - * Currently supports Frontbase, MaxDB, miniSQL, MSSQL, MSSQL Pro, MySQLi, MySQLt, MySQL, PostgresSQL, - * PostgresSQL64, PostgresSQL7, PostgresSQL8, SqLite, SqLite Pro, Sybase and Sybase ASE. - * - */ - -if (!defined('_ADODB_LAYER')) - define('_ADODB_LAYER',1); - -if (!defined('ADODB_DIR')) - define('ADODB_DIR', dirname(__FILE__)); - -$ADODB_vers = 'V1.42 ADOdb Lite 11 January 2007 (c) 2005-2007 Mark Dickenson. All rights reserved. Released LGPL.'; - -define('ADODB_FETCH_DEFAULT',0); -define('ADODB_FETCH_NUM',1); -define('ADODB_FETCH_ASSOC',2); -define('ADODB_FETCH_BOTH',3); - -GLOBAL $ADODB_FETCH_MODE; -$ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT; // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default... - -/** - * Database connection - * Usage: $db = new ADONewConnection('dbtype'); - * - * @access public - * @param string $dbtype - */ - -function &ADONewConnection( $dbtype = 'mysql', $modules = '' ) -{ - global $ADODB_FETCH_MODE; - $false = false; - - @include( ADODB_DIR . '/adodb.config.php' ); - - if (strpos($dbtype,'://')) { - $dsn_array = @parse_url(rawurldecode($dbtype)); - - if (!$dsn_array || !$dsn_array['scheme']) - return $false; - - $dbtype = $dsn_array['scheme']; - $modules = (!empty($dsn_array['fragment'])) ? $dsn_array['fragment'] : $modules; - } else $dsn_array = array('scheme'=>''); - - $dbtype = strtolower($dbtype); - include_once ADODB_DIR . '/adodbSQL_drivers/' . $dbtype . '/' . $dbtype . '_driver.inc'; - $last_module = $dbtype . '_' . 'driver'; - if(!empty($modules)) - { - $module_list = explode(":", strtolower($modules)); - $generic_modules = array(); - foreach($module_list as $mod) { - $mod = trim($mod); - if(is_file(ADODB_DIR . '/generic_modules/' . $mod . '_module.inc')) - { - $generic_modules[] = $mod; - } - else - { - include_once ADODB_DIR . '/adodbSQL_drivers/' . $dbtype . '/' . $dbtype . '_' . $mod . '_module.inc'; - $last_module = $dbtype . '_' . $mod; - } - } - - if(count($generic_modules)) - { - foreach($generic_modules as $mod) { - include_once ADODB_DIR . '/generic_modules/' . $mod . '_module.inc'; - $last_module = $mod; - } - } - } - - $extention = $last_module . '_ADOConnection'; - - $object = new $extention(); - $object->last_module_name = $last_module; - $object->raiseErrorFn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false; - $object->query_count = 0; - $object->query_time_total = 0; - - if(!empty($dsn_array['scheme'])) - { - if (isset($dsn_array['port'])) $object->port = $dsn_array['port']; - $persistent = false; - $forcenew = false; - if (isset($dsn_array['query'])) { - $option_array = explode('&', $dsn_array['query']); - foreach($option_array as $element => $value) { - $array = explode('=', $value); - $data = isset($array[1]) ? $array[1] : 1; - switch(strtolower($array[0])) { - case 'persist': - case 'persistent': - $persistent = $data; - break; - case 'debug': - $object->debug = (integer) $data; - break; - case 'fetchmode': - $ADODB_FETCH_MODE = constant($data); - break; - case 'clientflags': - $object->clientFlags = $data; - break; - case 'port': - $object->port = $data; - break; - case 'socket': - $object->socket = $data; - break; - case 'forcenew': - $forcenew = $data; - break; - } - } - } - - $dsn_array['host'] = isset($dsn_array['host']) ? $dsn_array['host'] : ''; - $dsn_array['user'] = isset($dsn_array['user']) ? $dsn_array['user'] : ''; - $dsn_array['pass'] = isset($dsn_array['pass']) ? $dsn_array['pass'] : ''; - $dsn_array['path'] = isset($dsn_array['path']) ? substr($dsn_array['path'], 1) : ''; - - $result = $object->_connect($dsn_array['host'], $dsn_array['user'], $dsn_array['pass'], $dsn_array['path'], $persistent, $forcenew); - - if (!$result) return $false; - } - - return $object; -} - -/** - * Alternative Database connection - * Usage: $db = new NewADOConnection('dbtype'); - * - * @access public - * @param string $dbtype - */ - -function &NewADOConnection($dbtype='', $module = '' ) -{ - $tmp =& ADONewConnection($dbtype, $module); - return $tmp; -} - -function &NewDataDictionary(&$connection, $dbtype=false) -{ - if(!$dbtype) - $dbtype = $connection->dbtype; - include_once ADODB_DIR . '/adodb-datadict.inc.php'; - include_once ADODB_DIR . '/adodbSQL_drivers/' . $dbtype . '/' . $dbtype . '_datadict.inc'; - - $class = "ADODB2_$dbtype"; - $dict = new $class(); - $dict->connection = &$connection; - $dict->upperName = strtoupper($dbtype); - $dict->quote = $connection->nameQuote; - $dict->debug_echo = $connection->debug_echo; - - return $dict; -} - -/** - * Backwards compatible with ADOdb usage of NewPerfMonitor - * Change to module basis for PerfMon mean we need only return a reference to $connection object. - * Usage: $perf =& NewPerfMonitor($conn); - $perf is a reference to $conn - * - * @access public - * @param ADOConnection $connection - * @param string $dbtype This is an optional parameter with no actual use in ADOdb-Lite; for BC only. - */ -function &NewPerfMonitor(&$connection, $dbtype=false) -{ - return $connection; -} - -class ADOConnection -{ - var $connectionId = false; - var $record_set = false; - var $database; - var $dbtype; - var $dataProvider; - var $host; - var $open; - var $password; - var $username; - var $persistent; - var $debug = false; - var $debug_console = false; - var $debug_echo = true; - var $debug_output; - var $forcenewconnection = false; - var $createdatabase = false; - var $last_module_name; - var $socket = false; - var $port = false; - var $clientFlags = 0; - var $nameQuote = '"'; - var $sysDate = false; /// name of function that returns the current date - var $sysTimeStamp = false; /// name of function that returns the current timestamp - var $sql; - var $raiseErrorFn = false; - var $query_count = 0; - var $query_time_total = 0; - var $query_list = array(); - var $query_list_time = array(); - var $query_list_errors = array(); - var $_logsql = false; - - function ADOConnection() - { - } - - /** - * Returns floating point version number of ADOdb Lite - * Usage: $db->Version(); - * - * @access public - */ - - function Version() - { - global $ADODB_vers; - return (float) substr($ADODB_vers,1); - } - - /** - * Returns true if connected to database - * Usage: $db->IsConnected(); - * - * @access public - */ - - function IsConnected() - { - if($this->connectionId === false || $this->connectionId == false) - return false; - else return true; - } - - /** - * Normal Database connection - * Usage: $result = $db->Connect('host', 'username', 'password', 'database'); - * - * @access public - * @param string $database - * @param string $host - * @param string $password - * @param string $username - * @param string $forcenew // private - */ - - function Connect( $host = "", $username = "", $password = "", $database = "", $forcenew = false) - { - return $this->_connect($host, $username, $password, $database, false, $forcenew); - } - - /** - * Persistent Database connection - * Usage: $result = $db->PConnect('host', 'username', 'password', 'database'); - * - * @access public - * @param string $database - * @param string $host - * @param string $password - * @param string $username - */ - - function PConnect( $host = "", $username = "", $password = "", $database = "") - { - return $this->_connect($host, $username, $password, $database, true, false); - } - - /** - * Force New Database connection - * Usage: $result = $db->NConnect('host', 'username', 'password', 'database'); - * - * @access public - * @param string $database - * @param string $host - * @param string $password - * @param string $username - */ - - function NConnect( $host = "", $username = "", $password = "", $database = "") - { - return $this->_connect($host, $username, $password, $database, false, true); - } - - /** - * Returns SQL query and instantiates sql statement & resultset driver - * Usage: $linkId =& $db->execute( 'SELECT * FROM foo ORDER BY id' ); - * - * @access public - * @param string $sql - * @return mixed Resource ID, Array - */ - - function &Execute( $sql, $inputarr = false ) - { - // adodb_log_sql will time the query execution and log the sql query - // note: the later $this->do_query() should not run since adodb_log_sql() independently executes the query itself. - if($this->_logsql === true) - { - $ret =& adodb_log_sql($this, $sql, $inputarr); - if (isset($ret)) return $ret; - } - $rs =& $this->do_query($sql, -1, -1, $inputarr); - return $rs; - } - - /** - * Returns SQL query and instantiates sql statement & resultset driver - * Usage: $linkId =& $db->SelectLimit( 'SELECT * FROM foo ORDER BY id', $nrows, $offset ); - * $nrows and $offset are optional - * - * @access public - * @param string $sql - * @param string $nrows - * @param string $offset - * @return mixed Resource ID, Array - */ - - function &SelectLimit( $sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0 ) - { - $rs =& $this->do_query( $sql, $offset, $nrows, $inputarr); - return $rs; - } - - /** - * Display debug output and database error. - * - * @access private - */ - - function outp($text, $newline = true) - { - global $ADODB_OUTP; - $this->debug_output = "<br>\n(" . $this->dbtype . "): ".htmlspecialchars($text)."<br>\n Error (" . $this->ErrorNo() .'): '. $this->ErrorMsg() . "<br>\n"; - - if(defined('ADODB_OUTP')) - { - $fn = ADODB_OUTP; - } else if(isset($ADODB_OUTP)) - { - $fn = $ADODB_OUTP; - } - - if(defined('ADODB_OUTP') || isset($ADODB_OUTP)) - { - $fn($this->debug_output, $newline); - return; - } - - if($this->debug_echo) - echo $this->debug_output; - } - -} - -/** - * Empty result record set for updates, inserts, ect - * - * @access private - */ - -class ADORecordSet_empty -{ - var $fields = false; - var $EOF = true; - function MoveNext() {return;} - function RecordCount() {return 0;} - function FieldCount() {return 0;} - function EOF(){return TRUE;} - function Close(){return true;} -} - -class ADOFieldObject { - var $name = ''; - var $max_length=0; - var $type=""; -} - -?> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:54:06
|
Revision: 61 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=61&view=rev Author: caleb870 Date: 2007-07-30 17:54:05 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-error.inc.php Removed Paths: ------------- trunk/functions/adodb-error.inc.php Copied: trunk/functions/adodb/adodb-error.inc.php (from rev 60, trunk/functions/adodb-error.inc.php) =================================================================== --- trunk/functions/adodb/adodb-error.inc.php (rev 0) +++ trunk/functions/adodb/adodb-error.inc.php 2007-07-31 00:54:05 UTC (rev 61) @@ -0,0 +1,277 @@ +<?php +/** + * @version V4.93 10 Oct 2006 (c) 2000-2006 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. + * + * Set tabs to 4 for best viewing. + * + * The following code is adapted from the PEAR DB error handling code. + * Portions (c)1997-2002 The PHP Group. + */ + + +if (!defined("DB_ERROR")) define("DB_ERROR",-1); + +if (!defined("DB_ERROR_SYNTAX")) { + define("DB_ERROR_SYNTAX", -2); + define("DB_ERROR_CONSTRAINT", -3); + define("DB_ERROR_NOT_FOUND", -4); + define("DB_ERROR_ALREADY_EXISTS", -5); + define("DB_ERROR_UNSUPPORTED", -6); + define("DB_ERROR_MISMATCH", -7); + define("DB_ERROR_INVALID", -8); + define("DB_ERROR_NOT_CAPABLE", -9); + define("DB_ERROR_TRUNCATED", -10); + define("DB_ERROR_INVALID_NUMBER", -11); + define("DB_ERROR_INVALID_DATE", -12); + define("DB_ERROR_DIVZERO", -13); + define("DB_ERROR_NODBSELECTED", -14); + define("DB_ERROR_CANNOT_CREATE", -15); + define("DB_ERROR_CANNOT_DELETE", -16); + define("DB_ERROR_CANNOT_DROP", -17); + define("DB_ERROR_NOSUCHTABLE", -18); + define("DB_ERROR_NOSUCHFIELD", -19); + define("DB_ERROR_NEED_MORE_DATA", -20); + define("DB_ERROR_NOT_LOCKED", -21); + define("DB_ERROR_VALUE_COUNT_ON_ROW", -22); + define("DB_ERROR_INVALID_DSN", -23); + define("DB_ERROR_CONNECT_FAILED", -24); + define("DB_ERROR_EXTENSION_NOT_FOUND",-25); + define("DB_ERROR_NOSUCHDB", -25); + define("DB_ERROR_ACCESS_VIOLATION", -26); +} + +function adodb_errormsg($value) +{ + global $ADODB_LANG,$ADODB_LANG_ARRAY; + + if (empty($ADODB_LANG)) + $ADODB_LANG = 'en'; + if (isset($ADODB_LANG_ARRAY['LANG']) && $ADODB_LANG_ARRAY['LANG'] == $ADODB_LANG) ; + else + { + include_once(ADODB_DIR."/lang/adodb-$ADODB_LANG.inc.php"); + } + return isset($ADODB_LANG_ARRAY[$value]) ? $ADODB_LANG_ARRAY[$value] : $ADODB_LANG_ARRAY[DB_ERROR]; +} + +function adodb_error($provider,$dbType,$errno) +{ + //var_dump($errno); + if (is_numeric($errno) && $errno == 0) + return 0; + + switch($provider) { + case 'mysql': + $map = adodb_error_mysql(); + break; + + case 'oracle': + case 'oci8': + $map = adodb_error_oci8(); + break; + + case 'ibase': + $map = adodb_error_ibase(); + break; + + case 'odbc': + $map = adodb_error_odbc(); + break; + + case 'mssql': + case 'sybase': + $map = adodb_error_mssql(); + break; + + case 'informix': + $map = adodb_error_ifx(); + break; + + case 'postgres': + return adodb_error_pg($errno); + break; + + case 'sqlite': + return $map = adodb_error_sqlite(); + break; + default: + return DB_ERROR; + } + //print_r($map); + //var_dump($errno); + if (isset($map[$errno])) + return $map[$errno]; + return DB_ERROR; +} + +//************************************************************************************** + +function adodb_error_pg($errormsg) +{ + if (is_numeric($errormsg)) + return (integer) $errormsg; + + static $error_regexps = array( + '/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/' => DB_ERROR_NOSUCHTABLE, + '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS, + '/divide by zero$/' => DB_ERROR_DIVZERO, + '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER, + '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD, + '/parser: parse error at or near \"/' => DB_ERROR_SYNTAX, + '/referential integrity violation/' => DB_ERROR_CONSTRAINT, + '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/' + => DB_ERROR_ALREADY_EXISTS + ); + reset($error_regexps); + while (list($regexp,$code) = each($error_regexps)) + { + if (preg_match($regexp, $errormsg)) + { + return $code; + } + } + // Fall back to DB_ERROR if there was no mapping. + return DB_ERROR; +} + +function adodb_error_odbc() +{ + static $MAP = array( + '01004' => DB_ERROR_TRUNCATED, + '07001' => DB_ERROR_MISMATCH, + '21S01' => DB_ERROR_MISMATCH, + '21S02' => DB_ERROR_MISMATCH, + '22003' => DB_ERROR_INVALID_NUMBER, + '22008' => DB_ERROR_INVALID_DATE, + '22012' => DB_ERROR_DIVZERO, + '23000' => DB_ERROR_CONSTRAINT, + '24000' => DB_ERROR_INVALID, + '34000' => DB_ERROR_INVALID, + '37000' => DB_ERROR_SYNTAX, + '42000' => DB_ERROR_SYNTAX, + 'IM001' => DB_ERROR_UNSUPPORTED, + 'S0000' => DB_ERROR_NOSUCHTABLE, + 'S0001' => DB_ERROR_NOT_FOUND, + 'S0002' => DB_ERROR_NOSUCHTABLE, + 'S0011' => DB_ERROR_ALREADY_EXISTS, + 'S0012' => DB_ERROR_NOT_FOUND, + 'S0021' => DB_ERROR_ALREADY_EXISTS, + 'S0022' => DB_ERROR_NOT_FOUND, + 'S1000' => DB_ERROR_NOSUCHTABLE, + 'S1009' => DB_ERROR_INVALID, + 'S1090' => DB_ERROR_INVALID, + 'S1C00' => DB_ERROR_NOT_CAPABLE + ); + return $MAP; +} + +function adodb_error_ibase() +{ + static $MAP = array( + -104 => DB_ERROR_SYNTAX, + -150 => DB_ERROR_ACCESS_VIOLATION, + -151 => DB_ERROR_ACCESS_VIOLATION, + -155 => DB_ERROR_NOSUCHTABLE, + -157 => DB_ERROR_NOSUCHFIELD, + -158 => DB_ERROR_VALUE_COUNT_ON_ROW, + -170 => DB_ERROR_MISMATCH, + -171 => DB_ERROR_MISMATCH, + -172 => DB_ERROR_INVALID, + -204 => DB_ERROR_INVALID, + -205 => DB_ERROR_NOSUCHFIELD, + -206 => DB_ERROR_NOSUCHFIELD, + -208 => DB_ERROR_INVALID, + -219 => DB_ERROR_NOSUCHTABLE, + -297 => DB_ERROR_CONSTRAINT, + -530 => DB_ERROR_CONSTRAINT, + -803 => DB_ERROR_CONSTRAINT, + -551 => DB_ERROR_ACCESS_VIOLATION, + -552 => DB_ERROR_ACCESS_VIOLATION, + -922 => DB_ERROR_NOSUCHDB, + -923 => DB_ERROR_CONNECT_FAILED, + -924 => DB_ERROR_CONNECT_FAILED + ); + return $MAP; +} + +function adodb_error_ifx() +{ + static $MAP = array( + '-201' => DB_ERROR_SYNTAX, + '-206' => DB_ERROR_NOSUCHTABLE, + '-217' => DB_ERROR_NOSUCHFIELD, + '-329' => DB_ERROR_NODBSELECTED, + '-1204' => DB_ERROR_INVALID_DATE, + '-1205' => DB_ERROR_INVALID_DATE, + '-1206' => DB_ERROR_INVALID_DATE, + '-1209' => DB_ERROR_INVALID_DATE, + '-1210' => DB_ERROR_INVALID_DATE, + '-1212' => DB_ERROR_INVALID_DATE + ); + return $MAP; +} + +function adodb_error_oci8() +{ + static $MAP = array( + 1 => DB_ERROR_ALREADY_EXISTS, + 900 => DB_ERROR_SYNTAX, + 904 => DB_ERROR_NOSUCHFIELD, + 923 => DB_ERROR_SYNTAX, + 942 => DB_ERROR_NOSUCHTABLE, + 955 => DB_ERROR_ALREADY_EXISTS, + 1476 => DB_ERROR_DIVZERO, + 1722 => DB_ERROR_INVALID_NUMBER, + 2289 => DB_ERROR_NOSUCHTABLE, + 2291 => DB_ERROR_CONSTRAINT, + 2449 => DB_ERROR_CONSTRAINT + ); + return $MAP; +} + +function adodb_error_mssql() +{ + static $MAP = array( + 208 => DB_ERROR_NOSUCHTABLE, + 2601 => DB_ERROR_ALREADY_EXISTS + ); + return $MAP; +} + +function adodb_error_sqlite() +{ + static $MAP = array( + 1 => DB_ERROR_SYNTAX + ); + return $MAP; +} + +function adodb_error_mysql() +{ + static $MAP = array( + 1004 => DB_ERROR_CANNOT_CREATE, + 1005 => DB_ERROR_CANNOT_CREATE, + 1006 => DB_ERROR_CANNOT_CREATE, + 1007 => DB_ERROR_ALREADY_EXISTS, + 1008 => DB_ERROR_CANNOT_DROP, + 1045 => DB_ERROR_ACCESS_VIOLATION, + 1046 => DB_ERROR_NODBSELECTED, + 1049 => DB_ERROR_NOSUCHDB, + 1050 => DB_ERROR_ALREADY_EXISTS, + 1051 => DB_ERROR_NOSUCHTABLE, + 1054 => DB_ERROR_NOSUCHFIELD, + 1062 => DB_ERROR_ALREADY_EXISTS, + 1064 => DB_ERROR_SYNTAX, + 1100 => DB_ERROR_NOT_LOCKED, + 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, + 1146 => DB_ERROR_NOSUCHTABLE, + 1048 => DB_ERROR_CONSTRAINT, + 2002 => DB_ERROR_CONNECT_FAILED, + 2005 => DB_ERROR_CONNECT_FAILED + ); + return $MAP; +} +?> \ No newline at end of file Deleted: trunk/functions/adodb-error.inc.php =================================================================== --- trunk/functions/adodb-error.inc.php 2007-07-31 00:53:54 UTC (rev 60) +++ trunk/functions/adodb-error.inc.php 2007-07-31 00:54:05 UTC (rev 61) @@ -1,277 +0,0 @@ -<?php -/** - * @version V4.93 10 Oct 2006 (c) 2000-2006 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. - * - * Set tabs to 4 for best viewing. - * - * The following code is adapted from the PEAR DB error handling code. - * Portions (c)1997-2002 The PHP Group. - */ - - -if (!defined("DB_ERROR")) define("DB_ERROR",-1); - -if (!defined("DB_ERROR_SYNTAX")) { - define("DB_ERROR_SYNTAX", -2); - define("DB_ERROR_CONSTRAINT", -3); - define("DB_ERROR_NOT_FOUND", -4); - define("DB_ERROR_ALREADY_EXISTS", -5); - define("DB_ERROR_UNSUPPORTED", -6); - define("DB_ERROR_MISMATCH", -7); - define("DB_ERROR_INVALID", -8); - define("DB_ERROR_NOT_CAPABLE", -9); - define("DB_ERROR_TRUNCATED", -10); - define("DB_ERROR_INVALID_NUMBER", -11); - define("DB_ERROR_INVALID_DATE", -12); - define("DB_ERROR_DIVZERO", -13); - define("DB_ERROR_NODBSELECTED", -14); - define("DB_ERROR_CANNOT_CREATE", -15); - define("DB_ERROR_CANNOT_DELETE", -16); - define("DB_ERROR_CANNOT_DROP", -17); - define("DB_ERROR_NOSUCHTABLE", -18); - define("DB_ERROR_NOSUCHFIELD", -19); - define("DB_ERROR_NEED_MORE_DATA", -20); - define("DB_ERROR_NOT_LOCKED", -21); - define("DB_ERROR_VALUE_COUNT_ON_ROW", -22); - define("DB_ERROR_INVALID_DSN", -23); - define("DB_ERROR_CONNECT_FAILED", -24); - define("DB_ERROR_EXTENSION_NOT_FOUND",-25); - define("DB_ERROR_NOSUCHDB", -25); - define("DB_ERROR_ACCESS_VIOLATION", -26); -} - -function adodb_errormsg($value) -{ - global $ADODB_LANG,$ADODB_LANG_ARRAY; - - if (empty($ADODB_LANG)) - $ADODB_LANG = 'en'; - if (isset($ADODB_LANG_ARRAY['LANG']) && $ADODB_LANG_ARRAY['LANG'] == $ADODB_LANG) ; - else - { - include_once(ADODB_DIR."/lang/adodb-$ADODB_LANG.inc.php"); - } - return isset($ADODB_LANG_ARRAY[$value]) ? $ADODB_LANG_ARRAY[$value] : $ADODB_LANG_ARRAY[DB_ERROR]; -} - -function adodb_error($provider,$dbType,$errno) -{ - //var_dump($errno); - if (is_numeric($errno) && $errno == 0) - return 0; - - switch($provider) { - case 'mysql': - $map = adodb_error_mysql(); - break; - - case 'oracle': - case 'oci8': - $map = adodb_error_oci8(); - break; - - case 'ibase': - $map = adodb_error_ibase(); - break; - - case 'odbc': - $map = adodb_error_odbc(); - break; - - case 'mssql': - case 'sybase': - $map = adodb_error_mssql(); - break; - - case 'informix': - $map = adodb_error_ifx(); - break; - - case 'postgres': - return adodb_error_pg($errno); - break; - - case 'sqlite': - return $map = adodb_error_sqlite(); - break; - default: - return DB_ERROR; - } - //print_r($map); - //var_dump($errno); - if (isset($map[$errno])) - return $map[$errno]; - return DB_ERROR; -} - -//************************************************************************************** - -function adodb_error_pg($errormsg) -{ - if (is_numeric($errormsg)) - return (integer) $errormsg; - - static $error_regexps = array( - '/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/' => DB_ERROR_NOSUCHTABLE, - '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS, - '/divide by zero$/' => DB_ERROR_DIVZERO, - '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER, - '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD, - '/parser: parse error at or near \"/' => DB_ERROR_SYNTAX, - '/referential integrity violation/' => DB_ERROR_CONSTRAINT, - '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/' - => DB_ERROR_ALREADY_EXISTS - ); - reset($error_regexps); - while (list($regexp,$code) = each($error_regexps)) - { - if (preg_match($regexp, $errormsg)) - { - return $code; - } - } - // Fall back to DB_ERROR if there was no mapping. - return DB_ERROR; -} - -function adodb_error_odbc() -{ - static $MAP = array( - '01004' => DB_ERROR_TRUNCATED, - '07001' => DB_ERROR_MISMATCH, - '21S01' => DB_ERROR_MISMATCH, - '21S02' => DB_ERROR_MISMATCH, - '22003' => DB_ERROR_INVALID_NUMBER, - '22008' => DB_ERROR_INVALID_DATE, - '22012' => DB_ERROR_DIVZERO, - '23000' => DB_ERROR_CONSTRAINT, - '24000' => DB_ERROR_INVALID, - '34000' => DB_ERROR_INVALID, - '37000' => DB_ERROR_SYNTAX, - '42000' => DB_ERROR_SYNTAX, - 'IM001' => DB_ERROR_UNSUPPORTED, - 'S0000' => DB_ERROR_NOSUCHTABLE, - 'S0001' => DB_ERROR_NOT_FOUND, - 'S0002' => DB_ERROR_NOSUCHTABLE, - 'S0011' => DB_ERROR_ALREADY_EXISTS, - 'S0012' => DB_ERROR_NOT_FOUND, - 'S0021' => DB_ERROR_ALREADY_EXISTS, - 'S0022' => DB_ERROR_NOT_FOUND, - 'S1000' => DB_ERROR_NOSUCHTABLE, - 'S1009' => DB_ERROR_INVALID, - 'S1090' => DB_ERROR_INVALID, - 'S1C00' => DB_ERROR_NOT_CAPABLE - ); - return $MAP; -} - -function adodb_error_ibase() -{ - static $MAP = array( - -104 => DB_ERROR_SYNTAX, - -150 => DB_ERROR_ACCESS_VIOLATION, - -151 => DB_ERROR_ACCESS_VIOLATION, - -155 => DB_ERROR_NOSUCHTABLE, - -157 => DB_ERROR_NOSUCHFIELD, - -158 => DB_ERROR_VALUE_COUNT_ON_ROW, - -170 => DB_ERROR_MISMATCH, - -171 => DB_ERROR_MISMATCH, - -172 => DB_ERROR_INVALID, - -204 => DB_ERROR_INVALID, - -205 => DB_ERROR_NOSUCHFIELD, - -206 => DB_ERROR_NOSUCHFIELD, - -208 => DB_ERROR_INVALID, - -219 => DB_ERROR_NOSUCHTABLE, - -297 => DB_ERROR_CONSTRAINT, - -530 => DB_ERROR_CONSTRAINT, - -803 => DB_ERROR_CONSTRAINT, - -551 => DB_ERROR_ACCESS_VIOLATION, - -552 => DB_ERROR_ACCESS_VIOLATION, - -922 => DB_ERROR_NOSUCHDB, - -923 => DB_ERROR_CONNECT_FAILED, - -924 => DB_ERROR_CONNECT_FAILED - ); - return $MAP; -} - -function adodb_error_ifx() -{ - static $MAP = array( - '-201' => DB_ERROR_SYNTAX, - '-206' => DB_ERROR_NOSUCHTABLE, - '-217' => DB_ERROR_NOSUCHFIELD, - '-329' => DB_ERROR_NODBSELECTED, - '-1204' => DB_ERROR_INVALID_DATE, - '-1205' => DB_ERROR_INVALID_DATE, - '-1206' => DB_ERROR_INVALID_DATE, - '-1209' => DB_ERROR_INVALID_DATE, - '-1210' => DB_ERROR_INVALID_DATE, - '-1212' => DB_ERROR_INVALID_DATE - ); - return $MAP; -} - -function adodb_error_oci8() -{ - static $MAP = array( - 1 => DB_ERROR_ALREADY_EXISTS, - 900 => DB_ERROR_SYNTAX, - 904 => DB_ERROR_NOSUCHFIELD, - 923 => DB_ERROR_SYNTAX, - 942 => DB_ERROR_NOSUCHTABLE, - 955 => DB_ERROR_ALREADY_EXISTS, - 1476 => DB_ERROR_DIVZERO, - 1722 => DB_ERROR_INVALID_NUMBER, - 2289 => DB_ERROR_NOSUCHTABLE, - 2291 => DB_ERROR_CONSTRAINT, - 2449 => DB_ERROR_CONSTRAINT - ); - return $MAP; -} - -function adodb_error_mssql() -{ - static $MAP = array( - 208 => DB_ERROR_NOSUCHTABLE, - 2601 => DB_ERROR_ALREADY_EXISTS - ); - return $MAP; -} - -function adodb_error_sqlite() -{ - static $MAP = array( - 1 => DB_ERROR_SYNTAX - ); - return $MAP; -} - -function adodb_error_mysql() -{ - static $MAP = array( - 1004 => DB_ERROR_CANNOT_CREATE, - 1005 => DB_ERROR_CANNOT_CREATE, - 1006 => DB_ERROR_CANNOT_CREATE, - 1007 => DB_ERROR_ALREADY_EXISTS, - 1008 => DB_ERROR_CANNOT_DROP, - 1045 => DB_ERROR_ACCESS_VIOLATION, - 1046 => DB_ERROR_NODBSELECTED, - 1049 => DB_ERROR_NOSUCHDB, - 1050 => DB_ERROR_ALREADY_EXISTS, - 1051 => DB_ERROR_NOSUCHTABLE, - 1054 => DB_ERROR_NOSUCHFIELD, - 1062 => DB_ERROR_ALREADY_EXISTS, - 1064 => DB_ERROR_SYNTAX, - 1100 => DB_ERROR_NOT_LOCKED, - 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, - 1146 => DB_ERROR_NOSUCHTABLE, - 1048 => DB_ERROR_CONSTRAINT, - 2002 => DB_ERROR_CONNECT_FAILED, - 2005 => DB_ERROR_CONNECT_FAILED - ); - return $MAP; -} -?> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:53:52
|
Revision: 60 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=60&view=rev Author: caleb870 Date: 2007-07-30 17:53:54 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-datadict.inc.php Removed Paths: ------------- trunk/functions/adodb-datadict.inc.php Copied: trunk/functions/adodb/adodb-datadict.inc.php (from rev 59, trunk/functions/adodb-datadict.inc.php) =================================================================== --- trunk/functions/adodb/adodb-datadict.inc.php (rev 0) +++ trunk/functions/adodb/adodb-datadict.inc.php 2007-07-31 00:53:54 UTC (rev 60) @@ -0,0 +1,838 @@ +<?php + +/** + V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + + Set tabs to 4 for best viewing. + + DOCUMENTATION: + + See adodb/tests/test-datadict.php for docs and examples. + + Modified 3 October, 2005 for use with ADOdb Lite by Mark Dickenson +*/ + +/* + Test script for parser +*/ + +// security - hide paths +if (!defined('ADODB_DIR')) die(); + +if (!function_exists('ctype_alnum')) { + function ctype_alnum($text) { + return preg_match('/^[a-z0-9]*$/i', $text); + } +} + +function _array_change_key_case($an_array) +{ + if (is_array($an_array)) { + $new_array = array(); + foreach($an_array as $key=>$value) + $new_array[strtoupper($key)] = $value; + + return $new_array; + } + + return $an_array; +} + +/** + Parse arguments, treat "text" (text) and 'text' as quotation marks. + To escape, use "" or '' or )) + + Will read in "abc def" sans quotes, as: abc def + Same with 'abc def'. + However if `abc def`, then will read in as `abc def` + + @param endstmtchar Character that indicates end of statement + @param tokenchars Include the following characters in tokens apart from A-Z and 0-9 + @returns 2 dimensional array containing parsed tokens. +*/ +function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-') +{ + $pos = 0; + $intoken = false; + $stmtno = 0; + $endquote = false; + $tokens = array(); + $tokens[$stmtno] = array(); + $max = strlen($args); + $quoted = false; + + while ($pos < $max) { + $ch = substr($args,$pos,1); + switch($ch) { + case ' ': + case "\t": + case "\n": + case "\r": + if (!$quoted) { + if ($intoken) { + $intoken = false; + $tokens[$stmtno][] = implode('',$tokarr); + } + break; + } + $tokarr[] = $ch; + break; + case '`': + if ($intoken) $tokarr[] = $ch; + case '(': + case ')': + case '"': + case "'": + if ($intoken) { + if (empty($endquote)) { + $tokens[$stmtno][] = implode('',$tokarr); + if ($ch == '(') $endquote = ')'; + else $endquote = $ch; + $quoted = true; + $intoken = true; + $tokarr = array(); + } else if ($endquote == $ch) { + $ch2 = substr($args,$pos+1,1); + if ($ch2 == $endquote) { + $pos += 1; + $tokarr[] = $ch2; + } else { + $quoted = false; + $intoken = false; + $tokens[$stmtno][] = implode('',$tokarr); + $endquote = ''; + } + } else + $tokarr[] = $ch; + }else { + if ($ch == '(') $endquote = ')'; + else $endquote = $ch; + $quoted = true; + $intoken = true; + $tokarr = array(); + if ($ch == '`') $tokarr[] = '`'; + } + break; + default: + if (!$intoken) { + if ($ch == $endstmtchar) { + $stmtno += 1; + $tokens[$stmtno] = array(); + break; + } + $intoken = true; + $quoted = false; + $endquote = false; + $tokarr = array(); + } + if ($quoted) $tokarr[] = $ch; + else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch; + else { + if ($ch == $endstmtchar) { + $tokens[$stmtno][] = implode('',$tokarr); + $stmtno += 1; + $tokens[$stmtno] = array(); + $intoken = false; + $tokarr = array(); + break; + } + $tokens[$stmtno][] = implode('',$tokarr); + $tokens[$stmtno][] = $ch; + $intoken = false; + } + } + $pos += 1; + } + if ($intoken) $tokens[$stmtno][] = implode('',$tokarr); + + return $tokens; +} + + +class ADODB_DataDict { + var $connection; + var $debug = false; + var $dropTable = 'DROP TABLE %s'; + var $renameTable = 'RENAME TABLE %s TO %s'; + var $dropIndex = 'DROP INDEX %s'; + var $addCol = ' ADD'; + var $alterCol = ' ALTER COLUMN'; + var $dropCol = ' DROP COLUMN'; + var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s'; // table, old-column, new-column, column-definitions (not used by default) + var $nameRegex = '\w'; + var $nameRegexBrackets = 'a-zA-Z0-9_\(\)'; + var $schema = false; + var $serverInfo = array(); + var $autoIncrement = false; + var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql + var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob + /// in other words, we use a text area for editting. + var $metaTablesSQL; + var $metaColumnsSQL; + var $debug_echo = true; + var $fetchMode; + var $raiseErrorFn; + + function SetFetchMode($mode) + { + GLOBAL $ADODB_FETCH_MODE; + $old = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = $mode; + return $old; + } + + function outp($text) + { + $this->debug_output = "<br>\n(" . $this->dbtype . "): ".htmlspecialchars($text)."<br>\n"; + if($this->debug_echo) + echo $this->debug_output; + } + + function GetCommentSQL($table,$col) + { + return false; + } + + function SetCommentSQL($table,$col,$cmt) + { + return false; + } + + /** + * @param ttype can either be 'VIEW' or 'TABLE' or false. + * If false, both views and tables are returned. + * "VIEW" returns only views + * "TABLE" returns only tables + * @param showSchema returns the schema/user with the table name, eg. USER.TABLE + * @param mask is the input mask - only supported by oci8 and postgresql + * + * @return array of tables for current database. + */ + + function MetaTables() + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaTables(); + } + + /** + * List columns in a database as an array of ADOFieldObjects. + * See top of file for definition of object. + * + * @param table table name to query + * @param upper uppercase table name (required by some databases) + * @schema is optional database schema to use - not supported by all databases. + * + * @return array of ADOFieldObjects for current table. + */ + + function MetaColumns($tab, $upper=true, $schema=false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema); + } + + /** + * @returns an array with the primary key columns in it. + */ + + function MetaPrimaryKeys($tab,$owner=false,$intkey=false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey); + } + + /** + * List indexes on a table as an array. + * @param table table name to query + * @param primary true to only show primary keys. Not actually used for most databases + * + * @return array of indexes on current table. Each element represents an index, and is itself an associative array. + + Array ( + [name_of_index] => Array + ( + [unique] => true or false + [columns] => Array + ( + [0] => firstname + [1] => lastname + ) + ) + */ + + function MetaIndexes($table, $primary = false, $owner = false) + { + if (!$this->connection->IsConnected()) return array(); + return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner); + } + + function MetaType($t,$len=-1,$fieldobj=false) + { + return $this->connection->MetaType($t,$len,$fieldobj); + } + + function ActualType($meta) + { + return $meta; + } + + function NameQuote($name = NULL,$allowBrackets=false) + { + if (!is_string($name)) { + return FALSE; + } + + $name = trim($name); + + if ( !is_object($this->connection) ) { + return $name; + } + + $quote = $this->connection->nameQuote; + + // if name is of the form `name`, quote it + if ( preg_match('/^`(.+)`$/', $name, $matches) ) { + return $quote . $matches[1] . $quote; + } + + // if name contains special characters, quote it + $regex = ($allowBrackets) ? $this->nameRegexBrackets : $this->nameRegex; + + if ( !preg_match('/^[' . $regex . ']+$/', $name) ) { + return $quote . $name . $quote; + } + + return $name; + } + + function TableName($name) + { + if ( $this->schema ) { + return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name); + } + return $this->NameQuote($name); + } + + // Executes the sql array returned by GetTableSQL and GetIndexSQL + function ExecuteSQLArray($sql, $continueOnError = true) + { + $rez = 2; + $conn = &$this->connection; + $saved = $conn->debug; + foreach($sql as $line) { + if ($this->debug) $conn->debug = true; + $ok = $conn->Execute($line); + $conn->debug = $saved; + if (!$ok) { + if ($this->debug) $this->outp($conn->ErrorMsg()); + if (!$continueOnError) return 0; + $rez = 1; + } + } + return $rez; + } + + function CreateDatabase($dbname,$options=false) + { + $options = $this->_Options($options); + $sql = array(); + + $s = 'CREATE DATABASE ' . $this->NameQuote($dbname); + if (isset($options[$this->upperName])) + $s .= ' '.$options[$this->upperName]; + + $sql[] = $s; + return $sql; + } + + /* + Generates the SQL to create index. Returns an array of sql strings. + */ + + function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false) + { + if (!is_array($flds)) { + $flds = explode(',',$flds); + } + foreach($flds as $key => $fld) { + # some indexes can use partial fields, eg. index first 32 chars of "name" with NAME(32) + $flds[$key] = $this->NameQuote($fld,$allowBrackets=true); + } + return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions)); + } + + function DropIndexSQL ($idxname, $tabname = NULL) + { + return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname))); + } + + function SetSchema($schema) + { + $this->schema = $schema; + } + + function AddColumnSQL($tabname, $flds) + { + $tabname = $this->TableName ($tabname); + $sql = array(); + list($lines,$pkey) = $this->_GenFields($flds); + $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' '; + foreach($lines as $v) { + $sql[] = $alter . $v; + } + return $sql; + } + + /** + * Change the definition of one column + * + * As some DBM's can't do that on there own, you need to supply the complete defintion of the new table, + * to allow, recreating the table and copying the content over to the new table + * @param string $tabname table-name + * @param string $flds column-name and type for the changed column + * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' + * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' + * @return array with SQL strings + */ + + function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + $tabname = $this->TableName ($tabname); + $sql = array(); + list($lines,$pkey) = $this->_GenFields($flds); + $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; + foreach($lines as $v) { + $sql[] = $alter . $v; + } + return $sql; + } + + /** + * Rename one column + * + * Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql) + * @param string $tabname table-name + * @param string $oldcolumn column-name to be renamed + * @param string $newcolumn new column-name + * @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default='' + * @return array with SQL strings + */ + + function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='') + { + $tabname = $this->TableName ($tabname); + if ($flds) { + list($lines,$pkey) = $this->_GenFields($flds); + list(,$first) = each($lines); + list(,$column_def) = split("[\t ]+",$first,2); + } + return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def)); + } + + /** + * Drop one column + * + * Some DBM's can't do that on there own, you need to supply the complete defintion of the new table, + * to allow, recreating the table and copying the content over to the new table + * @param string $tabname table-name + * @param string $flds column-name and type for the changed column + * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' + * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' + * @return array with SQL strings + */ + + function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + $tabname = $this->TableName ($tabname); + if (!is_array($flds)) $flds = explode(',',$flds); + $sql = array(); + $alter = 'ALTER TABLE ' . $tabname . $this->dropCol . ' '; + foreach($flds as $v) { + $sql[] = $alter . $this->NameQuote($v); + } + return $sql; + } + + function DropTableSQL($tabname) + { + return array (sprintf($this->dropTable, $this->TableName($tabname))); + } + + function RenameTableSQL($tabname,$newname) + { + return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname))); + } + + /* + Generate the SQL to create table. Returns an array of sql strings. + */ + + function CreateTableSQL($tabname, $flds, $tableoptions=false) + { + if (!$tableoptions) $tableoptions = array(); + + list($lines,$pkey) = $this->_GenFields($flds, true); + + $taboptions = $this->_Options($tableoptions); + $tabname = $this->TableName ($tabname); + $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions); + $tsql = $this->_Triggers($tabname,$taboptions); + foreach($tsql as $s) $sql[] = $s; + + return $sql; + } + + function _GenFields($flds,$widespacing=false) + { + if (is_string($flds)) { + $padding = ' '; + $txt = $flds.$padding; + $flds = array(); + $flds0 = Lens_ParseArgs($txt,','); + $hasparam = false; + foreach($flds0 as $f0) { + $f1 = array(); + foreach($f0 as $token) { + switch (strtoupper($token)) { + case 'CONSTRAINT': + case 'DEFAULT': + $hasparam = $token; + break; + default: + if ($hasparam) $f1[$hasparam] = $token; + else $f1[] = $token; + $hasparam = false; + break; + } + } + $flds[] = $f1; + + } + } + $this->autoIncrement = false; + $lines = array(); + $pkey = array(); + foreach($flds as $fld) { + $fld = _array_change_key_case($fld); + $fname = false; + $fdefault = false; + $fautoinc = false; + $ftype = false; + $fsize = false; + $fprec = false; + $fprimary = false; + $fnoquote = false; + $fdefts = false; + $fdefdate = false; + $fconstraint = false; + $fnotnull = false; + $funsigned = false; + + //----------------- + // Parse attributes + foreach($fld as $attr => $v) { + if ($attr == 2 && is_numeric($v)) $attr = 'SIZE'; + else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v); + switch($attr) { + case '0': + case 'NAME': + $fname = $v; + break; + case '1': + case 'TYPE': + $ty = $v; $ftype = $this->ActualType(strtoupper($v)); + break; + case 'SIZE': + $dotat = strpos($v,'.'); + if ($dotat === false) $dotat = strpos($v,','); + if ($dotat === false) $fsize = $v; + else { + $fsize = substr($v,0,$dotat); + $fprec = substr($v,$dotat+1); + } + break; + case 'UNSIGNED': + $funsigned = true; + break; + case 'AUTOINCREMENT': + case 'AUTO': + $fautoinc = true; + $fnotnull = true; + break; + case 'KEY': + case 'PRIMARY': + $fprimary = $v; + $fnotnull = true; + break; + case 'DEF': + case 'DEFAULT': + $fdefault = $v; + break; + case 'NOTNULL': + $fnotnull = $v; + break; + case 'NOQUOTE': + $fnoquote = $v; + break; + case 'DEFDATE': + $fdefdate = $v; + break; + case 'DEFTIMESTAMP': + $fdefts = $v; + break; + case 'CONSTRAINT': + $fconstraint = $v; + break; + } + } + + //-------------------- + // VALIDATE FIELD INFO + if (!strlen($fname)) { + if ($this->debug) $this->outp("Undefined NAME"); + return false; + } + + $fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname)); + $fname = $this->NameQuote($fname); + + if (!strlen($ftype)) { + if ($this->debug) $this->outp("Undefined TYPE for field '$fname'"); + return false; + } else { + $ftype = strtoupper($ftype); + } + + $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec); + + if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls + + if ($fprimary) $pkey[] = $fname; + + // some databases do not allow blobs to have defaults + if ($ty == 'X') $fdefault = false; + + //-------------------- + // CONSTRUCT FIELD SQL + if ($fdefts) { + if (substr($this->dbtype,0,5) == 'mysql') { + $ftype = 'TIMESTAMP'; + } else { + $fdefault = $this->connection->sysTimeStamp; + } + } else if ($fdefdate) { + if (substr($this->dbtype,0,5) == 'mysql') { + $ftype = 'TIMESTAMP'; + } else { + $fdefault = $this->connection->sysDate; + } + } else if ($fdefault !== false && !$fnoquote) + if ($ty == 'C' or $ty == 'X' or + ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault))) + if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ') + $fdefault = trim($fdefault); + else if (strtolower($fdefault) != 'null') + $fdefault = $this->connection->qstr($fdefault); + $suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned); + + if ($widespacing) $fname = str_pad($fname,24); + $lines[$fid] = $fname.' '.$ftype.$suffix; + + if ($fautoinc) $this->autoIncrement = true; + } // foreach $flds + return array($lines,$pkey); + } + + /* + GENERATE THE SIZE PART OF THE DATATYPE + $ftype is the actual type + $ty is the type defined originally in the DDL + */ + + function _GetSize($ftype, $ty, $fsize, $fprec) + { + if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) { + $ftype .= "(".$fsize; + if (strlen($fprec)) $ftype .= ",".$fprec; + $ftype .= ')'; + } + return $ftype; + } + + // return string must begin with space + function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint) + { + $suffix = ''; + if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault"; + if ($fnotnull) $suffix .= ' NOT NULL'; + if ($fconstraint) $suffix .= ' '.$fconstraint; + return $suffix; + } + + function _IndexSQL($idxname, $tabname, $flds, $idxoptions) + { + $sql = array(); + + if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) { + $sql[] = sprintf ($this->dropIndex, $idxname); + if ( isset($idxoptions['DROP']) ) + return $sql; + } + + if ( empty ($flds) ) { + return $sql; + } + + $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : ''; + + $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' '; + + if ( isset($idxoptions[$this->upperName]) ) + $s .= $idxoptions[$this->upperName]; + + if ( is_array($flds) ) + $flds = implode(', ',$flds); + $s .= '(' . $flds . ')'; + $sql[] = $s; + + return $sql; + } + + function _DropAutoIncrement($tabname) + { + return false; + } + + function _TableSQL($tabname,$lines,$pkey,$tableoptions) + { + $sql = array(); + + if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) { + $sql[] = sprintf($this->dropTable,$tabname); + if ($this->autoIncrement) { + $sInc = $this->_DropAutoIncrement($tabname); + if ($sInc) $sql[] = $sInc; + } + if ( isset ($tableoptions['DROP']) ) { + return $sql; + } + } + $s = "CREATE TABLE $tabname (\n"; + $s .= implode(",\n", $lines); + if (sizeof($pkey)>0) { + $s .= ",\n PRIMARY KEY ("; + $s .= implode(", ",$pkey).")"; + } + if (isset($tableoptions['CONSTRAINTS'])) + $s .= "\n".$tableoptions['CONSTRAINTS']; + + if (isset($tableoptions[$this->upperName.'_CONSTRAINTS'])) + $s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS']; + + $s .= "\n)"; + if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName]; + $sql[] = $s; + + return $sql; + } + + /* + GENERATE TRIGGERS IF NEEDED + used when table has auto-incrementing field that is emulated using triggers + */ + + function _Triggers($tabname,$taboptions) + { + return array(); + } + + /* + Sanitize options, so that array elements with no keys are promoted to keys + */ + + function _Options($opts) + { + if (!is_array($opts)) return array(); + $newopts = array(); + foreach($opts as $k => $v) { + if (is_numeric($k)) $newopts[strtoupper($v)] = $v; + else $newopts[strtoupper($k)] = $v; + } + return $newopts; + } + + /* + "Florian Buzin [ easywe ]" <florian.buzin#easywe.de> + + This function changes/adds new fields to your table. You don't + have to know if the col is new or not. It will check on its own. + */ + + function ChangeTableSQL($tablename, $flds, $tableoptions = false) + { + global $ADODB_FETCH_MODE; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; + if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); + + // check table exists + $save_handler = $this->raiseErrorFn; + $this->raiseErrorFn = ''; + $cols = $this->MetaColumns($tablename); + $this->raiseErrorFn = $save_handler; + + if (isset($savem)) $this->SetFetchMode($savem); + $ADODB_FETCH_MODE = $save; + + if ( empty($cols)) { + return $this->CreateTableSQL($tablename, $flds, $tableoptions); + } + + if (is_array($flds)) { + // Cycle through the update fields, comparing + // existing fields to fields to update. + // if the Metatype and size is exactly the + // same, ignore - by Mark Newham + $holdflds = array(); + foreach($flds as $k=>$v) { + if ( isset($cols[$k]) && is_object($cols[$k]) ) { + $c = $cols[$k]; + $ml = $c->max_length; + $mt = &$this->MetaType($c->type,$ml); + if ($ml == -1) $ml = ''; + if ($mt == 'X') $ml = $v['SIZE']; + if (($mt != $v['TYPE']) || $ml != $v['SIZE']) { + $holdflds[$k] = $v; + } + } else { + $holdflds[$k] = $v; + } + } + $flds = $holdflds; + } + + // already exists, alter table instead + list($lines,$pkey) = $this->_GenFields($flds); + $alter = 'ALTER TABLE ' . $this->TableName($tablename); + $sql = array(); + + foreach ( $lines as $id => $v ) { + if ( isset($cols[$id]) && is_object($cols[$id]) ) { + $flds = Lens_ParseArgs($v,','); + // We are trying to change the size of the field, if not allowed, simply ignore the request. + if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) continue; + + $sql[] = $alter . $this->alterCol . ' ' . $v; + } else { + $sql[] = $alter . $this->addCol . ' ' . $v; + } + } + return $sql; + } +} + +?> \ No newline at end of file Deleted: trunk/functions/adodb-datadict.inc.php =================================================================== --- trunk/functions/adodb-datadict.inc.php 2007-07-31 00:53:08 UTC (rev 59) +++ trunk/functions/adodb-datadict.inc.php 2007-07-31 00:53:54 UTC (rev 60) @@ -1,838 +0,0 @@ -<?php - -/** - V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. - - Set tabs to 4 for best viewing. - - DOCUMENTATION: - - See adodb/tests/test-datadict.php for docs and examples. - - Modified 3 October, 2005 for use with ADOdb Lite by Mark Dickenson -*/ - -/* - Test script for parser -*/ - -// security - hide paths -if (!defined('ADODB_DIR')) die(); - -if (!function_exists('ctype_alnum')) { - function ctype_alnum($text) { - return preg_match('/^[a-z0-9]*$/i', $text); - } -} - -function _array_change_key_case($an_array) -{ - if (is_array($an_array)) { - $new_array = array(); - foreach($an_array as $key=>$value) - $new_array[strtoupper($key)] = $value; - - return $new_array; - } - - return $an_array; -} - -/** - Parse arguments, treat "text" (text) and 'text' as quotation marks. - To escape, use "" or '' or )) - - Will read in "abc def" sans quotes, as: abc def - Same with 'abc def'. - However if `abc def`, then will read in as `abc def` - - @param endstmtchar Character that indicates end of statement - @param tokenchars Include the following characters in tokens apart from A-Z and 0-9 - @returns 2 dimensional array containing parsed tokens. -*/ -function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-') -{ - $pos = 0; - $intoken = false; - $stmtno = 0; - $endquote = false; - $tokens = array(); - $tokens[$stmtno] = array(); - $max = strlen($args); - $quoted = false; - - while ($pos < $max) { - $ch = substr($args,$pos,1); - switch($ch) { - case ' ': - case "\t": - case "\n": - case "\r": - if (!$quoted) { - if ($intoken) { - $intoken = false; - $tokens[$stmtno][] = implode('',$tokarr); - } - break; - } - $tokarr[] = $ch; - break; - case '`': - if ($intoken) $tokarr[] = $ch; - case '(': - case ')': - case '"': - case "'": - if ($intoken) { - if (empty($endquote)) { - $tokens[$stmtno][] = implode('',$tokarr); - if ($ch == '(') $endquote = ')'; - else $endquote = $ch; - $quoted = true; - $intoken = true; - $tokarr = array(); - } else if ($endquote == $ch) { - $ch2 = substr($args,$pos+1,1); - if ($ch2 == $endquote) { - $pos += 1; - $tokarr[] = $ch2; - } else { - $quoted = false; - $intoken = false; - $tokens[$stmtno][] = implode('',$tokarr); - $endquote = ''; - } - } else - $tokarr[] = $ch; - }else { - if ($ch == '(') $endquote = ')'; - else $endquote = $ch; - $quoted = true; - $intoken = true; - $tokarr = array(); - if ($ch == '`') $tokarr[] = '`'; - } - break; - default: - if (!$intoken) { - if ($ch == $endstmtchar) { - $stmtno += 1; - $tokens[$stmtno] = array(); - break; - } - $intoken = true; - $quoted = false; - $endquote = false; - $tokarr = array(); - } - if ($quoted) $tokarr[] = $ch; - else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch; - else { - if ($ch == $endstmtchar) { - $tokens[$stmtno][] = implode('',$tokarr); - $stmtno += 1; - $tokens[$stmtno] = array(); - $intoken = false; - $tokarr = array(); - break; - } - $tokens[$stmtno][] = implode('',$tokarr); - $tokens[$stmtno][] = $ch; - $intoken = false; - } - } - $pos += 1; - } - if ($intoken) $tokens[$stmtno][] = implode('',$tokarr); - - return $tokens; -} - - -class ADODB_DataDict { - var $connection; - var $debug = false; - var $dropTable = 'DROP TABLE %s'; - var $renameTable = 'RENAME TABLE %s TO %s'; - var $dropIndex = 'DROP INDEX %s'; - var $addCol = ' ADD'; - var $alterCol = ' ALTER COLUMN'; - var $dropCol = ' DROP COLUMN'; - var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s'; // table, old-column, new-column, column-definitions (not used by default) - var $nameRegex = '\w'; - var $nameRegexBrackets = 'a-zA-Z0-9_\(\)'; - var $schema = false; - var $serverInfo = array(); - var $autoIncrement = false; - var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql - var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob - /// in other words, we use a text area for editting. - var $metaTablesSQL; - var $metaColumnsSQL; - var $debug_echo = true; - var $fetchMode; - var $raiseErrorFn; - - function SetFetchMode($mode) - { - GLOBAL $ADODB_FETCH_MODE; - $old = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = $mode; - return $old; - } - - function outp($text) - { - $this->debug_output = "<br>\n(" . $this->dbtype . "): ".htmlspecialchars($text)."<br>\n"; - if($this->debug_echo) - echo $this->debug_output; - } - - function GetCommentSQL($table,$col) - { - return false; - } - - function SetCommentSQL($table,$col,$cmt) - { - return false; - } - - /** - * @param ttype can either be 'VIEW' or 'TABLE' or false. - * If false, both views and tables are returned. - * "VIEW" returns only views - * "TABLE" returns only tables - * @param showSchema returns the schema/user with the table name, eg. USER.TABLE - * @param mask is the input mask - only supported by oci8 and postgresql - * - * @return array of tables for current database. - */ - - function MetaTables() - { - if (!$this->connection->IsConnected()) return array(); - return $this->connection->MetaTables(); - } - - /** - * List columns in a database as an array of ADOFieldObjects. - * See top of file for definition of object. - * - * @param table table name to query - * @param upper uppercase table name (required by some databases) - * @schema is optional database schema to use - not supported by all databases. - * - * @return array of ADOFieldObjects for current table. - */ - - function MetaColumns($tab, $upper=true, $schema=false) - { - if (!$this->connection->IsConnected()) return array(); - return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema); - } - - /** - * @returns an array with the primary key columns in it. - */ - - function MetaPrimaryKeys($tab,$owner=false,$intkey=false) - { - if (!$this->connection->IsConnected()) return array(); - return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey); - } - - /** - * List indexes on a table as an array. - * @param table table name to query - * @param primary true to only show primary keys. Not actually used for most databases - * - * @return array of indexes on current table. Each element represents an index, and is itself an associative array. - - Array ( - [name_of_index] => Array - ( - [unique] => true or false - [columns] => Array - ( - [0] => firstname - [1] => lastname - ) - ) - */ - - function MetaIndexes($table, $primary = false, $owner = false) - { - if (!$this->connection->IsConnected()) return array(); - return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner); - } - - function MetaType($t,$len=-1,$fieldobj=false) - { - return $this->connection->MetaType($t,$len,$fieldobj); - } - - function ActualType($meta) - { - return $meta; - } - - function NameQuote($name = NULL,$allowBrackets=false) - { - if (!is_string($name)) { - return FALSE; - } - - $name = trim($name); - - if ( !is_object($this->connection) ) { - return $name; - } - - $quote = $this->connection->nameQuote; - - // if name is of the form `name`, quote it - if ( preg_match('/^`(.+)`$/', $name, $matches) ) { - return $quote . $matches[1] . $quote; - } - - // if name contains special characters, quote it - $regex = ($allowBrackets) ? $this->nameRegexBrackets : $this->nameRegex; - - if ( !preg_match('/^[' . $regex . ']+$/', $name) ) { - return $quote . $name . $quote; - } - - return $name; - } - - function TableName($name) - { - if ( $this->schema ) { - return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name); - } - return $this->NameQuote($name); - } - - // Executes the sql array returned by GetTableSQL and GetIndexSQL - function ExecuteSQLArray($sql, $continueOnError = true) - { - $rez = 2; - $conn = &$this->connection; - $saved = $conn->debug; - foreach($sql as $line) { - if ($this->debug) $conn->debug = true; - $ok = $conn->Execute($line); - $conn->debug = $saved; - if (!$ok) { - if ($this->debug) $this->outp($conn->ErrorMsg()); - if (!$continueOnError) return 0; - $rez = 1; - } - } - return $rez; - } - - function CreateDatabase($dbname,$options=false) - { - $options = $this->_Options($options); - $sql = array(); - - $s = 'CREATE DATABASE ' . $this->NameQuote($dbname); - if (isset($options[$this->upperName])) - $s .= ' '.$options[$this->upperName]; - - $sql[] = $s; - return $sql; - } - - /* - Generates the SQL to create index. Returns an array of sql strings. - */ - - function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false) - { - if (!is_array($flds)) { - $flds = explode(',',$flds); - } - foreach($flds as $key => $fld) { - # some indexes can use partial fields, eg. index first 32 chars of "name" with NAME(32) - $flds[$key] = $this->NameQuote($fld,$allowBrackets=true); - } - return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions)); - } - - function DropIndexSQL ($idxname, $tabname = NULL) - { - return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname))); - } - - function SetSchema($schema) - { - $this->schema = $schema; - } - - function AddColumnSQL($tabname, $flds) - { - $tabname = $this->TableName ($tabname); - $sql = array(); - list($lines,$pkey) = $this->_GenFields($flds); - $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' '; - foreach($lines as $v) { - $sql[] = $alter . $v; - } - return $sql; - } - - /** - * Change the definition of one column - * - * As some DBM's can't do that on there own, you need to supply the complete defintion of the new table, - * to allow, recreating the table and copying the content over to the new table - * @param string $tabname table-name - * @param string $flds column-name and type for the changed column - * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' - * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' - * @return array with SQL strings - */ - - function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') - { - $tabname = $this->TableName ($tabname); - $sql = array(); - list($lines,$pkey) = $this->_GenFields($flds); - $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; - foreach($lines as $v) { - $sql[] = $alter . $v; - } - return $sql; - } - - /** - * Rename one column - * - * Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql) - * @param string $tabname table-name - * @param string $oldcolumn column-name to be renamed - * @param string $newcolumn new column-name - * @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default='' - * @return array with SQL strings - */ - - function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='') - { - $tabname = $this->TableName ($tabname); - if ($flds) { - list($lines,$pkey) = $this->_GenFields($flds); - list(,$first) = each($lines); - list(,$column_def) = split("[\t ]+",$first,2); - } - return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def)); - } - - /** - * Drop one column - * - * Some DBM's can't do that on there own, you need to supply the complete defintion of the new table, - * to allow, recreating the table and copying the content over to the new table - * @param string $tabname table-name - * @param string $flds column-name and type for the changed column - * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' - * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' - * @return array with SQL strings - */ - - function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') - { - $tabname = $this->TableName ($tabname); - if (!is_array($flds)) $flds = explode(',',$flds); - $sql = array(); - $alter = 'ALTER TABLE ' . $tabname . $this->dropCol . ' '; - foreach($flds as $v) { - $sql[] = $alter . $this->NameQuote($v); - } - return $sql; - } - - function DropTableSQL($tabname) - { - return array (sprintf($this->dropTable, $this->TableName($tabname))); - } - - function RenameTableSQL($tabname,$newname) - { - return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname))); - } - - /* - Generate the SQL to create table. Returns an array of sql strings. - */ - - function CreateTableSQL($tabname, $flds, $tableoptions=false) - { - if (!$tableoptions) $tableoptions = array(); - - list($lines,$pkey) = $this->_GenFields($flds, true); - - $taboptions = $this->_Options($tableoptions); - $tabname = $this->TableName ($tabname); - $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions); - $tsql = $this->_Triggers($tabname,$taboptions); - foreach($tsql as $s) $sql[] = $s; - - return $sql; - } - - function _GenFields($flds,$widespacing=false) - { - if (is_string($flds)) { - $padding = ' '; - $txt = $flds.$padding; - $flds = array(); - $flds0 = Lens_ParseArgs($txt,','); - $hasparam = false; - foreach($flds0 as $f0) { - $f1 = array(); - foreach($f0 as $token) { - switch (strtoupper($token)) { - case 'CONSTRAINT': - case 'DEFAULT': - $hasparam = $token; - break; - default: - if ($hasparam) $f1[$hasparam] = $token; - else $f1[] = $token; - $hasparam = false; - break; - } - } - $flds[] = $f1; - - } - } - $this->autoIncrement = false; - $lines = array(); - $pkey = array(); - foreach($flds as $fld) { - $fld = _array_change_key_case($fld); - $fname = false; - $fdefault = false; - $fautoinc = false; - $ftype = false; - $fsize = false; - $fprec = false; - $fprimary = false; - $fnoquote = false; - $fdefts = false; - $fdefdate = false; - $fconstraint = false; - $fnotnull = false; - $funsigned = false; - - //----------------- - // Parse attributes - foreach($fld as $attr => $v) { - if ($attr == 2 && is_numeric($v)) $attr = 'SIZE'; - else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v); - switch($attr) { - case '0': - case 'NAME': - $fname = $v; - break; - case '1': - case 'TYPE': - $ty = $v; $ftype = $this->ActualType(strtoupper($v)); - break; - case 'SIZE': - $dotat = strpos($v,'.'); - if ($dotat === false) $dotat = strpos($v,','); - if ($dotat === false) $fsize = $v; - else { - $fsize = substr($v,0,$dotat); - $fprec = substr($v,$dotat+1); - } - break; - case 'UNSIGNED': - $funsigned = true; - break; - case 'AUTOINCREMENT': - case 'AUTO': - $fautoinc = true; - $fnotnull = true; - break; - case 'KEY': - case 'PRIMARY': - $fprimary = $v; - $fnotnull = true; - break; - case 'DEF': - case 'DEFAULT': - $fdefault = $v; - break; - case 'NOTNULL': - $fnotnull = $v; - break; - case 'NOQUOTE': - $fnoquote = $v; - break; - case 'DEFDATE': - $fdefdate = $v; - break; - case 'DEFTIMESTAMP': - $fdefts = $v; - break; - case 'CONSTRAINT': - $fconstraint = $v; - break; - } - } - - //-------------------- - // VALIDATE FIELD INFO - if (!strlen($fname)) { - if ($this->debug) $this->outp("Undefined NAME"); - return false; - } - - $fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname)); - $fname = $this->NameQuote($fname); - - if (!strlen($ftype)) { - if ($this->debug) $this->outp("Undefined TYPE for field '$fname'"); - return false; - } else { - $ftype = strtoupper($ftype); - } - - $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec); - - if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls - - if ($fprimary) $pkey[] = $fname; - - // some databases do not allow blobs to have defaults - if ($ty == 'X') $fdefault = false; - - //-------------------- - // CONSTRUCT FIELD SQL - if ($fdefts) { - if (substr($this->dbtype,0,5) == 'mysql') { - $ftype = 'TIMESTAMP'; - } else { - $fdefault = $this->connection->sysTimeStamp; - } - } else if ($fdefdate) { - if (substr($this->dbtype,0,5) == 'mysql') { - $ftype = 'TIMESTAMP'; - } else { - $fdefault = $this->connection->sysDate; - } - } else if ($fdefault !== false && !$fnoquote) - if ($ty == 'C' or $ty == 'X' or - ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault))) - if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ') - $fdefault = trim($fdefault); - else if (strtolower($fdefault) != 'null') - $fdefault = $this->connection->qstr($fdefault); - $suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned); - - if ($widespacing) $fname = str_pad($fname,24); - $lines[$fid] = $fname.' '.$ftype.$suffix; - - if ($fautoinc) $this->autoIncrement = true; - } // foreach $flds - return array($lines,$pkey); - } - - /* - GENERATE THE SIZE PART OF THE DATATYPE - $ftype is the actual type - $ty is the type defined originally in the DDL - */ - - function _GetSize($ftype, $ty, $fsize, $fprec) - { - if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) { - $ftype .= "(".$fsize; - if (strlen($fprec)) $ftype .= ",".$fprec; - $ftype .= ')'; - } - return $ftype; - } - - // return string must begin with space - function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint) - { - $suffix = ''; - if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault"; - if ($fnotnull) $suffix .= ' NOT NULL'; - if ($fconstraint) $suffix .= ' '.$fconstraint; - return $suffix; - } - - function _IndexSQL($idxname, $tabname, $flds, $idxoptions) - { - $sql = array(); - - if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) { - $sql[] = sprintf ($this->dropIndex, $idxname); - if ( isset($idxoptions['DROP']) ) - return $sql; - } - - if ( empty ($flds) ) { - return $sql; - } - - $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : ''; - - $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' '; - - if ( isset($idxoptions[$this->upperName]) ) - $s .= $idxoptions[$this->upperName]; - - if ( is_array($flds) ) - $flds = implode(', ',$flds); - $s .= '(' . $flds . ')'; - $sql[] = $s; - - return $sql; - } - - function _DropAutoIncrement($tabname) - { - return false; - } - - function _TableSQL($tabname,$lines,$pkey,$tableoptions) - { - $sql = array(); - - if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) { - $sql[] = sprintf($this->dropTable,$tabname); - if ($this->autoIncrement) { - $sInc = $this->_DropAutoIncrement($tabname); - if ($sInc) $sql[] = $sInc; - } - if ( isset ($tableoptions['DROP']) ) { - return $sql; - } - } - $s = "CREATE TABLE $tabname (\n"; - $s .= implode(",\n", $lines); - if (sizeof($pkey)>0) { - $s .= ",\n PRIMARY KEY ("; - $s .= implode(", ",$pkey).")"; - } - if (isset($tableoptions['CONSTRAINTS'])) - $s .= "\n".$tableoptions['CONSTRAINTS']; - - if (isset($tableoptions[$this->upperName.'_CONSTRAINTS'])) - $s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS']; - - $s .= "\n)"; - if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName]; - $sql[] = $s; - - return $sql; - } - - /* - GENERATE TRIGGERS IF NEEDED - used when table has auto-incrementing field that is emulated using triggers - */ - - function _Triggers($tabname,$taboptions) - { - return array(); - } - - /* - Sanitize options, so that array elements with no keys are promoted to keys - */ - - function _Options($opts) - { - if (!is_array($opts)) return array(); - $newopts = array(); - foreach($opts as $k => $v) { - if (is_numeric($k)) $newopts[strtoupper($v)] = $v; - else $newopts[strtoupper($k)] = $v; - } - return $newopts; - } - - /* - "Florian Buzin [ easywe ]" <florian.buzin#easywe.de> - - This function changes/adds new fields to your table. You don't - have to know if the col is new or not. It will check on its own. - */ - - function ChangeTableSQL($tablename, $flds, $tableoptions = false) - { - global $ADODB_FETCH_MODE; - $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; - if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); - - // check table exists - $save_handler = $this->raiseErrorFn; - $this->raiseErrorFn = ''; - $cols = $this->MetaColumns($tablename); - $this->raiseErrorFn = $save_handler; - - if (isset($savem)) $this->SetFetchMode($savem); - $ADODB_FETCH_MODE = $save; - - if ( empty($cols)) { - return $this->CreateTableSQL($tablename, $flds, $tableoptions); - } - - if (is_array($flds)) { - // Cycle through the update fields, comparing - // existing fields to fields to update. - // if the Metatype and size is exactly the - // same, ignore - by Mark Newham - $holdflds = array(); - foreach($flds as $k=>$v) { - if ( isset($cols[$k]) && is_object($cols[$k]) ) { - $c = $cols[$k]; - $ml = $c->max_length; - $mt = &$this->MetaType($c->type,$ml); - if ($ml == -1) $ml = ''; - if ($mt == 'X') $ml = $v['SIZE']; - if (($mt != $v['TYPE']) || $ml != $v['SIZE']) { - $holdflds[$k] = $v; - } - } else { - $holdflds[$k] = $v; - } - } - $flds = $holdflds; - } - - // already exists, alter table instead - list($lines,$pkey) = $this->_GenFields($flds); - $alter = 'ALTER TABLE ' . $this->TableName($tablename); - $sql = array(); - - foreach ( $lines as $id => $v ) { - if ( isset($cols[$id]) && is_object($cols[$id]) ) { - $flds = Lens_ParseArgs($v,','); - // We are trying to change the size of the field, if not allowed, simply ignore the request. - if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) continue; - - $sql[] = $alter . $this->alterCol . ' ' . $v; - } else { - $sql[] = $alter . $this->addCol . ' ' . $v; - } - } - return $sql; - } -} - -?> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:54:42
|
Revision: 62 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=62&view=rev Author: caleb870 Date: 2007-07-30 17:54:43 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-errorhandler.inc.php Removed Paths: ------------- trunk/functions/adodb-errorhandler.inc.php Copied: trunk/functions/adodb/adodb-errorhandler.inc.php (from rev 61, trunk/functions/adodb-errorhandler.inc.php) =================================================================== --- trunk/functions/adodb/adodb-errorhandler.inc.php (rev 0) +++ trunk/functions/adodb/adodb-errorhandler.inc.php 2007-07-31 00:54:43 UTC (rev 62) @@ -0,0 +1,79 @@ +<?php +/** + * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + * + * Set tabs to 4 for best viewing. + * + * Latest version is available at http://php.weblogs.com + * +*/ + +// added Claudio Bustos clbustos#entelchile.net +if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR); + +if (!defined('ADODB_ERROR_HANDLER')) define('ADODB_ERROR_HANDLER','ADODB_Error_Handler'); + +/** +* Default Error Handler. This will be called with the following params +* +* @param $dbms the RDBMS you are connecting to +* @param $fn the name of the calling function (in uppercase) +* @param $errno the native error number from the database +* @param $errmsg the native error msg from the database +* @param $p1 $fn specific parameter - see below +* @param $p2 $fn specific parameter - see below +* @param $thisConn $current connection object - can be false if no connection object created +*/ + +function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) +{ + if (error_reporting() == 0) + return; // obey @ protocol + + switch($fn) { + case 'EXECUTE': + $sql = $p1; + $inputparams = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")\n"; + break; + + case 'PCONNECT': + case 'CONNECT': + $host = $p1; + $database = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn($host, '****', '****', $database)\n"; + break; + + default: + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n"; + break; + } + /* + * Log connection error somewhere + * 0 message is sent to PHP's system logger, using the Operating System's system + * logging mechanism or a file, depending on what the error_log configuration + * directive is set to. + * 1 message is sent by email to the address in the destination parameter. + * This is the only message type where the fourth parameter, extra_headers is used. + * This message type uses the same internal function as mail() does. + * 2 message is sent through the PHP debugging connection. + * This option is only available if remote debugging has been enabled. + * In this case, the destination parameter specifies the host name or IP address + * and optionally, port number, of the socket receiving the debug information. + * 3 message is appended to the file destination + */ + if (defined('ADODB_ERROR_LOG_TYPE')) { + $t = date('Y-m-d H:i:s'); + if (defined('ADODB_ERROR_LOG_DEST')) + error_log("($t) $s", ADODB_ERROR_LOG_TYPE, ADODB_ERROR_LOG_DEST); + else + error_log("($t) $s", ADODB_ERROR_LOG_TYPE); + } + + //print "<p>$s</p>"; + trigger_error($s, ADODB_ERROR_HANDLER_TYPE); +} +?> Deleted: trunk/functions/adodb-errorhandler.inc.php =================================================================== --- trunk/functions/adodb-errorhandler.inc.php 2007-07-31 00:54:05 UTC (rev 61) +++ trunk/functions/adodb-errorhandler.inc.php 2007-07-31 00:54:43 UTC (rev 62) @@ -1,79 +0,0 @@ -<?php -/** - * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. - * - * Set tabs to 4 for best viewing. - * - * Latest version is available at http://php.weblogs.com - * -*/ - -// added Claudio Bustos clbustos#entelchile.net -if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR); - -if (!defined('ADODB_ERROR_HANDLER')) define('ADODB_ERROR_HANDLER','ADODB_Error_Handler'); - -/** -* Default Error Handler. This will be called with the following params -* -* @param $dbms the RDBMS you are connecting to -* @param $fn the name of the calling function (in uppercase) -* @param $errno the native error number from the database -* @param $errmsg the native error msg from the database -* @param $p1 $fn specific parameter - see below -* @param $p2 $fn specific parameter - see below -* @param $thisConn $current connection object - can be false if no connection object created -*/ - -function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) -{ - if (error_reporting() == 0) - return; // obey @ protocol - - switch($fn) { - case 'EXECUTE': - $sql = $p1; - $inputparams = $p2; - $s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")\n"; - break; - - case 'PCONNECT': - case 'CONNECT': - $host = $p1; - $database = $p2; - $s = "$dbms error: [$errno: $errmsg] in $fn($host, '****', '****', $database)\n"; - break; - - default: - $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n"; - break; - } - /* - * Log connection error somewhere - * 0 message is sent to PHP's system logger, using the Operating System's system - * logging mechanism or a file, depending on what the error_log configuration - * directive is set to. - * 1 message is sent by email to the address in the destination parameter. - * This is the only message type where the fourth parameter, extra_headers is used. - * This message type uses the same internal function as mail() does. - * 2 message is sent through the PHP debugging connection. - * This option is only available if remote debugging has been enabled. - * In this case, the destination parameter specifies the host name or IP address - * and optionally, port number, of the socket receiving the debug information. - * 3 message is appended to the file destination - */ - if (defined('ADODB_ERROR_LOG_TYPE')) { - $t = date('Y-m-d H:i:s'); - if (defined('ADODB_ERROR_LOG_DEST')) - error_log("($t) $s", ADODB_ERROR_LOG_TYPE, ADODB_ERROR_LOG_DEST); - else - error_log("($t) $s", ADODB_ERROR_LOG_TYPE); - } - - //print "<p>$s</p>"; - trigger_error($s, ADODB_ERROR_HANDLER_TYPE); -} -?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:54:52
|
Revision: 63 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=63&view=rev Author: caleb870 Date: 2007-07-30 17:54:55 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-errorpear.inc.php Removed Paths: ------------- trunk/functions/adodb-errorpear.inc.php Copied: trunk/functions/adodb/adodb-errorpear.inc.php (from rev 62, trunk/functions/adodb-errorpear.inc.php) =================================================================== --- trunk/functions/adodb/adodb-errorpear.inc.php (rev 0) +++ trunk/functions/adodb/adodb-errorpear.inc.php 2007-07-31 00:54:55 UTC (rev 63) @@ -0,0 +1,87 @@ +<?php +/** + * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + * + * Set tabs to 4 for best viewing. + * + * Latest version is available at http://php.weblogs.com + * +*/ +include_once('PEAR.php'); + +if (!defined('ADODB_ERROR_HANDLER')) + define('ADODB_ERROR_HANDLER','ADODB_Error_PEAR'); + +/* +* Enabled the following if you want to terminate scripts when an error occurs +*/ +//PEAR::setErrorHandling (PEAR_ERROR_DIE); + +/* +* Name of the PEAR_Error derived class to call. +*/ +if (!defined('ADODB_PEAR_ERROR_CLASS')) + define('ADODB_PEAR_ERROR_CLASS','PEAR_Error'); + +/* +* Store the last PEAR_Error object here +*/ +global $ADODB_Last_PEAR_Error; + +$ADODB_Last_PEAR_Error = false; + + /** +* Error Handler with PEAR support. This will be called with the following params +* +* @param $dbms the RDBMS you are connecting to +* @param $fn the name of the calling function (in uppercase) +* @param $errno the native error number from the database +* @param $errmsg the native error msg from the database +* @param $p1 $fn specific parameter - see below +* @param $P2 $fn specific parameter - see below + */ +function ADODB_Error_PEAR($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false) +{ + global $ADODB_Last_PEAR_Error; + + if (error_reporting() == 0) + return; // obey @ protocol + + switch($fn) { + case 'EXECUTE': + $sql = $p1; + $inputparams = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")"; + break; + + case 'PCONNECT': + case 'CONNECT': + $host = $p1; + $database = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn('$host', ?, ?, '$database')"; + break; + + default: + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)"; + break; + } + + $class = ADODB_PEAR_ERROR_CLASS; + $ADODB_Last_PEAR_Error = new $class($s, $errno, $GLOBALS['_PEAR_default_error_mode'], $GLOBALS['_PEAR_default_error_options'], $errmsg); + //print "<p>!$s</p>"; +} + +/** +* Returns last PEAR_Error object. This error might be for an error that +* occured several sql statements ago. +*/ +function &ADODB_PEAR_Error() +{ + global $ADODB_Last_PEAR_Error; + + return $ADODB_Last_PEAR_Error; +} +?> \ No newline at end of file Deleted: trunk/functions/adodb-errorpear.inc.php =================================================================== --- trunk/functions/adodb-errorpear.inc.php 2007-07-31 00:54:43 UTC (rev 62) +++ trunk/functions/adodb-errorpear.inc.php 2007-07-31 00:54:55 UTC (rev 63) @@ -1,87 +0,0 @@ -<?php -/** - * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. - * - * Set tabs to 4 for best viewing. - * - * Latest version is available at http://php.weblogs.com - * -*/ -include_once('PEAR.php'); - -if (!defined('ADODB_ERROR_HANDLER')) - define('ADODB_ERROR_HANDLER','ADODB_Error_PEAR'); - -/* -* Enabled the following if you want to terminate scripts when an error occurs -*/ -//PEAR::setErrorHandling (PEAR_ERROR_DIE); - -/* -* Name of the PEAR_Error derived class to call. -*/ -if (!defined('ADODB_PEAR_ERROR_CLASS')) - define('ADODB_PEAR_ERROR_CLASS','PEAR_Error'); - -/* -* Store the last PEAR_Error object here -*/ -global $ADODB_Last_PEAR_Error; - -$ADODB_Last_PEAR_Error = false; - - /** -* Error Handler with PEAR support. This will be called with the following params -* -* @param $dbms the RDBMS you are connecting to -* @param $fn the name of the calling function (in uppercase) -* @param $errno the native error number from the database -* @param $errmsg the native error msg from the database -* @param $p1 $fn specific parameter - see below -* @param $P2 $fn specific parameter - see below - */ -function ADODB_Error_PEAR($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false) -{ - global $ADODB_Last_PEAR_Error; - - if (error_reporting() == 0) - return; // obey @ protocol - - switch($fn) { - case 'EXECUTE': - $sql = $p1; - $inputparams = $p2; - $s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")"; - break; - - case 'PCONNECT': - case 'CONNECT': - $host = $p1; - $database = $p2; - $s = "$dbms error: [$errno: $errmsg] in $fn('$host', ?, ?, '$database')"; - break; - - default: - $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)"; - break; - } - - $class = ADODB_PEAR_ERROR_CLASS; - $ADODB_Last_PEAR_Error = new $class($s, $errno, $GLOBALS['_PEAR_default_error_mode'], $GLOBALS['_PEAR_default_error_options'], $errmsg); - //print "<p>!$s</p>"; -} - -/** -* Returns last PEAR_Error object. This error might be for an error that -* occured several sql statements ago. -*/ -function &ADODB_PEAR_Error() -{ - global $ADODB_Last_PEAR_Error; - - return $ADODB_Last_PEAR_Error; -} -?> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:55:12
|
Revision: 64 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=64&view=rev Author: caleb870 Date: 2007-07-30 17:55:15 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-exceptions.inc.php Removed Paths: ------------- trunk/functions/adodb-exceptions.inc.php Copied: trunk/functions/adodb/adodb-exceptions.inc.php (from rev 63, trunk/functions/adodb-exceptions.inc.php) =================================================================== --- trunk/functions/adodb/adodb-exceptions.inc.php (rev 0) +++ trunk/functions/adodb/adodb-exceptions.inc.php 2007-07-31 00:55:15 UTC (rev 64) @@ -0,0 +1,86 @@ +<?php + +/** + * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + * + * Set tabs to 4 for best viewing. + * + * Latest version is available at http://php.weblogs.com + * + * Exception-handling code using PHP5 exceptions (try-catch-throw). + */ + +if (!defined('ADODB_ERROR_HANDLER_TYPE')) + define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR); + +define('ADODB_ERROR_HANDLER','adodb_throw'); + +class ADODB_Exception extends Exception { + var $dbms; + var $fn; + var $sql = ''; + var $params = ''; + var $host = ''; + var $database = ''; + + function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) + { + switch($fn) { + case 'EXECUTE': + $this->sql = $p1; + $this->params = $p2; + $s = "$dbms error: [$errno: $errmsg] in $fn(\"$p1\")\n"; + break; + + case 'PCONNECT': + case 'CONNECT': + $user = $thisConnection->username; + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)\n"; + break; + + default: + $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n"; + break; + } + + $this->dbms = $dbms; + $this->host = $thisConnection->host; + $this->database = $thisConnection->database; + $this->fn = $fn; + $this->msg = $errmsg; + + if (!is_numeric($errno)) + $errno = -1; + + parent::__construct($s,$errno); + } +} + +/** +* Default Error Handler. This will be called with the following params +* +* @param $dbms the RDBMS you are connecting to +* @param $fn the name of the calling function (in uppercase) +* @param $errno the native error number from the database +* @param $errmsg the native error msg from the database +* @param $p1 $fn specific parameter - see below +* @param $P2 $fn specific parameter - see below +*/ + +function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) +{ + global $ADODB_EXCEPTION; + + if (error_reporting() == 0) + return; // obey @ protocol + + if (is_string($ADODB_EXCEPTION)) + $errfn = $ADODB_EXCEPTION; + else $errfn = 'ADODB_EXCEPTION'; + + throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection); +} +?> \ No newline at end of file Deleted: trunk/functions/adodb-exceptions.inc.php =================================================================== --- trunk/functions/adodb-exceptions.inc.php 2007-07-31 00:54:55 UTC (rev 63) +++ trunk/functions/adodb-exceptions.inc.php 2007-07-31 00:55:15 UTC (rev 64) @@ -1,86 +0,0 @@ -<?php - -/** - * @version V4.66 28 Sept 2005 (c) 2000-2005 John Lim (jl...@na...). 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. - * - * Set tabs to 4 for best viewing. - * - * Latest version is available at http://php.weblogs.com - * - * Exception-handling code using PHP5 exceptions (try-catch-throw). - */ - -if (!defined('ADODB_ERROR_HANDLER_TYPE')) - define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR); - -define('ADODB_ERROR_HANDLER','adodb_throw'); - -class ADODB_Exception extends Exception { - var $dbms; - var $fn; - var $sql = ''; - var $params = ''; - var $host = ''; - var $database = ''; - - function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) - { - switch($fn) { - case 'EXECUTE': - $this->sql = $p1; - $this->params = $p2; - $s = "$dbms error: [$errno: $errmsg] in $fn(\"$p1\")\n"; - break; - - case 'PCONNECT': - case 'CONNECT': - $user = $thisConnection->username; - $s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)\n"; - break; - - default: - $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n"; - break; - } - - $this->dbms = $dbms; - $this->host = $thisConnection->host; - $this->database = $thisConnection->database; - $this->fn = $fn; - $this->msg = $errmsg; - - if (!is_numeric($errno)) - $errno = -1; - - parent::__construct($s,$errno); - } -} - -/** -* Default Error Handler. This will be called with the following params -* -* @param $dbms the RDBMS you are connecting to -* @param $fn the name of the calling function (in uppercase) -* @param $errno the native error number from the database -* @param $errmsg the native error msg from the database -* @param $p1 $fn specific parameter - see below -* @param $P2 $fn specific parameter - see below -*/ - -function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection) -{ - global $ADODB_EXCEPTION; - - if (error_reporting() == 0) - return; // obey @ protocol - - if (is_string($ADODB_EXCEPTION)) - $errfn = $ADODB_EXCEPTION; - else $errfn = 'ADODB_EXCEPTION'; - - throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection); -} -?> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:55:42
|
Revision: 65 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=65&view=rev Author: caleb870 Date: 2007-07-30 17:55:44 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-perf.inc.php Removed Paths: ------------- trunk/functions/adodb-perf.inc.php Copied: trunk/functions/adodb/adodb-perf.inc.php (from rev 64, trunk/functions/adodb-perf.inc.php) =================================================================== --- trunk/functions/adodb/adodb-perf.inc.php (rev 0) +++ trunk/functions/adodb/adodb-perf.inc.php 2007-07-31 00:55:44 UTC (rev 65) @@ -0,0 +1,241 @@ +<?php +/* +V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. See License.txt. + Set tabs to 4 for best viewing. + + Latest version is available at http://adodb.sourceforge.net + + Library for basic performance monitoring and tuning. + + My apologies if you see code mixed with presentation. The presentation suits + my needs. If you want to separate code from presentation, be my guest. Patches + are welcome. + + Modified 17 March 2006 for use with ADOdb Lite by Pádraic Brady + Such modifications (c) 2006 Pádraic Brady (mau...@ho...) + +*/ + +if (!defined(ADODB_DIR)) include_once(dirname(__FILE__).'/adodb.inc.php'); +include_once(ADODB_DIR . '/tohtml.inc.php'); + +define( 'ADODB_OPT_HIGH', 2); +define( 'ADODB_OPT_LOW', 1); + +// returns in K the memory of current process, or 0 if not known +function adodb_getmem() +{ + if (function_exists('memory_get_usage')) + return (integer) ((memory_get_usage()+512)/1024); + + $pid = getmypid(); + + if ( strncmp(strtoupper(PHP_OS),'WIN',3)==0) { + $output = array(); + + exec('tasklist /FI "PID eq ' . $pid. '" /FO LIST', $output); + return substr($output[5], strpos($output[5], ':') + 1); + } + + /* Hopefully UNIX */ + exec("ps --pid $pid --no-headers -o%mem,size", $output); + if (sizeof($output) == 0) return 0; + + $memarr = explode(' ',$output[0]); + if (sizeof($memarr)>=2) return (integer) $memarr[1]; + + return 0; +} + +// avoids localization problems where , is used instead of . +function adodb_round($n,$prec) +{ + return number_format($n, $prec, '.', ''); +} + +/* return microtime value as a float */ +function adodb_microtime() +{ + $t = microtime(); + $t = explode(' ',$t); + return (float)$t[1]+ (float)$t[0]; +} + +/* sql code timing */ +function& adodb_log_sql(&$conn,$sql,$inputarr) +{ + + $perf_table = adodb_perf::table(); + $conn->_logsql = false; // replaces setting ::fnExecute=false in ADOdb + $t0 = microtime(); + $rs =& $conn->Execute($sql,$inputarr); + $t1 = microtime(); + $conn->_logsql = true; // reverse setting ::_logsql=false + + if (!empty($conn->_logsql)) { + $conn->_logsql = false; // disable logsql error simulation + $dbT = $conn->dbtype; + + $a0 = split(' ',$t0); + $a0 = (float)$a0[1]+(float)$a0[0]; + + $a1 = split(' ',$t1); + $a1 = (float)$a1[1]+(float)$a1[0]; + + $time = $a1 - $a0; + + if (!$rs) { + $errM = $conn->ErrorMsg(); + $errN = $conn->ErrorNo(); + $tracer = substr('ERROR: '.htmlspecialchars($errM),0,250); + } else { + $tracer = ''; + $errM = ''; + $errN = 0; + } + if(isset($_SERVER['HTTP_HOST'])) + { + $tracer .= '<br>'.$_SERVER['HTTP_HOST']; + if(isset($_SERVER['PHP_SELF'])) + { + $tracer .= $_SERVER['PHP_SELF']; + } + } + elseif(isset($_SERVER['PHP_SELF'])) + { + $tracer .= '<br>'.$_SERVER['PHP_SELF']; + } + + $tracer = (string) substr($tracer,0,500); + + if(is_array($inputarr)) + { + if(is_array(reset($inputarr))) + { + $params = 'Array sizeof=' . sizeof($inputarr); + } + else + { + // Quote string parameters so we can see them in the + // performance stats. This helps spot disabled indexes. + $xar_params = $inputarr; + foreach($xar_params as $xar_param_key => $xar_param) + { + if (gettype($xar_param) == 'string') + $xar_params[$xar_param_key] = '"' . $xar_param . '"'; + } + $params = implode(', ', $xar_params); + if (strlen($params) >= 3000) $params = substr($params, 0, 3000); + } + } + else + { + $params = ''; + } + + if (is_array($sql)) $sql = $sql[0]; + $arr = array('b'=>strlen($sql).'.'.crc32($sql), + 'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>adodb_round($time,6)); + + $saved = $conn->debug; + $conn->debug = 0; + + $d = $conn->sysTimeStamp; + if (empty($d)) + { + $d = date("'Y-m-d H:i:s'"); + } + + /* + // OCI/Informix/ODBC_MSSQL - not sure if/how available in adodb-lite so I've commented out the section for now - (Pádraic) + */ + + /*if ($dbT == 'oci8' && $dbT != 'oci8po') + { + $isql = "insert into $perf_table values($d,:b,:c,:d,:e,:f)"; + } + elseif($dbT == 'odbc_mssql' || $dbT == 'informix') + { + $timer = $arr['f']; + if ($dbT == 'informix') $sql2 = substr($sql2,0,230); + + $sql1 = $conn->qstr($arr['b']); + $sql2 = $conn->qstr($arr['c']); + $params = $conn->qstr($arr['d']); + $tracer = $conn->qstr($arr['e']); + + $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values($d,$sql1,$sql2,$params,$tracer,$timer)"; + if ($dbT == 'informix') $isql = str_replace(chr(10),' ',$isql); + $arr = false; + } else {*/ + $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $d,?,?,?,?,?)"; + //} + + $ok = $conn->Execute($isql,$arr); + $conn->debug = $saved; + + if ($ok) { + $conn->_logsql = true; + } else { + $err2 = $conn->ErrorMsg(); + $conn->_logsql = true; // enable logsql error simulation + $perf =& NewPerfMonitor($conn); + if ($perf) { + if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr); + } else { + $ok = $conn->Execute("create table $perf_table ( + created varchar(50), + sql0 varchar(250), + sql1 varchar(4000), + params varchar(3000), + tracer varchar(500), + timer decimal(16,6))"); + } + /*if (!$ok) { + ADOConnection::outp( "<p><b>LOGSQL Insert Failed</b>: $isql<br>$err2</p>"); + $conn->_logsql = false; + }*/ + } + $conn->_errorMsg = $errM; + $conn->_errorCode = $errN; + } + return $rs; +} + + +/* +The settings data structure is an associative array that database parameter per element. + +Each database parameter element in the array is itself an array consisting of: + +0: category code, used to group related db parameters +1: either + a. sql string to retrieve value, eg. "select value from v\$parameter where name='db_block_size'", + b. array holding sql string and field to look for, e.g. array('show variables','table_cache'), + c. a string prefixed by =, then a PHP method of the class is invoked, + e.g. to invoke $this->GetIndexValue(), set this array element to '=GetIndexValue', +2: description of the database parameter +*/ + +class adodb_perf { + + function adodb_perf() {} + + /** + * Alias for perfmon_parent_ADOConnection::table() + * + * @access public + * @param string $newtable The name for the table to use; optional. + * @return string + */ + function table($newtable = false) { + $rt = perfmon_parent_ADOConnection::table($newtable); + return $rt; + } + + } + +?> Deleted: trunk/functions/adodb-perf.inc.php =================================================================== --- trunk/functions/adodb-perf.inc.php 2007-07-31 00:55:15 UTC (rev 64) +++ trunk/functions/adodb-perf.inc.php 2007-07-31 00:55:44 UTC (rev 65) @@ -1,241 +0,0 @@ -<?php -/* -V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. See License.txt. - Set tabs to 4 for best viewing. - - Latest version is available at http://adodb.sourceforge.net - - Library for basic performance monitoring and tuning. - - My apologies if you see code mixed with presentation. The presentation suits - my needs. If you want to separate code from presentation, be my guest. Patches - are welcome. - - Modified 17 March 2006 for use with ADOdb Lite by Pádraic Brady - Such modifications (c) 2006 Pádraic Brady (mau...@ho...) - -*/ - -if (!defined(ADODB_DIR)) include_once(dirname(__FILE__).'/adodb.inc.php'); -include_once(ADODB_DIR . '/tohtml.inc.php'); - -define( 'ADODB_OPT_HIGH', 2); -define( 'ADODB_OPT_LOW', 1); - -// returns in K the memory of current process, or 0 if not known -function adodb_getmem() -{ - if (function_exists('memory_get_usage')) - return (integer) ((memory_get_usage()+512)/1024); - - $pid = getmypid(); - - if ( strncmp(strtoupper(PHP_OS),'WIN',3)==0) { - $output = array(); - - exec('tasklist /FI "PID eq ' . $pid. '" /FO LIST', $output); - return substr($output[5], strpos($output[5], ':') + 1); - } - - /* Hopefully UNIX */ - exec("ps --pid $pid --no-headers -o%mem,size", $output); - if (sizeof($output) == 0) return 0; - - $memarr = explode(' ',$output[0]); - if (sizeof($memarr)>=2) return (integer) $memarr[1]; - - return 0; -} - -// avoids localization problems where , is used instead of . -function adodb_round($n,$prec) -{ - return number_format($n, $prec, '.', ''); -} - -/* return microtime value as a float */ -function adodb_microtime() -{ - $t = microtime(); - $t = explode(' ',$t); - return (float)$t[1]+ (float)$t[0]; -} - -/* sql code timing */ -function& adodb_log_sql(&$conn,$sql,$inputarr) -{ - - $perf_table = adodb_perf::table(); - $conn->_logsql = false; // replaces setting ::fnExecute=false in ADOdb - $t0 = microtime(); - $rs =& $conn->Execute($sql,$inputarr); - $t1 = microtime(); - $conn->_logsql = true; // reverse setting ::_logsql=false - - if (!empty($conn->_logsql)) { - $conn->_logsql = false; // disable logsql error simulation - $dbT = $conn->dbtype; - - $a0 = split(' ',$t0); - $a0 = (float)$a0[1]+(float)$a0[0]; - - $a1 = split(' ',$t1); - $a1 = (float)$a1[1]+(float)$a1[0]; - - $time = $a1 - $a0; - - if (!$rs) { - $errM = $conn->ErrorMsg(); - $errN = $conn->ErrorNo(); - $tracer = substr('ERROR: '.htmlspecialchars($errM),0,250); - } else { - $tracer = ''; - $errM = ''; - $errN = 0; - } - if(isset($_SERVER['HTTP_HOST'])) - { - $tracer .= '<br>'.$_SERVER['HTTP_HOST']; - if(isset($_SERVER['PHP_SELF'])) - { - $tracer .= $_SERVER['PHP_SELF']; - } - } - elseif(isset($_SERVER['PHP_SELF'])) - { - $tracer .= '<br>'.$_SERVER['PHP_SELF']; - } - - $tracer = (string) substr($tracer,0,500); - - if(is_array($inputarr)) - { - if(is_array(reset($inputarr))) - { - $params = 'Array sizeof=' . sizeof($inputarr); - } - else - { - // Quote string parameters so we can see them in the - // performance stats. This helps spot disabled indexes. - $xar_params = $inputarr; - foreach($xar_params as $xar_param_key => $xar_param) - { - if (gettype($xar_param) == 'string') - $xar_params[$xar_param_key] = '"' . $xar_param . '"'; - } - $params = implode(', ', $xar_params); - if (strlen($params) >= 3000) $params = substr($params, 0, 3000); - } - } - else - { - $params = ''; - } - - if (is_array($sql)) $sql = $sql[0]; - $arr = array('b'=>strlen($sql).'.'.crc32($sql), - 'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>adodb_round($time,6)); - - $saved = $conn->debug; - $conn->debug = 0; - - $d = $conn->sysTimeStamp; - if (empty($d)) - { - $d = date("'Y-m-d H:i:s'"); - } - - /* - // OCI/Informix/ODBC_MSSQL - not sure if/how available in adodb-lite so I've commented out the section for now - (Pádraic) - */ - - /*if ($dbT == 'oci8' && $dbT != 'oci8po') - { - $isql = "insert into $perf_table values($d,:b,:c,:d,:e,:f)"; - } - elseif($dbT == 'odbc_mssql' || $dbT == 'informix') - { - $timer = $arr['f']; - if ($dbT == 'informix') $sql2 = substr($sql2,0,230); - - $sql1 = $conn->qstr($arr['b']); - $sql2 = $conn->qstr($arr['c']); - $params = $conn->qstr($arr['d']); - $tracer = $conn->qstr($arr['e']); - - $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values($d,$sql1,$sql2,$params,$tracer,$timer)"; - if ($dbT == 'informix') $isql = str_replace(chr(10),' ',$isql); - $arr = false; - } else {*/ - $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $d,?,?,?,?,?)"; - //} - - $ok = $conn->Execute($isql,$arr); - $conn->debug = $saved; - - if ($ok) { - $conn->_logsql = true; - } else { - $err2 = $conn->ErrorMsg(); - $conn->_logsql = true; // enable logsql error simulation - $perf =& NewPerfMonitor($conn); - if ($perf) { - if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr); - } else { - $ok = $conn->Execute("create table $perf_table ( - created varchar(50), - sql0 varchar(250), - sql1 varchar(4000), - params varchar(3000), - tracer varchar(500), - timer decimal(16,6))"); - } - /*if (!$ok) { - ADOConnection::outp( "<p><b>LOGSQL Insert Failed</b>: $isql<br>$err2</p>"); - $conn->_logsql = false; - }*/ - } - $conn->_errorMsg = $errM; - $conn->_errorCode = $errN; - } - return $rs; -} - - -/* -The settings data structure is an associative array that database parameter per element. - -Each database parameter element in the array is itself an array consisting of: - -0: category code, used to group related db parameters -1: either - a. sql string to retrieve value, eg. "select value from v\$parameter where name='db_block_size'", - b. array holding sql string and field to look for, e.g. array('show variables','table_cache'), - c. a string prefixed by =, then a PHP method of the class is invoked, - e.g. to invoke $this->GetIndexValue(), set this array element to '=GetIndexValue', -2: description of the database parameter -*/ - -class adodb_perf { - - function adodb_perf() {} - - /** - * Alias for perfmon_parent_ADOConnection::table() - * - * @access public - * @param string $newtable The name for the table to use; optional. - * @return string - */ - function table($newtable = false) { - $rt = perfmon_parent_ADOConnection::table($newtable); - return $rt; - } - - } - -?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:57:29
|
Revision: 69 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=69&view=rev Author: caleb870 Date: 2007-07-30 17:57:32 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/tohtml.inc.php Removed Paths: ------------- trunk/functions/tohtml.inc.php Copied: trunk/functions/adodb/tohtml.inc.php (from rev 68, trunk/functions/tohtml.inc.php) =================================================================== --- trunk/functions/adodb/tohtml.inc.php (rev 0) +++ trunk/functions/adodb/tohtml.inc.php 2007-07-31 00:57:32 UTC (rev 69) @@ -0,0 +1,183 @@ +<?php +/* + V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. + + Some pretty-printing by Chris Oxenreider <oxe...@st...> +*/ + +// specific code for tohtml +GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND; + +$ADODB_ROUND=4; // rounding +$gSQLMaxRows = 1000; // max no of rows to download +$gSQLBlockRows=20; // max no of rows per table block + +// RecordSet to HTML Table +//------------------------------------------------------------ +// Convert a recordset to a html table. Multiple tables are generated +// if the number of rows is > $gSQLBlockRows. This is because +// web browsers normally require the whole table to be downloaded +// before it can be rendered, so we break the output into several +// smaller faster rendering tables. +// +// $rs: the recordset +// $ztabhtml: the table tag attributes (optional) +// $zheaderarray: contains the replacement strings for the headers (optional) +// +// USAGE: +// include('adodb.inc.php'); +// $db = ADONewConnection('mysql'); +// $db->Connect('mysql','userid','password','database'); +// $rs = $db->Execute('select col1,col2,col3 from table'); +// rs2html($rs, 'BORDER=2', array('Title1', 'Title2', 'Title3')); +// $rs->Close(); +// +// RETURNS: number of rows displayed + + +function rs2html(&$rs,$ztabhtml=false,$zheaderarray=false,$htmlspecialchars=true,$echo = true) +{ + $s ='';$rows=0;$docnt = false; + GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND; + + if (!$rs) + { + printf(ADODB_BAD_RS,'rs2html'); + return false; + } + + if(!$ztabhtml) + { + $ztabhtml = 'style="border: 2px groove #000000; background-color: #FFFFFF; width: 98%;"'; + } +; + $typearr = array(); + $ncols = $rs->FieldCount(); + $hdr = "\n<table $ztabhtml><tr>\n\n"; //removed cols='$ncols' as proprietary table attribute + for ($i=0; $i < $ncols; $i++) + { + $field = $rs->FetchField($i); + if ($field) + { + if ($zheaderarray) $fname = $zheaderarray[$i]; + else $fname = htmlentities($field->name, ENT_QUOTES, 'UTF-8'); + $typearr[$i] = $rs->MetaType($field->type,$field->max_length); + } + else + { + $fname = 'Field '.($i+1); + $typearr[$i] = 'C'; + } + if (strlen($fname)==0) $fname = ' '; + $hdr .= "\n<th>$fname</th>"; + } + $hdr .= "\n</tr>"; + if ($echo) print $hdr."\n\n"; + else $html = $hdr; + + // smart algorithm - handles ADODB_FETCH_MODE's correctly by probing... + $numoffset = isset($rs->fields[0]) ||isset($rs->fields[1]) || isset($rs->fields[2]); + while (!$rs->EOF) { + + $s .= "\n<tr style='vertical-align: top;'>\n"; + + for ($i=0; $i < $ncols; $i++) { + if ($i===0) $v=($numoffset) ? $rs->fields[0] : reset($rs->fields); + else $v = ($numoffset) ? $rs->fields[$i] : next($rs->fields); + + $type = $typearr[$i]; + switch($type) { + case 'D': + if (empty($v)) $s .= "<td> </td>\n"; + else if (!strpos($v,':')) { + $s .= " <td>". $v ." </td>\n"; + } + break; + case 'T': + if (empty($v)) $s .= "<td> </td>\n"; + else $s .= " <td>".$v." </td>\n"; + break; + + case 'N': + if (abs($v) - round($v,0) < 0.00000001) + $v = round($v); + else + $v = round($v,$ADODB_ROUND); + case 'I': + $s .= " <td style='text-align: right;'>".stripslashes((trim($v))) ." </td>\n"; + + break; + + default: + if ($htmlspecialchars) $v = htmlentities(trim($v), ENT_QUOTES, 'UTF-8'); + $v = trim($v); + if (strlen($v) == 0) $v = ' '; + $s .= " <td>". str_replace("\n",'<br />',stripslashes($v)) ."</td>\n"; + + } + } // for + $s .= "</tr>\n\n"; + + $rows += 1; + if ($rows >= $gSQLMaxRows) { + $rows = "<p>Truncated at $gSQLMaxRows</p>"; + break; + } // switch + + $rs->MoveNext(); + + // additional EOF check to prevent a widow header + if (!$rs->EOF && $rows % $gSQLBlockRows == 0) { + + //if (connection_aborted()) break;// not needed as PHP aborts script, unlike ASP + if ($echo) print $s . "</table>\n\n"; + else $html .= $s ."</table>\n\n"; + $s = $hdr; + } + } // while + + if ($echo) print $s."</table>\n\n"; + else $html .= $s."</table>\n\n"; + + if ($docnt) if ($echo) print "<h2>".$rows." Rows</h2>"; + + return ($echo) ? $rows : $html; + } + +// pass in 2 dimensional array +function arr2html(&$arr,$ztabhtml='',$zheaderarray='') +{ + if (!$ztabhtml) $ztabhtml = 'style="border: 2px groove #000000; background-color: #FFFFFF;"'; + + $s = "<table $ztabhtml>";//';print_r($arr); + + if ($zheaderarray) { + $s .= '<tr>'; + for ($i=0; $i<sizeof($zheaderarray); $i++) { + $s .= " <th>{$zheaderarray[$i]}</th>\n"; + } + $s .= "\n</tr>"; + } + + for ($i=0; $i<sizeof($arr); $i++) { + $s .= '<tr>'; + $a = &$arr[$i]; + if (is_array($a)) + for ($j=0; $j<sizeof($a); $j++) { + $val = $a[$j]; + if (empty($val)) $val = ' '; + $s .= " <td>$val</td>\n"; + } + else if ($a) { + $s .= ' <td>'.$a."</td>\n"; + } else $s .= " <td> </td>\n"; + $s .= "\n</tr>\n"; + } + $s .= '</table>'; + print $s; +} + +?> Deleted: trunk/functions/tohtml.inc.php =================================================================== --- trunk/functions/tohtml.inc.php 2007-07-31 00:56:43 UTC (rev 68) +++ trunk/functions/tohtml.inc.php 2007-07-31 00:57:32 UTC (rev 69) @@ -1,183 +0,0 @@ -<?php -/* - V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. - - Some pretty-printing by Chris Oxenreider <oxe...@st...> -*/ - -// specific code for tohtml -GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND; - -$ADODB_ROUND=4; // rounding -$gSQLMaxRows = 1000; // max no of rows to download -$gSQLBlockRows=20; // max no of rows per table block - -// RecordSet to HTML Table -//------------------------------------------------------------ -// Convert a recordset to a html table. Multiple tables are generated -// if the number of rows is > $gSQLBlockRows. This is because -// web browsers normally require the whole table to be downloaded -// before it can be rendered, so we break the output into several -// smaller faster rendering tables. -// -// $rs: the recordset -// $ztabhtml: the table tag attributes (optional) -// $zheaderarray: contains the replacement strings for the headers (optional) -// -// USAGE: -// include('adodb.inc.php'); -// $db = ADONewConnection('mysql'); -// $db->Connect('mysql','userid','password','database'); -// $rs = $db->Execute('select col1,col2,col3 from table'); -// rs2html($rs, 'BORDER=2', array('Title1', 'Title2', 'Title3')); -// $rs->Close(); -// -// RETURNS: number of rows displayed - - -function rs2html(&$rs,$ztabhtml=false,$zheaderarray=false,$htmlspecialchars=true,$echo = true) -{ - $s ='';$rows=0;$docnt = false; - GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND; - - if (!$rs) - { - printf(ADODB_BAD_RS,'rs2html'); - return false; - } - - if(!$ztabhtml) - { - $ztabhtml = 'style="border: 2px groove #000000; background-color: #FFFFFF; width: 98%;"'; - } -; - $typearr = array(); - $ncols = $rs->FieldCount(); - $hdr = "\n<table $ztabhtml><tr>\n\n"; //removed cols='$ncols' as proprietary table attribute - for ($i=0; $i < $ncols; $i++) - { - $field = $rs->FetchField($i); - if ($field) - { - if ($zheaderarray) $fname = $zheaderarray[$i]; - else $fname = htmlentities($field->name, ENT_QUOTES, 'UTF-8'); - $typearr[$i] = $rs->MetaType($field->type,$field->max_length); - } - else - { - $fname = 'Field '.($i+1); - $typearr[$i] = 'C'; - } - if (strlen($fname)==0) $fname = ' '; - $hdr .= "\n<th>$fname</th>"; - } - $hdr .= "\n</tr>"; - if ($echo) print $hdr."\n\n"; - else $html = $hdr; - - // smart algorithm - handles ADODB_FETCH_MODE's correctly by probing... - $numoffset = isset($rs->fields[0]) ||isset($rs->fields[1]) || isset($rs->fields[2]); - while (!$rs->EOF) { - - $s .= "\n<tr style='vertical-align: top;'>\n"; - - for ($i=0; $i < $ncols; $i++) { - if ($i===0) $v=($numoffset) ? $rs->fields[0] : reset($rs->fields); - else $v = ($numoffset) ? $rs->fields[$i] : next($rs->fields); - - $type = $typearr[$i]; - switch($type) { - case 'D': - if (empty($v)) $s .= "<td> </td>\n"; - else if (!strpos($v,':')) { - $s .= " <td>". $v ." </td>\n"; - } - break; - case 'T': - if (empty($v)) $s .= "<td> </td>\n"; - else $s .= " <td>".$v." </td>\n"; - break; - - case 'N': - if (abs($v) - round($v,0) < 0.00000001) - $v = round($v); - else - $v = round($v,$ADODB_ROUND); - case 'I': - $s .= " <td style='text-align: right;'>".stripslashes((trim($v))) ." </td>\n"; - - break; - - default: - if ($htmlspecialchars) $v = htmlentities(trim($v), ENT_QUOTES, 'UTF-8'); - $v = trim($v); - if (strlen($v) == 0) $v = ' '; - $s .= " <td>". str_replace("\n",'<br />',stripslashes($v)) ."</td>\n"; - - } - } // for - $s .= "</tr>\n\n"; - - $rows += 1; - if ($rows >= $gSQLMaxRows) { - $rows = "<p>Truncated at $gSQLMaxRows</p>"; - break; - } // switch - - $rs->MoveNext(); - - // additional EOF check to prevent a widow header - if (!$rs->EOF && $rows % $gSQLBlockRows == 0) { - - //if (connection_aborted()) break;// not needed as PHP aborts script, unlike ASP - if ($echo) print $s . "</table>\n\n"; - else $html .= $s ."</table>\n\n"; - $s = $hdr; - } - } // while - - if ($echo) print $s."</table>\n\n"; - else $html .= $s."</table>\n\n"; - - if ($docnt) if ($echo) print "<h2>".$rows." Rows</h2>"; - - return ($echo) ? $rows : $html; - } - -// pass in 2 dimensional array -function arr2html(&$arr,$ztabhtml='',$zheaderarray='') -{ - if (!$ztabhtml) $ztabhtml = 'style="border: 2px groove #000000; background-color: #FFFFFF;"'; - - $s = "<table $ztabhtml>";//';print_r($arr); - - if ($zheaderarray) { - $s .= '<tr>'; - for ($i=0; $i<sizeof($zheaderarray); $i++) { - $s .= " <th>{$zheaderarray[$i]}</th>\n"; - } - $s .= "\n</tr>"; - } - - for ($i=0; $i<sizeof($arr); $i++) { - $s .= '<tr>'; - $a = &$arr[$i]; - if (is_array($a)) - for ($j=0; $j<sizeof($a); $j++) { - $val = $a[$j]; - if (empty($val)) $val = ' '; - $s .= " <td>$val</td>\n"; - } - else if ($a) { - $s .= ' <td>'.$a."</td>\n"; - } else $s .= " <td> </td>\n"; - $s .= "\n</tr>\n"; - } - $s .= '</table>'; - print $s; -} - -?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:57:39
|
Revision: 70 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=70&view=rev Author: caleb870 Date: 2007-07-30 17:57:42 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/xmlschema.dtd Removed Paths: ------------- trunk/functions/xmlschema.dtd Copied: trunk/functions/adodb/xmlschema.dtd (from rev 69, trunk/functions/xmlschema.dtd) =================================================================== --- trunk/functions/adodb/xmlschema.dtd (rev 0) +++ trunk/functions/adodb/xmlschema.dtd 2007-07-31 00:57:42 UTC (rev 70) @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<!DOCTYPE adodb_schema [ +<!ELEMENT schema (table*, sql*)> +<!ATTLIST schema version CDATA #REQUIRED> +<!ELEMENT table ((field+|DROP), constraint*, descr?, index*, data*)> +<!ELEMENT field ((NOTNULL|KEY|PRIMARY)?, (AUTO|AUTOINCREMENT)?, (DEFAULT|DEFDATE|DEFTIMESTAMP)?, NOQUOTE, CONSTRAINT, descr?)> +<!ELEMENT data (row+)> +<!ELEMENT row (f+)> +<!ELEMENT f (#CDATA)> +<!ELEMENT descr (#CDATA)> +<!ELEMENT NOTNULL EMPTY> +<!ELEMENT KEY EMPTY> +<!ELEMENT PRIMARY EMPTY> +<!ELEMENT AUTO EMPTY> +<!ELEMENT AUTOINCREMENT EMPTY> +<!ELEMENT DEFAULT EMPTY> +<!ELEMENT DEFDATE EMPTY> +<!ELEMENT DEFTIMESTAMP EMPTY> +<!ELEMENT NOQUOTE EMPTY> +<!ELEMENT DROP EMPTY> +<!ELEMENT constraint (#CDATA)> +<!ATTLIST table name CDATA #REQUIRED platform CDATA #IMPLIED version CDATA #IMPLIED> +<!ATTLIST field name CDATA #REQUIRED type (C|C2|X|X2|B|D|T|L|I|F|N) #REQUIRED size CDATA #IMPLIED> +<!ATTLIST data platform CDATA #IMPLIED> +<!ATTLIST f name CDATA #IMPLIED> +<!ATTLIST DEFAULT VALUE CDATA #REQUIRED> +<!ELEMENT index ((col+|DROP), CLUSTERED?, BITMAP?, UNIQUE?, FULLTEXT?, HASH?, descr?)> +<!ELEMENT col (#CDATA)> +<!ELEMENT CLUSTERED EMPTY> +<!ELEMENT BITMAP EMPTY> +<!ELEMENT UNIQUE EMPTY> +<!ELEMENT FULLTEXT EMPTY> +<!ELEMENT HASH EMPTY> +<!ATTLIST index name CDATA #REQUIRED platform CDATA #IMPLIED> +<!ELEMENT sql (query+, descr?)> +<!ELEMENT query (#CDATA)> +<!ATTLIST sql name CDATA #IMPLIED platform CDATA #IMPLIED, key CDATA, prefixmethod (AUTO|MANUAL|NONE) > +] > Deleted: trunk/functions/xmlschema.dtd =================================================================== --- trunk/functions/xmlschema.dtd 2007-07-31 00:57:32 UTC (rev 69) +++ trunk/functions/xmlschema.dtd 2007-07-31 00:57:42 UTC (rev 70) @@ -1,38 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE adodb_schema [ -<!ELEMENT schema (table*, sql*)> -<!ATTLIST schema version CDATA #REQUIRED> -<!ELEMENT table ((field+|DROP), constraint*, descr?, index*, data*)> -<!ELEMENT field ((NOTNULL|KEY|PRIMARY)?, (AUTO|AUTOINCREMENT)?, (DEFAULT|DEFDATE|DEFTIMESTAMP)?, NOQUOTE, CONSTRAINT, descr?)> -<!ELEMENT data (row+)> -<!ELEMENT row (f+)> -<!ELEMENT f (#CDATA)> -<!ELEMENT descr (#CDATA)> -<!ELEMENT NOTNULL EMPTY> -<!ELEMENT KEY EMPTY> -<!ELEMENT PRIMARY EMPTY> -<!ELEMENT AUTO EMPTY> -<!ELEMENT AUTOINCREMENT EMPTY> -<!ELEMENT DEFAULT EMPTY> -<!ELEMENT DEFDATE EMPTY> -<!ELEMENT DEFTIMESTAMP EMPTY> -<!ELEMENT NOQUOTE EMPTY> -<!ELEMENT DROP EMPTY> -<!ELEMENT constraint (#CDATA)> -<!ATTLIST table name CDATA #REQUIRED platform CDATA #IMPLIED version CDATA #IMPLIED> -<!ATTLIST field name CDATA #REQUIRED type (C|C2|X|X2|B|D|T|L|I|F|N) #REQUIRED size CDATA #IMPLIED> -<!ATTLIST data platform CDATA #IMPLIED> -<!ATTLIST f name CDATA #IMPLIED> -<!ATTLIST DEFAULT VALUE CDATA #REQUIRED> -<!ELEMENT index ((col+|DROP), CLUSTERED?, BITMAP?, UNIQUE?, FULLTEXT?, HASH?, descr?)> -<!ELEMENT col (#CDATA)> -<!ELEMENT CLUSTERED EMPTY> -<!ELEMENT BITMAP EMPTY> -<!ELEMENT UNIQUE EMPTY> -<!ELEMENT FULLTEXT EMPTY> -<!ELEMENT HASH EMPTY> -<!ATTLIST index name CDATA #REQUIRED platform CDATA #IMPLIED> -<!ELEMENT sql (query+, descr?)> -<!ELEMENT query (#CDATA)> -<!ATTLIST sql name CDATA #IMPLIED platform CDATA #IMPLIED, key CDATA, prefixmethod (AUTO|MANUAL|NONE) > -] > This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:55:56
|
Revision: 66 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=66&view=rev Author: caleb870 Date: 2007-07-30 17:55:59 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-perf-module.inc.php Removed Paths: ------------- trunk/functions/adodb-perf-module.inc.php Copied: trunk/functions/adodb/adodb-perf-module.inc.php (from rev 65, trunk/functions/adodb-perf-module.inc.php) =================================================================== --- trunk/functions/adodb/adodb-perf-module.inc.php (rev 0) +++ trunk/functions/adodb/adodb-perf-module.inc.php 2007-07-31 00:55:59 UTC (rev 66) @@ -0,0 +1,974 @@ +<?php +/* +V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. See License.txt. + + Library for basic performance monitoring and tuning. + + Modified 23 April 2006 for use with ADOdb Lite by Pádraic Brady + Such modifications as listed (c) 2006 Pádraic Brady (mau...@ho...) + + Modifications: + - Moved below methods from adodb_perf class to create a common parent from which all driver + specific perfmon modules will extend to prevent duplicate code. + - See specific driver module files for other changes + +*/ + +eval('class perfmon_parent_EXTENDER extends ' . $last_module . '_ADOConnection { }'); + +class perfmon_parent_ADOConnection extends perfmon_parent_EXTENDER +{ + + var $color = '#F0F0F0'; + var $table = '<table style="border: 2px groove #000000; background-color: #FFFFFF;">'; + var $titles = '<tr><td><strong>Parameter</strong></td><td><strong>Value</strong></td><td><strong>Description</strong></td></tr>'; + var $warnRatio = 90; + var $tablesSQL = false; + var $cliFormat = "%32s => %s \r\n"; + var $sql1 = 'sql1'; // used for casting sql1 to text for mssql + var $explain = true; + var $helpurl = '<a href="javascript:void();">LogSQL help</a>'; + var $createTableSQL = false; + var $maxLength = 2000; + var $settings = false; + var $_logsql = false; + var $_lastload; + + /** + * Sets the table name to use for SQL logging. Returns value of current table when called. + * Usage: perfmon_parent_ADOConnection::table('custom_log_sql'); + * $currentTable = perfmon_parent_ADOConnection::table(); + * + * @access public + * @param string $newtable The name for the table to use; optional. + * @return string + */ + function table($newtable = false) + { + static $_table; + if (!empty($newtable)) $_table = $newtable; + if (empty($_table)) $_table = 'adodb_logsql'; + return $_table; + } + + /** + * Enables SQL logging to database for Performance Monitor use. + * Usage: $oldValue = $db->LogSQL( $enable ); + * $enable is optional; defaults to TRUE enabling logging. FALSE disables logging. + * + * @access public + * @param bool $enable + * @return bool + */ + function LogSQL($enable=true) + { + $old = $this->_logsql; + $this->_logsql = $enable; + return $old; + } + + /** + * Returns an array with information to calculate CPU Load + * + * @access private + * @return mixed + */ + function _CPULoad() { + // Algorithm is taken from + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/example__obtaining_raw_performance_data.asp + if (strncmp(PHP_OS,'WIN',3)==0) + { + if (PHP_VERSION == '5.0.0') return false; + if (PHP_VERSION == '5.0.1') return false; + if (PHP_VERSION == '5.0.2') return false; + if (PHP_VERSION == '5.0.3') return false; + if (PHP_VERSION == '4.3.10') return false; # see http://bugs.php.net/bug.php?id=31737 + + @$c = new COM("WinMgmts:{impersonationLevel=impersonate}!Win32_PerfRawData_PerfOS_Processor.Name='_Total'"); + if (!$c) return false; + + $info[0] = $c->PercentProcessorTime; + $info[1] = 0; + $info[2] = 0; + $info[3] = $c->TimeStamp_Sys100NS; + return $info; + } + + // Algorithm - Steve Blinch (BlitzAffe Online, http://www.blitzaffe.com) + $statfile = '/proc/stat'; + if (!file_exists($statfile)) return false; + + $fd = fopen($statfile,"r"); + if (!$fd) return false; + + $statinfo = explode("\n",fgets($fd, 1024)); + fclose($fd); + foreach($statinfo as $line) + { + $info = explode(" ",$line); + if($info[0]=="cpu") + { + array_shift($info); // pop off "cpu" + if(!$info[0]) array_shift($info); // pop off blank space (if any) + return $info; + } + } + + return false; + } + + /* NOT IMPLEMENTED */ + function MemInfo() + { + + } + + + /** + * Returns CPU Load + * + * @access public + * @return mixed + */ + function CPULoad() + { + $info = $this->_CPULoad(); + if (!$info) return false; + + if (empty($this->_lastLoad)) + { + sleep(1); + $this->_lastLoad = $info; + $info = $this->_CPULoad(); + } + + $last = $this->_lastLoad; + $this->_lastLoad = $info; + + $d_user = $info[0] - $last[0]; + $d_nice = $info[1] - $last[1]; + $d_system = $info[2] - $last[2]; + $d_idle = $info[3] - $last[3]; + + if (strncmp(PHP_OS,'WIN',3)==0) + { + if ($d_idle < 1) $d_idle = 1; + return 100*(1-$d_user/$d_idle); + } + else + { + $total=$d_user+$d_nice+$d_system+$d_idle; + if ($total<1) $total=1; + return 100*($d_user+$d_nice+$d_system)/$total; + } + } + + function Tracer($sql) + { + $perf_table = perfmon_parent_ADOConnection::table(); + $saveE = $this->LogSQL(false); + + global $ADODB_FETCH_MODE; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + $sqlq = $this->qstr($sql); + $arr = $this->GetArray( + "select count(*),tracer + from $perf_table where sql1=$sqlq + group by tracer + order by 1 desc" + ); + $s = ''; + if ($arr) + { + $s .= '\n<h3>Scripts Affected</h3>\n'; + foreach($arr as $k) + { + $s .= sprintf("%4d",$k[0]).' '.strip_tags($k[1]).'<br />'; + } + } + $this->LogSQL($saveE); + return $s; + } + + /* + Explain Plan for $sql. + If only a snippet of the $sql is passed in, then $partial will hold the crc32 of the + actual sql. + */ + function Explain($sql, $partial=false) + { + return false; + } + + function InvalidSQL($numsql = 10) + { + + if (isset($_GET['sql'])) return; + $s = '<h3>Invalid SQL</h3>'; + $saveE = $this->LogSQL(false); + $perf_table = perfmon_parent_ADOConnection::table(); + $rs =& $this->SelectLimit( + "select distinct count(*), sql1, tracer as error_msg + from $perf_table + where tracer like 'ERROR:%' + group by sql1, tracer + order by 1 desc" + ,$numsql + ); + $this->LogSQL($saveE); + if ($rs) + { + $s .= rs2html($rs,false,false,false,false); + } + else + { + return "\n<p>$this->helpurl. ".$this->ErrorMsg()."</p>\n"; + } + return $s; + } + + + /* + This script identifies the longest running SQL + */ + function _SuspiciousSQL($numsql = 10) + { + global $ADODB_FETCH_MODE; + + $perf_table = perfmon_parent_ADOConnection::table(); + $saveE = $this->LogSQL(false); + + if (isset($_GET['exps']) && isset($_GET['sql'])) + { + $partial = !empty($_GET['part']); + echo '<a name="explain"></a>' . $this->Explain($_GET['sql'], $partial) . "\n"; + } + + if (isset($_GET['sql'])) return; + $sql1 = $this->sql1; + + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + $rs =& $this->SelectLimit( + "select avg(timer) as avg_timer, $sql1, count(*), max(timer) as max_timer, min(timer) as min_timer + from $perf_table + where {$this->upperCase}({$this->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT') + and (tracer is null or tracer not like 'ERROR:%') + group by sql1 + order by 1 desc" + ,$numsql + ); + + $ADODB_FETCH_MODE = $save; + $this->LogSQL($saveE); + + if (!$rs) return "<p>$this->helpurl. ".$this->ErrorMsg()."</p>"; + $s = "<h3>Suspicious SQL</h3>\n<span style=\"font-size: 8pt;\">The following SQL have high average execution times</span><br />\n<table style=\"border: 2px groove #000000; background-color: #FFFFFF;\">\n<tr>\n<td><strong>Avg Time</strong></td>\n<td><strong>Count</strong></td>\n<td><strong>SQL</strong></td>\n<td><strong>Max</strong></td>\n<td><strong>Min</strong></td>\n</tr>\n"; + + $max = $this->maxLength; + while (!$rs->EOF) + { + $sql = $rs->fields[1]; + $raw = urlencode($sql); + if (strlen($raw)>$max-100) + { + $sql2 = substr($sql,0,$max-500); + $raw = urlencode($sql2).'&part='.crc32($sql); + } + $prefix = "<a target=\"sql".rand()."\" href=\"?hidem=1&exps=1&sql=".$raw."&x#explain\">"; + $suffix = "</a>"; + if ($this->explain == false || strlen($prefix) > $max) + { + $suffix = ' ... <em>String too long for GET parameter: '.strlen($prefix).'</em>'; + $prefix = ''; + } + + $s .= "\n<tr>\n<td>\n" + .adodb_round($rs->fields[0],6) + ."\n</td><td style='text-align: right;'>\n" + .$rs->fields[2] + ."\n</td><td>\n<span style=\"font-size: 10pt;\">" + .$prefix + .htmlentities($sql, ENT_QUOTES, 'UTF-8') + .$suffix + ."</span>\n</td><td>\n" + .$rs->fields[3] + ."\n</td><td>\n" + .$rs->fields[4] + ."\n</tr>"; + + $rs->MoveNext(); + } + return $s."\n</table>\n"; + + } + + function CheckMemory() + { + return ''; + } + + + function SuspiciousSQL($numsql=10) + { + return perfmon_parent_ADOConnection::_SuspiciousSQL($numsql); + } + + function ExpensiveSQL($numsql=10) + { + return perfmon_parent_ADOConnection::_ExpensiveSQL($numsql); + } + + + /* + This reports the percentage of load on the instance due to the most + expensive few SQL statements. Tuning these statements can often + make huge improvements in overall system performance. + */ + function _ExpensiveSQL($numsql = 10) + { + global $ADODB_FETCH_MODE; + $perf_table = perfmon_parent_ADOConnection::table(); + + $saveE = $this->LogSQL(false); + + if (isset($_GET['expe']) && isset($_GET['sql'])) + { + $partial = !empty($_GET['part']); + echo "\n<a name=\"explain\"></a>" . $this->Explain($_GET['sql'], $partial) . "\n"; + } + + if (isset($_GET['sql'])) return; + + $sql1 = $this->sql1; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + $rs =& $this->SelectLimit( + "select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer + from $perf_table + where {$this->upperCase}({$this->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT') + and (tracer is null or tracer not like 'ERROR:%') + group by sql1 + having count(*)>1 + order by 1 desc" + ,$numsql + ); + + $this->LogSQL($saveE); + $ADODB_FETCH_MODE = $save; + + if (!$rs) return "<p>$this->helpurl. " . $this->ErrorMsg() . "</p>\n"; + $s = "\n<h3>Expensive SQL</h3>\n<span style=\"font-size: 8pt;\">Tuning the following SQL could reduce the server load substantially</span><br />\n<table style=\"border: 2px groove #000000;\">\n<tr>\n<td><strong>Load</strong></td>\n<td><strong>Count</strong></td>\n<td><strong>SQL</strong></td>\n<td><strong>Max</strong></td>\n<td><strong>Min</strong></td>\n</tr>\n"; + + $max = $this->maxLength; + while (!$rs->EOF) + { + $sql = $rs->fields[1]; + $raw = urlencode($sql); + if (strlen($raw)>$max-100) + { + $sql2 = substr($sql,0,$max-500); + $raw = urlencode($sql2).'&part='.crc32($sql); + } + $prefix = "<a target=\"sqle" . rand() . "\" href=\"?hidem=1&expe=1&sql=" . $raw . "&x#explain\">"; + $suffix = "</a>\n"; + if($this->explain == false || strlen($prefix > $max)) + { + $prefix = ''; + $suffix = ''; + } + $s .= "\n<tr>\n<td>\n" + .adodb_round($rs->fields[0],6) + ."\n</td><td style='text-align: right;'>\n" + .$rs->fields[2] + ."\n</td>\n<td><span style=\"font-size: 10pt;\">" + .$prefix + .htmlentities($sql, ENT_QUOTES, 'UTF-8') + .$suffix + ."</span>" + ."\n</td><td>" + .$rs->fields[3] + ."\n</td><td>" + .$rs->fields[4] + ."\n</tr>"; + $rs->MoveNext(); + } + return $s."\n</table>\n"; + } + + /* + Raw function to return parameter value from $settings. + */ + function DBParameter($param) + { + if (empty($this->settings[$param])) return false; + $sql = $this->settings[$param][1]; + return $this->_DBParameter($sql); + } + + /* + Raw function returning array of poll paramters + */ + function &PollParameters() + { + $arr[0] = (float)$this->DBParameter('data cache hit ratio'); + $arr[1] = (float)$this->DBParameter('data reads'); + $arr[2] = (float)$this->DBParameter('data writes'); + $arr[3] = (integer) $this->DBParameter('current connections'); + return $arr; + } + + /* + Low-level Get Database Parameter + */ + function _DBParameter($sql) + { + $savelog = $this->LogSQL(false); + if (is_array($sql)) + { + global $ADODB_FETCH_MODE; + + $sql1 = $sql[0]; + $key = $sql[1]; + if (sizeof($sql)>2) $pos = $sql[2]; + else $pos = 1; + if (sizeof($sql)>3) $coef = $sql[3]; + else $coef = false; + $ret = false; + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + + $rs = $this->Execute($sql1); + + $ADODB_FETCH_MODE = $save; + if($rs) + { + while (!$rs->EOF) + { + $keyf = reset($rs->fields); + if (trim($keyf) == $key) + { + $ret = $rs->fields[$pos]; + if ($coef) $ret *= $coef; + break; + } + $rs->MoveNext(); + } + $rs->Close(); + } + $this->LogSQL($savelog); + return $ret; + } + else + { + if (strncmp($sql,'=',1) == 0) + { + $fn = substr($sql,1); + return $this->$fn(); + } + $sql = str_replace('$DATABASE',$this->database,$sql); + $ret = $this->GetOne($sql); + $this->LogSQL($savelog); + + return $ret; + } + } + + /* + Warn if cache ratio falls below threshold. Displayed in "Description" column. + */ + function WarnCacheRatio($val) + { + if ($val < $this->warnRatio) + return '<span style="color: red;"><strong>Cache ratio should be at least '.$this->warnRatio.'%</strong></span>'; + else return ''; + } + + /***********************************************************************************************/ + // HIGH LEVEL UI FUNCTIONS + /***********************************************************************************************/ + + + function UI($pollsecs=5) + { + + $perf_table = perfmon_parent_ADOConnection::table(); + + $app = $this->host; + if ($this->host && $this->database) $app .= ', db='; + $app .= $this->database; + + if ($app) $app .= ', '; + $savelog = $this->LogSQL(false); + $info = $this->ServerInfo(); + if(isset($_GET['clearsql'])) + { + $this->Execute("delete from $perf_table"); + } + $this->LogSQL($savelog); + + // magic quotes + + if (isset($_GET['sql']) && get_magic_quotes_gpc()) + { + $_GET['sql'] = $_GET['sql'] = str_replace(array("\\'",'\"'),array("'",'"'),$_GET['sql']); + } + + if (!isset($_SESSION['ADODB_PERF_SQL'])) $nsql = $_SESSION['ADODB_PERF_SQL'] = 10; + else $nsql = $_SESSION['ADODB_PERF_SQL']; + + $app .= $info['description']; + + if(isset($_GET['do'])) + { + $do = $_GET['do']; + } + else if (isset($_POST['do'])) $do = $_POST['do']; + else if (isset($_GET['sql'])) $do = 'viewsql'; + else $do = 'stats'; + + if (isset($_GET['nsql'])) + { + if ($_GET['nsql'] > 0) $nsql = $_SESSION['ADODB_PERF_SQL'] = (integer) $_GET['nsql']; + } + + // page header + echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> + <html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\"> + <head> + <title>ADOdb-Lite Performance Monitor on $app</title> + <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" /> + <style type=\"text/css\"> + /*<![CDATA[*/ + body { background-color: #FFFFFF; font-size: 10pt; color: #000000; } + td { padding: 0px 3px 0px 3px; } + table { border: 2px groove #000000; } + /*]]>*/ + </style> + </head> + <body> + "; + + if ($do == 'viewsql') + { + $form = "\n<form method=\"post\" action=\"". $_SERVER['PHP_SELF'] ."\"># SQL:<input type=\"hidden\" value=\"viewsql\" name=\"do\" /> <input type=\"text\" size=\"4\" name=\"nsql\" value=\"$nsql\" /><input type=\"submit\" value=\"Go\" /></form>"; + } + else + { + $form = " "; + } + + $allowsql = !defined('ADODB_PERF_NO_RUN_SQL'); + + if(empty($_GET['hidem'])) + { + echo "\n<table style=\"width: 100%; background-color: lightyellow;\">\n<tr>\n<td colspan='2'>\n<strong><a href=\"http://adodb.sourceforge.net/?perf=1\">ADOdb-Lite</a> Performance Monitor</strong> <span style=\"font-size: 8pt;\">for $app</span>\n</td>\n</tr>\n<tr>\n<td>\n<a href=\"?do=stats\"><strong>Performance Stats</strong></a> <a href=\"?do=viewsql\"><strong>View SQL</strong></a> <a href=\"?do=tables\"><strong>View Tables</strong></a> <a href=\"?do=poll\"><strong>Poll Stats</strong></a>", + $allowsql ? ' <a href="?do=dosql"><strong>Run SQL</strong></a></td>' : '</td>', + "\n<td>$form\n</td>", + "\n</tr>\n</table>\n"; + } + + switch ($do) + { + case 'stats': + echo $this->HealthCheck(); + echo $this->CheckMemory(); + break; + + case 'poll': + echo "<iframe width=\"720\" height=\"80%\" + src=\"{$_SERVER['PHP_SELF']}?do=poll2&hidem=1\"></iframe>"; + break; + + case 'poll2': + echo "<pre>"; + $this->Poll($pollsecs); + echo "</pre>"; + break; + + case 'dosql': + if (!$allowsql) break; + $this->DoSQLForm(); + break; + + case 'viewsql': + if (empty($_GET['hidem'])) + { + echo " <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br />"; + } + echo($this->SuspiciousSQL($nsql)); + echo($this->ExpensiveSQL($nsql)); + echo($this->InvalidSQL($nsql)); + break; + + case 'tables': + echo $this->Tables(); + break; + + default: + echo $this->HealthCheck(); + echo $this->CheckMemory(); + break; + } + global $ADODB_vers; + echo "<div align=\"center\"><span style=\"font-size: 8pt;\">$ADODB_vers</span></div>"; + } + + /* + Runs in infinite loop, returning real-time statistics + */ + function Poll($secs=5) + { + //$saveE = $this->LogSQL(false); // but how to re-enable? + + if ($secs <= 1) $secs = 1; + echo "Accumulating statistics, every $secs seconds...\n"; flush(); + $arro =& $this->PollParameters(); + $cnt = 0; + set_time_limit(0); + sleep($secs); + while (1) { + + $arr =& $this->PollParameters(); + + $hits = sprintf('%2.2f',$arr[0]); + $reads = sprintf('%12.4f',($arr[1]-$arro[1])/$secs); + $writes = sprintf('%12.4f',($arr[2]-$arro[2])/$secs); + $sess = sprintf('%5d',$arr[3]); + + $load = $this->CPULoad(); + if ($load !== false) + { + $oslabel = 'WS-CPU%'; + $osval = sprintf(" %2.1f ",(float) $load); + } + else + { + $oslabel = ''; + $osval = ''; + } + if ($cnt % 10 == 0) echo " Time ".$oslabel." Hit% Sess Reads/s Writes/s\n"; + $cnt += 1; + echo date('H:i:s').' '.$osval."$hits $sess $reads $writes\n"; + flush(); + + if (connection_aborted()) return; + + sleep($secs); + $arro = $arr; + } + } + + /* + Returns basic health check in a command line interface + */ + function HealthCheckCLI() + { + return $this->HealthCheck(true); + } + + + /* + Returns basic health check as HTML + */ + function HealthCheck($cli=false) + { + $saveE = $this->LogSQL(false); + if ($cli) $html = ''; + else $html = $this->table.'<tr><td colspan="3"><h3>'.$this->dbtype.'</h3></td></tr>'.$this->titles; + + foreach($this->settings as $name => $arr) + { + if ($arr === false) break; + + if (!is_string($name)) + { + if ($cli) $html .= " -- $arr -- \n"; + else $html .= "<tr style=\"background-color: $this->color;\"><td colspan=\"3\"><em>$arr</em> </td></tr>"; + continue; + } + + if (!is_array($arr)) break; + $category = $arr[0]; + $how = $arr[1]; + if (sizeof($arr)>2) $desc = $arr[2]; + else $desc = ' '; + + + if ($category == 'HIDE') continue; + + $val = $this->_DBParameter($how); + + if ($desc && strncmp($desc,"=",1) === 0) + { + $fn = substr($desc,1); + $desc = $this->$fn($val); + } + + if ($val === false) + { + $m = $this->ErrorMsg(); + $val = "Error: $m"; + } + else + { + if (is_numeric($val) && $val >= 256*1024) + { + if ($val % (1024*1024) == 0) + { + $val /= (1024*1024); + $val .= 'M'; + } + else if ($val % 1024 == 0) + { + $val /= 1024; + $val .= 'K'; + } + } + } + if ($category != $oldc) + { + $oldc = $category; + } + if (strlen($desc)==0) $desc = ' '; + if (strlen($val)==0) $val = ' '; + if ($cli) + { + $html .= str_replace(' ','',sprintf($this->cliFormat,strip_tags($name),strip_tags($val),strip_tags($desc))); + } + else + { + $html .= "<tr><td>".$name.'</td><td>'.$val.'</td><td>'.$desc."</td></tr>\n"; + } + } + + if (!$cli) $html .= "</table>\n"; + $this->LogSQL($saveE); + + return $html; + } + + function Tables($orderby='1') + { + if (!$this->tablesSQL) return false; + + $savelog = $this->LogSQL(false); + $rs = $this->Execute($this->tablesSQL.' order by '.$orderby); + $this->LogSQL($savelog); + $html = rs2html($rs,false,false,false,false); + return $html; + } + + + function CreateLogTable() + { + if (!$this->createTableSQL) return false; + + $savelog = $this->LogSQL(false); + $ok = $this->Execute($this->createTableSQL); + $this->LogSQL($savelog); + return ($ok) ? true : false; + } + + function DoSQLForm() + { + $PHP_SELF = $_SERVER['PHP_SELF']; + $sql = isset($_REQUEST['sql']) ? $_REQUEST['sql'] : ''; // Let the form spoofing commence... *** + + if (isset($_SESSION['phplens_sqlrows'])) $rows = $_SESSION['phplens_sqlrows']; + else $rows = 3; + + if (isset($_REQUEST['SMALLER'])) { + $rows /= 2; + if ($rows < 3) $rows = 3; + $_SESSION['phplens_sqlrows'] = $rows; + } + if (isset($_REQUEST['BIGGER'])) { + $rows *= 2; + $_SESSION['phplens_sqlrows'] = $rows; + } + +?> + +<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"> +<table><tr> +<td> Form size: <input type="submit" value=" < " name="SMALLER" /><input type="submit" value=" > > " name="BIGGER" /> +</td> +<td align=right> +<input type="submit" value=" Run SQL Below " name="RUN" /><input type="hidden" name="do" value="dosql" /> +</td></tr> + <tr> + <td colspan="2"><textarea rows="<?php print $rows; ?>" name="sql" cols="80"><?php print htmlentities($sql, ENT_QUOTES, 'UTF-8'); ?></textarea> + </td> + </tr> + </table> +</form> + +<?php + if (!isset($_REQUEST['sql'])) return; + + $sql = $this->undomq(trim($sql)); + if (substr($sql,strlen($sql)-1) === ';') + { + $print = true; + $sqla = $this->SplitSQL($sql); + } + else + { + $print = false; + $sqla = array($sql); + } + foreach($sqla as $sqls) { + + if (!$sqls) continue; + + if ($print) { + print "<p>".htmlentities($sqls, ENT_QUOTES, 'UTF-8')."</p>"; + flush(); + } + $savelog = $this->LogSQL(false); + $rs = $this->Execute($sqls); + $this->LogSQL($savelog); + if ($rs && is_object($rs) && !$rs->EOF) + { + rs2html($rs); + while ($rs->NextRecordSet()) + { + print "<table style=\"width: 98%; background-color: #C0C0FF;\"><tr><td> </td></tr></table>"; + rs2html($rs); + } + } + else + { + $e1 = (integer) $this->ErrorNo(); + $e2 = $this->ErrorMsg(); + if (($e1) || ($e2)) + { + if (empty($e1)) $e1 = '-1'; // postgresql fix + print ' '.$e1.': '.$e2; + } + else + { + print "<p>No Recordset returned<br /></p>"; + } + } + } // foreach + } + + function SplitSQL($sql) + { + $arr = explode(';',$sql); + return $arr; + } + + function undomq(&$m) + { + if (get_magic_quotes_gpc()) { + // undo the damage + $m = str_replace('\\\\','\\',$m); + $m = str_replace('\"','"',$m); + $m = str_replace('\\\'','\'',$m); + } + return $m; + } + + + /************************************************************************/ + + /** + * Reorganise multiple table-indices/statistics/.. + * OptimizeMode could be given by last Parameter + * + * @example + * <pre> + * optimizeTables( 'tableA'); + * </pre> + * <pre> + * optimizeTables( 'tableA', 'tableB', 'tableC'); + * </pre> + * <pre> + * optimizeTables( 'tableA', 'tableB', ADODB_OPT_LOW); + * </pre> + * + * @param string table name of the table to optimize + * @param int mode optimization-mode + * <code>ADODB_OPT_HIGH</code> for full optimization + * <code>ADODB_OPT_LOW</code> for CPU-less optimization + * Default is LOW <code>ADODB_OPT_LOW</code> + * @author Markus Staab + * @return Returns <code>true</code> on success and <code>false</code> on error + */ + function OptimizeTables() + { + $args = func_get_args(); + $numArgs = func_num_args(); + + if ( $numArgs == 0) return false; + + $mode = ADODB_OPT_LOW; + $lastArg = $args[ $numArgs - 1]; + if ( !is_string($lastArg)) + { + $mode = $lastArg; + unset( $args[ $numArgs - 1]); + } + + foreach( $args as $table) + { + $this->optimizeTable( $table, $mode); + } + } + + /** + * Reorganise the table-indices/statistics/.. depending on the given mode. + * Default Implementation throws an error. + * + * @param string table name of the table to optimize + * @param int mode optimization-mode + * <code>ADODB_OPT_HIGH</code> for full optimization + * <code>ADODB_OPT_LOW</code> for CPU-less optimization + * Default is LOW <code>ADODB_OPT_LOW</code> + * @author Markus Staab + * @return Returns <code>true</code> on success and <code>false</code> on error + */ + function OptimizeTable( $table, $mode = ADODB_OPT_LOW) + { + $this->outp( sprintf( "<p>%s: '%s' not implemented for driver '%s'</p>", __CLASS__, __FUNCTION__, $this->dbtype)); + return false; + } + + /** + * Reorganise current database. + * Default implementation loops over all <code>MetaTables()</code> and + * optimize each using <code>optmizeTable()</code> + * + * Non-functional in ADOdb-Lite due to lack of MetaTables() implementation in default modules + * + * @author Markus Staab + * @return Returns <code>true</code> on success and <code>false</code> on error + */ + function optimizeDatabase() + { + //$tables = $this->MetaTables( 'TABLES'); // non-functional without a MetaTables method in ADOdb-Lite... + if ( !$tables ) return false; + + foreach( $tables as $table) + { + if (!$this->optimizeTable( $table)) + { + return false; + } + } + return true; + } + +} + +?> Deleted: trunk/functions/adodb-perf-module.inc.php =================================================================== --- trunk/functions/adodb-perf-module.inc.php 2007-07-31 00:55:44 UTC (rev 65) +++ trunk/functions/adodb-perf-module.inc.php 2007-07-31 00:55:59 UTC (rev 66) @@ -1,974 +0,0 @@ -<?php -/* -V4.65 22 July 2005 (c) 2000-2005 John Lim (jl...@na...). 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. See License.txt. - - Library for basic performance monitoring and tuning. - - Modified 23 April 2006 for use with ADOdb Lite by Pádraic Brady - Such modifications as listed (c) 2006 Pádraic Brady (mau...@ho...) - - Modifications: - - Moved below methods from adodb_perf class to create a common parent from which all driver - specific perfmon modules will extend to prevent duplicate code. - - See specific driver module files for other changes - -*/ - -eval('class perfmon_parent_EXTENDER extends ' . $last_module . '_ADOConnection { }'); - -class perfmon_parent_ADOConnection extends perfmon_parent_EXTENDER -{ - - var $color = '#F0F0F0'; - var $table = '<table style="border: 2px groove #000000; background-color: #FFFFFF;">'; - var $titles = '<tr><td><strong>Parameter</strong></td><td><strong>Value</strong></td><td><strong>Description</strong></td></tr>'; - var $warnRatio = 90; - var $tablesSQL = false; - var $cliFormat = "%32s => %s \r\n"; - var $sql1 = 'sql1'; // used for casting sql1 to text for mssql - var $explain = true; - var $helpurl = '<a href="javascript:void();">LogSQL help</a>'; - var $createTableSQL = false; - var $maxLength = 2000; - var $settings = false; - var $_logsql = false; - var $_lastload; - - /** - * Sets the table name to use for SQL logging. Returns value of current table when called. - * Usage: perfmon_parent_ADOConnection::table('custom_log_sql'); - * $currentTable = perfmon_parent_ADOConnection::table(); - * - * @access public - * @param string $newtable The name for the table to use; optional. - * @return string - */ - function table($newtable = false) - { - static $_table; - if (!empty($newtable)) $_table = $newtable; - if (empty($_table)) $_table = 'adodb_logsql'; - return $_table; - } - - /** - * Enables SQL logging to database for Performance Monitor use. - * Usage: $oldValue = $db->LogSQL( $enable ); - * $enable is optional; defaults to TRUE enabling logging. FALSE disables logging. - * - * @access public - * @param bool $enable - * @return bool - */ - function LogSQL($enable=true) - { - $old = $this->_logsql; - $this->_logsql = $enable; - return $old; - } - - /** - * Returns an array with information to calculate CPU Load - * - * @access private - * @return mixed - */ - function _CPULoad() { - // Algorithm is taken from - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/example__obtaining_raw_performance_data.asp - if (strncmp(PHP_OS,'WIN',3)==0) - { - if (PHP_VERSION == '5.0.0') return false; - if (PHP_VERSION == '5.0.1') return false; - if (PHP_VERSION == '5.0.2') return false; - if (PHP_VERSION == '5.0.3') return false; - if (PHP_VERSION == '4.3.10') return false; # see http://bugs.php.net/bug.php?id=31737 - - @$c = new COM("WinMgmts:{impersonationLevel=impersonate}!Win32_PerfRawData_PerfOS_Processor.Name='_Total'"); - if (!$c) return false; - - $info[0] = $c->PercentProcessorTime; - $info[1] = 0; - $info[2] = 0; - $info[3] = $c->TimeStamp_Sys100NS; - return $info; - } - - // Algorithm - Steve Blinch (BlitzAffe Online, http://www.blitzaffe.com) - $statfile = '/proc/stat'; - if (!file_exists($statfile)) return false; - - $fd = fopen($statfile,"r"); - if (!$fd) return false; - - $statinfo = explode("\n",fgets($fd, 1024)); - fclose($fd); - foreach($statinfo as $line) - { - $info = explode(" ",$line); - if($info[0]=="cpu") - { - array_shift($info); // pop off "cpu" - if(!$info[0]) array_shift($info); // pop off blank space (if any) - return $info; - } - } - - return false; - } - - /* NOT IMPLEMENTED */ - function MemInfo() - { - - } - - - /** - * Returns CPU Load - * - * @access public - * @return mixed - */ - function CPULoad() - { - $info = $this->_CPULoad(); - if (!$info) return false; - - if (empty($this->_lastLoad)) - { - sleep(1); - $this->_lastLoad = $info; - $info = $this->_CPULoad(); - } - - $last = $this->_lastLoad; - $this->_lastLoad = $info; - - $d_user = $info[0] - $last[0]; - $d_nice = $info[1] - $last[1]; - $d_system = $info[2] - $last[2]; - $d_idle = $info[3] - $last[3]; - - if (strncmp(PHP_OS,'WIN',3)==0) - { - if ($d_idle < 1) $d_idle = 1; - return 100*(1-$d_user/$d_idle); - } - else - { - $total=$d_user+$d_nice+$d_system+$d_idle; - if ($total<1) $total=1; - return 100*($d_user+$d_nice+$d_system)/$total; - } - } - - function Tracer($sql) - { - $perf_table = perfmon_parent_ADOConnection::table(); - $saveE = $this->LogSQL(false); - - global $ADODB_FETCH_MODE; - $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - - $sqlq = $this->qstr($sql); - $arr = $this->GetArray( - "select count(*),tracer - from $perf_table where sql1=$sqlq - group by tracer - order by 1 desc" - ); - $s = ''; - if ($arr) - { - $s .= '\n<h3>Scripts Affected</h3>\n'; - foreach($arr as $k) - { - $s .= sprintf("%4d",$k[0]).' '.strip_tags($k[1]).'<br />'; - } - } - $this->LogSQL($saveE); - return $s; - } - - /* - Explain Plan for $sql. - If only a snippet of the $sql is passed in, then $partial will hold the crc32 of the - actual sql. - */ - function Explain($sql, $partial=false) - { - return false; - } - - function InvalidSQL($numsql = 10) - { - - if (isset($_GET['sql'])) return; - $s = '<h3>Invalid SQL</h3>'; - $saveE = $this->LogSQL(false); - $perf_table = perfmon_parent_ADOConnection::table(); - $rs =& $this->SelectLimit( - "select distinct count(*), sql1, tracer as error_msg - from $perf_table - where tracer like 'ERROR:%' - group by sql1, tracer - order by 1 desc" - ,$numsql - ); - $this->LogSQL($saveE); - if ($rs) - { - $s .= rs2html($rs,false,false,false,false); - } - else - { - return "\n<p>$this->helpurl. ".$this->ErrorMsg()."</p>\n"; - } - return $s; - } - - - /* - This script identifies the longest running SQL - */ - function _SuspiciousSQL($numsql = 10) - { - global $ADODB_FETCH_MODE; - - $perf_table = perfmon_parent_ADOConnection::table(); - $saveE = $this->LogSQL(false); - - if (isset($_GET['exps']) && isset($_GET['sql'])) - { - $partial = !empty($_GET['part']); - echo '<a name="explain"></a>' . $this->Explain($_GET['sql'], $partial) . "\n"; - } - - if (isset($_GET['sql'])) return; - $sql1 = $this->sql1; - - $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - - $rs =& $this->SelectLimit( - "select avg(timer) as avg_timer, $sql1, count(*), max(timer) as max_timer, min(timer) as min_timer - from $perf_table - where {$this->upperCase}({$this->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT') - and (tracer is null or tracer not like 'ERROR:%') - group by sql1 - order by 1 desc" - ,$numsql - ); - - $ADODB_FETCH_MODE = $save; - $this->LogSQL($saveE); - - if (!$rs) return "<p>$this->helpurl. ".$this->ErrorMsg()."</p>"; - $s = "<h3>Suspicious SQL</h3>\n<span style=\"font-size: 8pt;\">The following SQL have high average execution times</span><br />\n<table style=\"border: 2px groove #000000; background-color: #FFFFFF;\">\n<tr>\n<td><strong>Avg Time</strong></td>\n<td><strong>Count</strong></td>\n<td><strong>SQL</strong></td>\n<td><strong>Max</strong></td>\n<td><strong>Min</strong></td>\n</tr>\n"; - - $max = $this->maxLength; - while (!$rs->EOF) - { - $sql = $rs->fields[1]; - $raw = urlencode($sql); - if (strlen($raw)>$max-100) - { - $sql2 = substr($sql,0,$max-500); - $raw = urlencode($sql2).'&part='.crc32($sql); - } - $prefix = "<a target=\"sql".rand()."\" href=\"?hidem=1&exps=1&sql=".$raw."&x#explain\">"; - $suffix = "</a>"; - if ($this->explain == false || strlen($prefix) > $max) - { - $suffix = ' ... <em>String too long for GET parameter: '.strlen($prefix).'</em>'; - $prefix = ''; - } - - $s .= "\n<tr>\n<td>\n" - .adodb_round($rs->fields[0],6) - ."\n</td><td style='text-align: right;'>\n" - .$rs->fields[2] - ."\n</td><td>\n<span style=\"font-size: 10pt;\">" - .$prefix - .htmlentities($sql, ENT_QUOTES, 'UTF-8') - .$suffix - ."</span>\n</td><td>\n" - .$rs->fields[3] - ."\n</td><td>\n" - .$rs->fields[4] - ."\n</tr>"; - - $rs->MoveNext(); - } - return $s."\n</table>\n"; - - } - - function CheckMemory() - { - return ''; - } - - - function SuspiciousSQL($numsql=10) - { - return perfmon_parent_ADOConnection::_SuspiciousSQL($numsql); - } - - function ExpensiveSQL($numsql=10) - { - return perfmon_parent_ADOConnection::_ExpensiveSQL($numsql); - } - - - /* - This reports the percentage of load on the instance due to the most - expensive few SQL statements. Tuning these statements can often - make huge improvements in overall system performance. - */ - function _ExpensiveSQL($numsql = 10) - { - global $ADODB_FETCH_MODE; - $perf_table = perfmon_parent_ADOConnection::table(); - - $saveE = $this->LogSQL(false); - - if (isset($_GET['expe']) && isset($_GET['sql'])) - { - $partial = !empty($_GET['part']); - echo "\n<a name=\"explain\"></a>" . $this->Explain($_GET['sql'], $partial) . "\n"; - } - - if (isset($_GET['sql'])) return; - - $sql1 = $this->sql1; - $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - - $rs =& $this->SelectLimit( - "select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer - from $perf_table - where {$this->upperCase}({$this->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT') - and (tracer is null or tracer not like 'ERROR:%') - group by sql1 - having count(*)>1 - order by 1 desc" - ,$numsql - ); - - $this->LogSQL($saveE); - $ADODB_FETCH_MODE = $save; - - if (!$rs) return "<p>$this->helpurl. " . $this->ErrorMsg() . "</p>\n"; - $s = "\n<h3>Expensive SQL</h3>\n<span style=\"font-size: 8pt;\">Tuning the following SQL could reduce the server load substantially</span><br />\n<table style=\"border: 2px groove #000000;\">\n<tr>\n<td><strong>Load</strong></td>\n<td><strong>Count</strong></td>\n<td><strong>SQL</strong></td>\n<td><strong>Max</strong></td>\n<td><strong>Min</strong></td>\n</tr>\n"; - - $max = $this->maxLength; - while (!$rs->EOF) - { - $sql = $rs->fields[1]; - $raw = urlencode($sql); - if (strlen($raw)>$max-100) - { - $sql2 = substr($sql,0,$max-500); - $raw = urlencode($sql2).'&part='.crc32($sql); - } - $prefix = "<a target=\"sqle" . rand() . "\" href=\"?hidem=1&expe=1&sql=" . $raw . "&x#explain\">"; - $suffix = "</a>\n"; - if($this->explain == false || strlen($prefix > $max)) - { - $prefix = ''; - $suffix = ''; - } - $s .= "\n<tr>\n<td>\n" - .adodb_round($rs->fields[0],6) - ."\n</td><td style='text-align: right;'>\n" - .$rs->fields[2] - ."\n</td>\n<td><span style=\"font-size: 10pt;\">" - .$prefix - .htmlentities($sql, ENT_QUOTES, 'UTF-8') - .$suffix - ."</span>" - ."\n</td><td>" - .$rs->fields[3] - ."\n</td><td>" - .$rs->fields[4] - ."\n</tr>"; - $rs->MoveNext(); - } - return $s."\n</table>\n"; - } - - /* - Raw function to return parameter value from $settings. - */ - function DBParameter($param) - { - if (empty($this->settings[$param])) return false; - $sql = $this->settings[$param][1]; - return $this->_DBParameter($sql); - } - - /* - Raw function returning array of poll paramters - */ - function &PollParameters() - { - $arr[0] = (float)$this->DBParameter('data cache hit ratio'); - $arr[1] = (float)$this->DBParameter('data reads'); - $arr[2] = (float)$this->DBParameter('data writes'); - $arr[3] = (integer) $this->DBParameter('current connections'); - return $arr; - } - - /* - Low-level Get Database Parameter - */ - function _DBParameter($sql) - { - $savelog = $this->LogSQL(false); - if (is_array($sql)) - { - global $ADODB_FETCH_MODE; - - $sql1 = $sql[0]; - $key = $sql[1]; - if (sizeof($sql)>2) $pos = $sql[2]; - else $pos = 1; - if (sizeof($sql)>3) $coef = $sql[3]; - else $coef = false; - $ret = false; - $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - - $rs = $this->Execute($sql1); - - $ADODB_FETCH_MODE = $save; - if($rs) - { - while (!$rs->EOF) - { - $keyf = reset($rs->fields); - if (trim($keyf) == $key) - { - $ret = $rs->fields[$pos]; - if ($coef) $ret *= $coef; - break; - } - $rs->MoveNext(); - } - $rs->Close(); - } - $this->LogSQL($savelog); - return $ret; - } - else - { - if (strncmp($sql,'=',1) == 0) - { - $fn = substr($sql,1); - return $this->$fn(); - } - $sql = str_replace('$DATABASE',$this->database,$sql); - $ret = $this->GetOne($sql); - $this->LogSQL($savelog); - - return $ret; - } - } - - /* - Warn if cache ratio falls below threshold. Displayed in "Description" column. - */ - function WarnCacheRatio($val) - { - if ($val < $this->warnRatio) - return '<span style="color: red;"><strong>Cache ratio should be at least '.$this->warnRatio.'%</strong></span>'; - else return ''; - } - - /***********************************************************************************************/ - // HIGH LEVEL UI FUNCTIONS - /***********************************************************************************************/ - - - function UI($pollsecs=5) - { - - $perf_table = perfmon_parent_ADOConnection::table(); - - $app = $this->host; - if ($this->host && $this->database) $app .= ', db='; - $app .= $this->database; - - if ($app) $app .= ', '; - $savelog = $this->LogSQL(false); - $info = $this->ServerInfo(); - if(isset($_GET['clearsql'])) - { - $this->Execute("delete from $perf_table"); - } - $this->LogSQL($savelog); - - // magic quotes - - if (isset($_GET['sql']) && get_magic_quotes_gpc()) - { - $_GET['sql'] = $_GET['sql'] = str_replace(array("\\'",'\"'),array("'",'"'),$_GET['sql']); - } - - if (!isset($_SESSION['ADODB_PERF_SQL'])) $nsql = $_SESSION['ADODB_PERF_SQL'] = 10; - else $nsql = $_SESSION['ADODB_PERF_SQL']; - - $app .= $info['description']; - - if(isset($_GET['do'])) - { - $do = $_GET['do']; - } - else if (isset($_POST['do'])) $do = $_POST['do']; - else if (isset($_GET['sql'])) $do = 'viewsql'; - else $do = 'stats'; - - if (isset($_GET['nsql'])) - { - if ($_GET['nsql'] > 0) $nsql = $_SESSION['ADODB_PERF_SQL'] = (integer) $_GET['nsql']; - } - - // page header - echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> - <html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\"> - <head> - <title>ADOdb-Lite Performance Monitor on $app</title> - <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" /> - <style type=\"text/css\"> - /*<![CDATA[*/ - body { background-color: #FFFFFF; font-size: 10pt; color: #000000; } - td { padding: 0px 3px 0px 3px; } - table { border: 2px groove #000000; } - /*]]>*/ - </style> - </head> - <body> - "; - - if ($do == 'viewsql') - { - $form = "\n<form method=\"post\" action=\"". $_SERVER['PHP_SELF'] ."\"># SQL:<input type=\"hidden\" value=\"viewsql\" name=\"do\" /> <input type=\"text\" size=\"4\" name=\"nsql\" value=\"$nsql\" /><input type=\"submit\" value=\"Go\" /></form>"; - } - else - { - $form = " "; - } - - $allowsql = !defined('ADODB_PERF_NO_RUN_SQL'); - - if(empty($_GET['hidem'])) - { - echo "\n<table style=\"width: 100%; background-color: lightyellow;\">\n<tr>\n<td colspan='2'>\n<strong><a href=\"http://adodb.sourceforge.net/?perf=1\">ADOdb-Lite</a> Performance Monitor</strong> <span style=\"font-size: 8pt;\">for $app</span>\n</td>\n</tr>\n<tr>\n<td>\n<a href=\"?do=stats\"><strong>Performance Stats</strong></a> <a href=\"?do=viewsql\"><strong>View SQL</strong></a> <a href=\"?do=tables\"><strong>View Tables</strong></a> <a href=\"?do=poll\"><strong>Poll Stats</strong></a>", - $allowsql ? ' <a href="?do=dosql"><strong>Run SQL</strong></a></td>' : '</td>', - "\n<td>$form\n</td>", - "\n</tr>\n</table>\n"; - } - - switch ($do) - { - case 'stats': - echo $this->HealthCheck(); - echo $this->CheckMemory(); - break; - - case 'poll': - echo "<iframe width=\"720\" height=\"80%\" - src=\"{$_SERVER['PHP_SELF']}?do=poll2&hidem=1\"></iframe>"; - break; - - case 'poll2': - echo "<pre>"; - $this->Poll($pollsecs); - echo "</pre>"; - break; - - case 'dosql': - if (!$allowsql) break; - $this->DoSQLForm(); - break; - - case 'viewsql': - if (empty($_GET['hidem'])) - { - echo " <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br />"; - } - echo($this->SuspiciousSQL($nsql)); - echo($this->ExpensiveSQL($nsql)); - echo($this->InvalidSQL($nsql)); - break; - - case 'tables': - echo $this->Tables(); - break; - - default: - echo $this->HealthCheck(); - echo $this->CheckMemory(); - break; - } - global $ADODB_vers; - echo "<div align=\"center\"><span style=\"font-size: 8pt;\">$ADODB_vers</span></div>"; - } - - /* - Runs in infinite loop, returning real-time statistics - */ - function Poll($secs=5) - { - //$saveE = $this->LogSQL(false); // but how to re-enable? - - if ($secs <= 1) $secs = 1; - echo "Accumulating statistics, every $secs seconds...\n"; flush(); - $arro =& $this->PollParameters(); - $cnt = 0; - set_time_limit(0); - sleep($secs); - while (1) { - - $arr =& $this->PollParameters(); - - $hits = sprintf('%2.2f',$arr[0]); - $reads = sprintf('%12.4f',($arr[1]-$arro[1])/$secs); - $writes = sprintf('%12.4f',($arr[2]-$arro[2])/$secs); - $sess = sprintf('%5d',$arr[3]); - - $load = $this->CPULoad(); - if ($load !== false) - { - $oslabel = 'WS-CPU%'; - $osval = sprintf(" %2.1f ",(float) $load); - } - else - { - $oslabel = ''; - $osval = ''; - } - if ($cnt % 10 == 0) echo " Time ".$oslabel." Hit% Sess Reads/s Writes/s\n"; - $cnt += 1; - echo date('H:i:s').' '.$osval."$hits $sess $reads $writes\n"; - flush(); - - if (connection_aborted()) return; - - sleep($secs); - $arro = $arr; - } - } - - /* - Returns basic health check in a command line interface - */ - function HealthCheckCLI() - { - return $this->HealthCheck(true); - } - - - /* - Returns basic health check as HTML - */ - function HealthCheck($cli=false) - { - $saveE = $this->LogSQL(false); - if ($cli) $html = ''; - else $html = $this->table.'<tr><td colspan="3"><h3>'.$this->dbtype.'</h3></td></tr>'.$this->titles; - - foreach($this->settings as $name => $arr) - { - if ($arr === false) break; - - if (!is_string($name)) - { - if ($cli) $html .= " -- $arr -- \n"; - else $html .= "<tr style=\"background-color: $this->color;\"><td colspan=\"3\"><em>$arr</em> </td></tr>"; - continue; - } - - if (!is_array($arr)) break; - $category = $arr[0]; - $how = $arr[1]; - if (sizeof($arr)>2) $desc = $arr[2]; - else $desc = ' '; - - - if ($category == 'HIDE') continue; - - $val = $this->_DBParameter($how); - - if ($desc && strncmp($desc,"=",1) === 0) - { - $fn = substr($desc,1); - $desc = $this->$fn($val); - } - - if ($val === false) - { - $m = $this->ErrorMsg(); - $val = "Error: $m"; - } - else - { - if (is_numeric($val) && $val >= 256*1024) - { - if ($val % (1024*1024) == 0) - { - $val /= (1024*1024); - $val .= 'M'; - } - else if ($val % 1024 == 0) - { - $val /= 1024; - $val .= 'K'; - } - } - } - if ($category != $oldc) - { - $oldc = $category; - } - if (strlen($desc)==0) $desc = ' '; - if (strlen($val)==0) $val = ' '; - if ($cli) - { - $html .= str_replace(' ','',sprintf($this->cliFormat,strip_tags($name),strip_tags($val),strip_tags($desc))); - } - else - { - $html .= "<tr><td>".$name.'</td><td>'.$val.'</td><td>'.$desc."</td></tr>\n"; - } - } - - if (!$cli) $html .= "</table>\n"; - $this->LogSQL($saveE); - - return $html; - } - - function Tables($orderby='1') - { - if (!$this->tablesSQL) return false; - - $savelog = $this->LogSQL(false); - $rs = $this->Execute($this->tablesSQL.' order by '.$orderby); - $this->LogSQL($savelog); - $html = rs2html($rs,false,false,false,false); - return $html; - } - - - function CreateLogTable() - { - if (!$this->createTableSQL) return false; - - $savelog = $this->LogSQL(false); - $ok = $this->Execute($this->createTableSQL); - $this->LogSQL($savelog); - return ($ok) ? true : false; - } - - function DoSQLForm() - { - $PHP_SELF = $_SERVER['PHP_SELF']; - $sql = isset($_REQUEST['sql']) ? $_REQUEST['sql'] : ''; // Let the form spoofing commence... *** - - if (isset($_SESSION['phplens_sqlrows'])) $rows = $_SESSION['phplens_sqlrows']; - else $rows = 3; - - if (isset($_REQUEST['SMALLER'])) { - $rows /= 2; - if ($rows < 3) $rows = 3; - $_SESSION['phplens_sqlrows'] = $rows; - } - if (isset($_REQUEST['BIGGER'])) { - $rows *= 2; - $_SESSION['phplens_sqlrows'] = $rows; - } - -?> - -<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"> -<table><tr> -<td> Form size: <input type="submit" value=" < " name="SMALLER" /><input type="submit" value=" > > " name="BIGGER" /> -</td> -<td align=right> -<input type="submit" value=" Run SQL Below " name="RUN" /><input type="hidden" name="do" value="dosql" /> -</td></tr> - <tr> - <td colspan="2"><textarea rows="<?php print $rows; ?>" name="sql" cols="80"><?php print htmlentities($sql, ENT_QUOTES, 'UTF-8'); ?></textarea> - </td> - </tr> - </table> -</form> - -<?php - if (!isset($_REQUEST['sql'])) return; - - $sql = $this->undomq(trim($sql)); - if (substr($sql,strlen($sql)-1) === ';') - { - $print = true; - $sqla = $this->SplitSQL($sql); - } - else - { - $print = false; - $sqla = array($sql); - } - foreach($sqla as $sqls) { - - if (!$sqls) continue; - - if ($print) { - print "<p>".htmlentities($sqls, ENT_QUOTES, 'UTF-8')."</p>"; - flush(); - } - $savelog = $this->LogSQL(false); - $rs = $this->Execute($sqls); - $this->LogSQL($savelog); - if ($rs && is_object($rs) && !$rs->EOF) - { - rs2html($rs); - while ($rs->NextRecordSet()) - { - print "<table style=\"width: 98%; background-color: #C0C0FF;\"><tr><td> </td></tr></table>"; - rs2html($rs); - } - } - else - { - $e1 = (integer) $this->ErrorNo(); - $e2 = $this->ErrorMsg(); - if (($e1) || ($e2)) - { - if (empty($e1)) $e1 = '-1'; // postgresql fix - print ' '.$e1.': '.$e2; - } - else - { - print "<p>No Recordset returned<br /></p>"; - } - } - } // foreach - } - - function SplitSQL($sql) - { - $arr = explode(';',$sql); - return $arr; - } - - function undomq(&$m) - { - if (get_magic_quotes_gpc()) { - // undo the damage - $m = str_replace('\\\\','\\',$m); - $m = str_replace('\"','"',$m); - $m = str_replace('\\\'','\'',$m); - } - return $m; - } - - - /************************************************************************/ - - /** - * Reorganise multiple table-indices/statistics/.. - * OptimizeMode could be given by last Parameter - * - * @example - * <pre> - * optimizeTables( 'tableA'); - * </pre> - * <pre> - * optimizeTables( 'tableA', 'tableB', 'tableC'); - * </pre> - * <pre> - * optimizeTables( 'tableA', 'tableB', ADODB_OPT_LOW); - * </pre> - * - * @param string table name of the table to optimize - * @param int mode optimization-mode - * <code>ADODB_OPT_HIGH</code> for full optimization - * <code>ADODB_OPT_LOW</code> for CPU-less optimization - * Default is LOW <code>ADODB_OPT_LOW</code> - * @author Markus Staab - * @return Returns <code>true</code> on success and <code>false</code> on error - */ - function OptimizeTables() - { - $args = func_get_args(); - $numArgs = func_num_args(); - - if ( $numArgs == 0) return false; - - $mode = ADODB_OPT_LOW; - $lastArg = $args[ $numArgs - 1]; - if ( !is_string($lastArg)) - { - $mode = $lastArg; - unset( $args[ $numArgs - 1]); - } - - foreach( $args as $table) - { - $this->optimizeTable( $table, $mode); - } - } - - /** - * Reorganise the table-indices/statistics/.. depending on the given mode. - * Default Implementation throws an error. - * - * @param string table name of the table to optimize - * @param int mode optimization-mode - * <code>ADODB_OPT_HIGH</code> for full optimization - * <code>ADODB_OPT_LOW</code> for CPU-less optimization - * Default is LOW <code>ADODB_OPT_LOW</code> - * @author Markus Staab - * @return Returns <code>true</code> on success and <code>false</code> on error - */ - function OptimizeTable( $table, $mode = ADODB_OPT_LOW) - { - $this->outp( sprintf( "<p>%s: '%s' not implemented for driver '%s'</p>", __CLASS__, __FUNCTION__, $this->dbtype)); - return false; - } - - /** - * Reorganise current database. - * Default implementation loops over all <code>MetaTables()</code> and - * optimize each using <code>optmizeTable()</code> - * - * Non-functional in ADOdb-Lite due to lack of MetaTables() implementation in default modules - * - * @author Markus Staab - * @return Returns <code>true</code> on success and <code>false</code> on error - */ - function optimizeDatabase() - { - //$tables = $this->MetaTables( 'TABLES'); // non-functional without a MetaTables method in ADOdb-Lite... - if ( !$tables ) return false; - - foreach( $tables as $table) - { - if (!$this->optimizeTable( $table)) - { - return false; - } - } - return true; - } - -} - -?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cal...@us...> - 2007-07-31 00:56:32
|
Revision: 67 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=67&view=rev Author: caleb870 Date: 2007-07-30 17:56:34 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-time.inc.php Removed Paths: ------------- trunk/functions/adodb-time.inc.php Copied: trunk/functions/adodb/adodb-time.inc.php (from rev 66, trunk/functions/adodb-time.inc.php) =================================================================== --- trunk/functions/adodb/adodb-time.inc.php (rev 0) +++ trunk/functions/adodb/adodb-time.inc.php 2007-07-31 00:56:34 UTC (rev 67) @@ -0,0 +1,1313 @@ +<?php +/** +ADOdb Date Library, part of the ADOdb abstraction library +Download: http://phplens.com/phpeverywhere/ + +PHP native date functions use integer timestamps for computations. +Because of this, dates are restricted to the years 1901-2038 on Unix +and 1970-2038 on Windows due to integer overflow for dates beyond +those years. This library overcomes these limitations by replacing the +native function's signed integers (normally 32-bits) with PHP floating +point numbers (normally 64-bits). + +Dates from 100 A.D. to 3000 A.D. and later +have been tested. The minimum is 100 A.D. as <100 will invoke the +2 => 4 digit year conversion. The maximum is billions of years in the +future, but this is a theoretical limit as the computation of that year +would take too long with the current implementation of adodb_mktime(). + +This library replaces native functions as follows: + +<pre> + getdate() with adodb_getdate() + date() with adodb_date() + gmdate() with adodb_gmdate() + mktime() with adodb_mktime() + gmmktime() with adodb_gmmktime() + strftime() with adodb_strftime() + strftime() with adodb_gmstrftime() +</pre> + +The parameters are identical, except that adodb_date() accepts a subset +of date()'s field formats. Mktime() will convert from local time to GMT, +and date() will convert from GMT to local time, but daylight savings is +not handled currently. + +This library is independant of the rest of ADOdb, and can be used +as standalone code. + +PERFORMANCE + +For high speed, this library uses the native date functions where +possible, and only switches to PHP code when the dates fall outside +the 32-bit signed integer range. + +GREGORIAN CORRECTION + +Pope Gregory shortened October of A.D. 1582 by ten days. Thursday, +October 4, 1582 (Julian) was followed immediately by Friday, October 15, +1582 (Gregorian). + +Since 0.06, we handle this correctly, so: + +adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582) + == 24 * 3600 (1 day) + +============================================================================= + +COPYRIGHT + +(c) 2003-2005 John Lim and released under BSD-style license except for code by +jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year +and originally found at http://www.php.net/manual/en/function.mktime.php + +============================================================================= + +BUG REPORTS + +These should be posted to the ADOdb forums at + + http://phplens.com/lens/lensforum/topics.php?id=4 + +============================================================================= + +FUNCTION DESCRIPTIONS + + +** FUNCTION adodb_getdate($date=false) + +Returns an array containing date information, as getdate(), but supports +dates greater than 1901 to 2038. The local date/time format is derived from a +heuristic the first time adodb_getdate is called. + + +** FUNCTION adodb_date($fmt, $timestamp = false) + +Convert a timestamp to a formatted local date. If $timestamp is not defined, the +current timestamp is used. Unlike the function date(), it supports dates +outside the 1901 to 2038 range. + +The format fields that adodb_date supports: + +<pre> + a - "am" or "pm" + A - "AM" or "PM" + d - day of the month, 2 digits with leading zeros; i.e. "01" to "31" + D - day of the week, textual, 3 letters; e.g. "Fri" + F - month, textual, long; e.g. "January" + g - hour, 12-hour format without leading zeros; i.e. "1" to "12" + G - hour, 24-hour format without leading zeros; i.e. "0" to "23" + h - hour, 12-hour format; i.e. "01" to "12" + H - hour, 24-hour format; i.e. "00" to "23" + i - minutes; i.e. "00" to "59" + j - day of the month without leading zeros; i.e. "1" to "31" + l (lowercase 'L') - day of the week, textual, long; e.g. "Friday" + L - boolean for whether it is a leap year; i.e. "0" or "1" + m - month; i.e. "01" to "12" + M - month, textual, 3 letters; e.g. "Jan" + n - month without leading zeros; i.e. "1" to "12" + O - Difference to Greenwich time in hours; e.g. "+0200" + Q - Quarter, as in 1, 2, 3, 4 + r - RFC 822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200" + s - seconds; i.e. "00" to "59" + S - English ordinal suffix for the day of the month, 2 characters; + i.e. "st", "nd", "rd" or "th" + t - number of days in the given month; i.e. "28" to "31" + T - Timezone setting of this machine; e.g. "EST" or "MDT" + U - seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) + w - day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday) + Y - year, 4 digits; e.g. "1999" + y - year, 2 digits; e.g. "99" + z - day of the year; i.e. "0" to "365" + Z - timezone offset in seconds (i.e. "-43200" to "43200"). + The offset for timezones west of UTC is always negative, + and for those east of UTC is always positive. +</pre> + +Unsupported: +<pre> + B - Swatch Internet time + I (capital i) - "1" if Daylight Savings Time, "0" otherwise. + W - ISO-8601 week number of year, weeks starting on Monday + +</pre> + + +** FUNCTION adodb_date2($fmt, $isoDateString = false) +Same as adodb_date, but 2nd parameter accepts iso date, eg. + + adodb_date2('d-M-Y H:i','2003-12-25 13:01:34'); + + +** FUNCTION adodb_gmdate($fmt, $timestamp = false) + +Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the +current timestamp is used. Unlike the function date(), it supports dates +outside the 1901 to 2038 range. + + +** FUNCTION adodb_mktime($hr, $min, $sec[, $month, $day, $year]) + +Converts a local date to a unix timestamp. Unlike the function mktime(), it supports +dates outside the 1901 to 2038 range. All parameters are optional. + + +** FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year]) + +Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports +dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters +are currently compulsory. + +** FUNCTION adodb_gmstrftime($fmt, $timestamp = false) +Convert a timestamp to a formatted GMT date. + +** FUNCTION adodb_strftime($fmt, $timestamp = false) + +Convert a timestamp to a formatted local date. Internally converts $fmt into +adodb_date format, then echo result. + +For best results, you can define the local date format yourself. Define a global +variable $ADODB_DATE_LOCALE which is an array, 1st element is date format using +adodb_date syntax, and 2nd element is the time format, also in adodb_date syntax. + + eg. $ADODB_DATE_LOCALE = array('d/m/Y','H:i:s'); + + Supported format codes: + +<pre> + %a - abbreviated weekday name according to the current locale + %A - full weekday name according to the current locale + %b - abbreviated month name according to the current locale + %B - full month name according to the current locale + %c - preferred date and time representation for the current locale + %d - day of the month as a decimal number (range 01 to 31) + %D - same as %m/%d/%y + %e - day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31') + %h - same as %b + %H - hour as a decimal number using a 24-hour clock (range 00 to 23) + %I - hour as a decimal number using a 12-hour clock (range 01 to 12) + %m - month as a decimal number (range 01 to 12) + %M - minute as a decimal number + %n - newline character + %p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale + %r - time in a.m. and p.m. notation + %R - time in 24 hour notation + %S - second as a decimal number + %t - tab character + %T - current time, equal to %H:%M:%S + %x - preferred date representation for the current locale without the time + %X - preferred time representation for the current locale without the date + %y - year as a decimal number without a century (range 00 to 99) + %Y - year as a decimal number including the century + %Z - time zone or name or abbreviation + %% - a literal `%' character +</pre> + + Unsupported codes: +<pre> + %C - century number (the year divided by 100 and truncated to an integer, range 00 to 99) + %g - like %G, but without the century. + %G - The 4-digit year corresponding to the ISO week number (see %V). + This has the same format and value as %Y, except that if the ISO week number belongs + to the previous or next year, that year is used instead. + %j - day of the year as a decimal number (range 001 to 366) + %u - weekday as a decimal number [1,7], with 1 representing Monday + %U - week number of the current year as a decimal number, starting + with the first Sunday as the first day of the first week + %V - The ISO 8601:1988 week number of the current year as a decimal number, + range 01 to 53, where week 1 is the first week that has at least 4 days in the + current year, and with Monday as the first day of the week. (Use %G or %g for + the year component that corresponds to the week number for the specified timestamp.) + %w - day of the week as a decimal, Sunday being 0 + %W - week number of the current year as a decimal number, starting with the + first Monday as the first day of the first week +</pre> + +============================================================================= + +NOTES + +Useful url for generating test timestamps: + http://www.4webhelp.net/us/timestamp.php + +Possible future optimizations include + +a. Using an algorithm similar to Plauger's in "The Standard C Library" +(page 428, xttotm.c _Ttotm() function). Plauger's algorithm will not +work outside 32-bit signed range, so i decided not to implement it. + +b. Implement daylight savings, which looks awfully complicated, see + http://webexhibits.org/daylightsaving/ + + +CHANGELOG +- 08 Sept 2005 0.22 +In adodb_date2(), $is_gmt not supported properly. Fixed. + +- 18 July 2005 0.21 +In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat. +Added support for negative months in adodb_mktime(). + +- 24 Feb 2005 0.20 +Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date(). + +- 21 Dec 2004 0.17 +In adodb_getdate(), the timestamp was accidentally converted to gmt when $is_gmt is false. +Also adodb_mktime(0,0,0) did not work properly. Both fixed thx Mauro. + +- 17 Nov 2004 0.16 +Removed intval typecast in adodb_mktime() for secs, allowing: + adodb_mktime(0,0,0 + 2236672153,1,1,1934); +Suggested by Ryan. + +- 18 July 2004 0.15 +All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory. +This brings it more in line with mktime (still not identical). + +- 23 June 2004 0.14 + +Allow you to define your own daylights savings function, adodb_daylight_sv. +If the function is defined (somewhere in an include), then you can correct for daylights savings. + +In this example, we apply daylights savings in June or July, adding one hour. This is extremely +unrealistic as it does not take into account time-zone, geographic location, current year. + +function adodb_daylight_sv(&$arr, $is_gmt) +{ + if ($is_gmt) return; + $m = $arr['mon']; + if ($m == 6 || $m == 7) $arr['hours'] += 1; +} + +This is only called by adodb_date() and not by adodb_mktime(). + +The format of $arr is +Array ( + [seconds] => 0 + [minutes] => 0 + [hours] => 0 + [mday] => 1 # day of month, eg 1st day of the month + [mon] => 2 # month (eg. Feb) + [year] => 2102 + [yday] => 31 # days in current year + [leap] => # true if leap year + [ndays] => 28 # no of days in current month + ) + + +- 28 Apr 2004 0.13 +Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov. + +- 20 Mar 2004 0.12 +Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32. + +- 26 Oct 2003 0.11 +Because of daylight savings problems (some systems apply daylight savings to +January!!!), changed adodb_get_gmt_diff() to ignore daylight savings. + +- 9 Aug 2003 0.10 +Fixed bug with dates after 2038. +See http://phplens.com/lens/lensforum/msgs.php?id=6980 + +- 1 July 2003 0.09 +Added support for Q (Quarter). +Added adodb_date2(), which accepts ISO date in 2nd param + +- 3 March 2003 0.08 +Added support for 'S' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS +if you want PHP to handle negative timestamps between 1901 to 1969. + +- 27 Feb 2003 0.07 +All negative numbers handled by adodb now because of RH 7.3+ problems. +See http://bugs.php.net/bug.php?id=20048&edit=2 + +- 4 Feb 2003 0.06 +Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates +are now correctly handled. + +- 29 Jan 2003 0.05 + +Leap year checking differs under Julian calendar (pre 1582). Also +leap year code optimized by checking for most common case first. + +We also handle month overflow correctly in mktime (eg month set to 13). + +Day overflow for less than one month's days is supported. + +- 28 Jan 2003 0.04 + +Gregorian correction handled. In PHP5, we might throw an error if +mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10. +Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582. + +- 27 Jan 2003 0.03 + +Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION. +Fixed calculation of days since start of year for <1970. + +- 27 Jan 2003 0.02 + +Changed _adodb_getdate() to inline leap year checking for better performance. +Fixed problem with time-zones west of GMT +0000. + +- 24 Jan 2003 0.01 + +First implementation. +*/ + + +/* Initialization */ + +/* + Version Number +*/ +define('ADODB_DATE_VERSION',0.22); + +/* + This code was originally for windows. But apparently this problem happens + also with Linux, RH 7.3 and later! + + glibc-2.2.5-34 and greater has been changed to return -1 for dates < + 1970. This used to work. The problem exists with RedHat 7.3 and 8.0 + echo (mktime(0, 0, 0, 1, 1, 1960)); // prints -1 + + References: + http://bugs.php.net/bug.php?id=20048&edit=2 + http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html +*/ + +if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1); + +function adodb_date_test_date($y1,$m,$d=13) +{ + $t = adodb_mktime(0,0,0,$m,$d,$y1); + $rez = adodb_date('Y-n-j H:i:s',$t); + if ("$y1-$m-$d 00:00:00" != $rez) { + print "<b>$y1 error, expected=$y1-$m-$d 00:00:00, adodb=$rez</b><br>"; + return false; + } + return true; +} + +function adodb_date_test_strftime($fmt) +{ + $s1 = strftime($fmt); + $s2 = adodb_strftime($fmt); + + if ($s1 == $s2) return true; + + echo "error for $fmt, strftime=$s1, $adodb=$s2<br>"; + return false; +} + +/** + Test Suite +*/ +function adodb_date_test() +{ + + error_reporting(E_ALL); + print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."</h4>"; + @set_time_limit(0); + $fail = false; + + // This flag disables calling of PHP native functions, so we can properly test the code + if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1); + + adodb_date_test_strftime('%Y %m %x %X'); + adodb_date_test_strftime("%A %d %B %Y"); + adodb_date_test_strftime("%H %M S"); + + $t = adodb_mktime(0,0,0); + if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>'; + + $t = adodb_mktime(0,0,0,6,1,2102); + if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>'; + + $t = adodb_mktime(0,0,0,2,1,2102); + if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>'; + + + print "<p>Testing gregorian <=> julian conversion<p>"; + $t = adodb_mktime(0,0,0,10,11,1492); + //http://www.holidayorigins.com/html/columbus_day.html - Friday check + if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing<br>'; + + $t = adodb_mktime(0,0,0,2,29,1500); + if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years<br>'; + + $t = adodb_mktime(0,0,0,2,29,1700); + if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years<br>'; + + print adodb_mktime(0,0,0,10,4,1582).' '; + print adodb_mktime(0,0,0,10,15,1582); + $diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)); + if ($diff != 3600*24) print " <b>Error in gregorian correction = ".($diff/3600/24)." days </b><br>"; + + print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : '<b>Error</b>')."<br>"; + print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : '<b>Error</b>')."<br>"; + + print "<p>Testing overflow<p>"; + + $t = adodb_mktime(0,0,0,3,33,1965); + if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1 <br>'; + $t = adodb_mktime(0,0,0,4,33,1971); + if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2 <br>'; + $t = adodb_mktime(0,0,0,1,60,1965); + if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).' <br>'; + $t = adodb_mktime(0,0,0,12,32,1965); + if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).' <br>'; + $t = adodb_mktime(0,0,0,12,63,1965); + if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).' <br>'; + $t = adodb_mktime(0,0,0,13,3,1965); + if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1 <br>'; + + print "Testing 2-digit => 4-digit year conversion<p>"; + if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000<br>"; + if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010<br>"; + if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020<br>"; + if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030<br>"; + if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940<br>"; + if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>"; + if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>"; + + // Test string formating + print "<p>Testing date formating</p>"; + $fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C822 r s t U w y Y z Z 2003'; + $s1 = date($fmt,0); + $s2 = adodb_date($fmt,0); + if ($s1 != $s2) { + print " date() 0 failed<br>$s1<br>$s2<br>"; + } + flush(); + for ($i=100; --$i > 0; ) { + + $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000); + $s1 = date($fmt,$ts); + $s2 = adodb_date($fmt,$ts); + //print "$s1 <br>$s2 <p>"; + $pos = strcmp($s1,$s2); + + if (($s1) != ($s2)) { + for ($j=0,$k=strlen($s1); $j < $k; $j++) { + if ($s1[$j] != $s2[$j]) { + print substr($s1,$j).' '; + break; + } + } + print "<b>Error date(): $ts<br><pre> + \"$s1\" (date len=".strlen($s1).") + \"$s2\" (adodb_date len=".strlen($s2).")</b></pre><br>"; + $fail = true; + } + + $a1 = getdate($ts); + $a2 = adodb_getdate($ts); + $rez = array_diff($a1,$a2); + if (sizeof($rez)>0) { + print "<b>Error getdate() $ts</b><br>"; + print_r($a1); + print "<br>"; + print_r($a2); + print "<p>"; + $fail = true; + } + } + + // Test generation of dates outside 1901-2038 + print "<p>Testing random dates between 100 and 4000</p>"; + adodb_date_test_date(100,1); + for ($i=100; --$i >= 0;) { + $y1 = 100+rand(0,1970-100); + $m = rand(1,12); + adodb_date_test_date($y1,$m); + + $y1 = 3000-rand(0,3000-1970); + adodb_date_test_date($y1,$m); + } + print '<p>'; + $start = 1960+rand(0,10); + $yrs = 12; + $i = 365.25*86400*($start-1970); + $offset = 36000+rand(10000,60000); + $max = 365*$yrs*86400; + $lastyear = 0; + + // we generate a timestamp, convert it to a date, and convert it back to a timestamp + // and check if the roundtrip broke the original timestamp value. + print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: "; + $cnt = 0; + for ($max += $i; $i < $max; $i += $offset) { + $ret = adodb_date('m,d,Y,H,i,s',$i); + $arr = explode(',',$ret); + if ($lastyear != $arr[2]) { + $lastyear = $arr[2]; + print " $lastyear "; + flush(); + } + $newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]); + if ($i != $newi) { + print "Error at $i, adodb_mktime returned $newi ($ret)"; + $fail = true; + break; + } + $cnt += 1; + } + echo "Tested $cnt dates<br>"; + if (!$fail) print "<p>Passed !</p>"; + else print "<p><b>Failed</b> :-(</p>"; +} + +/** + Returns day of week, 0 = Sunday,... 6=Saturday. + Algorithm from PEAR::Date_Calc +*/ +function adodb_dow($year, $month, $day) +{ +/* +Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and +proclaimed that from that time onwards 3 days would be dropped from the calendar +every 400 years. + +Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). +*/ + if ($year <= 1582) { + if ($year < 1582 || + ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3; + else + $greg_correction = 0; + } else + $greg_correction = 0; + + if($month > 2) + $month -= 2; + else { + $month += 10; + $year--; + } + + $day = floor((13 * $month - 1) / 5) + + $day + ($year % 100) + + floor(($year % 100) / 4) + + floor(($year / 100) / 4) - 2 * + floor($year / 100) + 77 + $greg_correction; + + return $day - 7 * floor($day / 7); +} + + +/** + Checks for leap year, returns true if it is. No 2-digit year check. Also + handles julian calendar correctly. +*/ +function _adodb_is_leap_year($year) +{ + if ($year % 4 != 0) return false; + + if ($year % 400 == 0) { + return true; + // if gregorian calendar (>1582), century not-divisible by 400 is not leap + } else if ($year > 1582 && $year % 100 == 0 ) { + return false; + } + + return true; +} + + +/** + checks for leap year, returns true if it is. Has 2-digit year check +*/ +function adodb_is_leap_year($year) +{ + return _adodb_is_leap_year(adodb_year_digit_check($year)); +} + +/** + Fix 2-digit years. Works for any century. + Assumes that if 2-digit is more than 30 years in future, then previous century. +*/ +function adodb_year_digit_check($y) +{ + if ($y < 100) { + + $yr = (integer) date("Y"); + $century = (integer) ($yr /100); + + if ($yr%100 > 50) { + $c1 = $century + 1; + $c0 = $century; + } else { + $c1 = $century; + $c0 = $century - 1; + } + $c1 *= 100; + // if 2-digit year is less than 30 years in future, set it to this century + // otherwise if more than 30 years in future, then we set 2-digit year to the prev century. + if (($y + $c1) < $yr+30) $y = $y + $c1; + else $y = $y + $c0*100; + } + return $y; +} + +/** + get local time zone offset from GMT +*/ +function adodb_get_gmt_diff() +{ +static $TZ; + if (isset($TZ)) return $TZ; + + $TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0); + return $TZ; +} + +/** + Returns an array with date info. +*/ +function adodb_getdate($d=false,$fast=false) +{ + if ($d === false) return getdate(); + if (!defined('ADODB_TEST_DATES')) { + if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range + if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer + return @getdate($d); + } + } + return _adodb_getdate($d); +} + +/* +// generate $YRS table for _adodb_getdate() +function adodb_date_gentable($out=true) +{ + + for ($i=1970; $i >= 1600; $i-=10) { + $s = adodb_gmmktime(0,0,0,1,1,$i); + echo "$i => $s,<br>"; + } +} +adodb_date_gentable(); + +for ($i=1970; $i > 1500; $i--) { + +echo "<hr>$i "; + adodb_date_test_date($i,1,1); +} + +*/ + + +$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); +$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); + +function adodb_validdate($y,$m,$d) +{ +global $_month_table_normal,$_month_table_leaf; + + if (_adodb_is_leap_year($y)) $marr =& $_month_table_leaf; + else $marr =& $_month_table_normal; + + if ($m > 12 || $m < 1) return false; + + if ($d > 31 || $d < 1) return false; + + if ($marr[$m] < $d) return false; + + if ($y < 1000 && $y > 3000) return false; + + return true; +} + +/** + Low-level function that returns the getdate() array. We have a special + $fast flag, which if set to true, will return fewer array values, + and is much faster as it does not calculate dow, etc. +*/ +function _adodb_getdate($origd=false,$fast=false,$is_gmt=false) +{ +static $YRS; +global $_month_table_normal,$_month_table_leaf; + + $d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff()); + + $_day_power = 86400; + $_hour_power = 3600; + $_min_power = 60; + + if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction + + $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); + $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); + + $d366 = $_day_power * 366; + $d365 = $_day_power * 365; + + if ($d < 0) { + + if (empty($YRS)) $YRS = array( + 1970 => 0, + 1960 => -315619200, + 1950 => -631152000, + 1940 => -946771200, + 1930 => -1262304000, + 1920 => -1577923200, + 1910 => -1893456000, + 1900 => -2208988800, + 1890 => -2524521600, + 1880 => -2840140800, + 1870 => -3155673600, + 1860 => -3471292800, + 1850 => -3786825600, + 1840 => -4102444800, + 1830 => -4417977600, + 1820 => -4733596800, + 1810 => -5049129600, + 1800 => -5364662400, + 1790 => -5680195200, + 1780 => -5995814400, + 1770 => -6311347200, + 1760 => -6626966400, + 1750 => -6942499200, + 1740 => -7258118400, + 1730 => -7573651200, + 1720 => -7889270400, + 1710 => -8204803200, + 1700 => -8520336000, + 1690 => -8835868800, + 1680 => -9151488000, + 1670 => -9467020800, + 1660 => -9782640000, + 1650 => -10098172800, + 1640 => -10413792000, + 1630 => -10729324800, + 1620 => -11044944000, + 1610 => -11360476800, + 1600 => -11676096000); + + if ($is_gmt) $origd = $d; + // The valid range of a 32bit signed timestamp is typically from + // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT + // + + # old algorithm iterates through all years. new algorithm does it in + # 10 year blocks + + /* + # old algo + for ($a = 1970 ; --$a >= 0;) { + $lastd = $d; + + if ($leaf = _adodb_is_leap_year($a)) $d += $d366; + else $d += $d365; + + if ($d >= 0) { + $year = $a; + break; + } + } + */ + + $lastsecs = 0; + $lastyear = 1970; + foreach($YRS as $year => $secs) { + if ($d >= $secs) { + $a = $lastyear; + break; + } + $lastsecs = $secs; + $lastyear = $year; + } + + $d -= $lastsecs; + if (!isset($a)) $a = $lastyear; + + //echo ' yr=',$a,' ', $d,'.'; + + for (; --$a >= 0;) { + $lastd = $d; + + if ($leaf = _adodb_is_leap_year($a)) $d += $d366; + else $d += $d365; + + if ($d >= 0) { + $year = $a; + break; + } + } + /**/ + + $secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd; + + $d = $lastd; + $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal; + for ($a = 13 ; --$a > 0;) { + $lastd = $d; + $d += $mtab[$a] * $_day_power; + if ($d >= 0) { + $month = $a; + $ndays = $mtab[$a]; + break; + } + } + + $d = $lastd; + $day = $ndays + ceil(($d+1) / ($_day_power)); + + $d += ($ndays - $day+1)* $_day_power; + $hour = floor($d/$_hour_power); + + } else { + for ($a = 1970 ;; $a++) { + $lastd = $d; + + if ($leaf = _adodb_is_leap_year($a)) $d -= $d366; + else $d -= $d365; + if ($d < 0) { + $year = $a; + break; + } + } + $secsInYear = $lastd; + $d = $lastd; + $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal; + for ($a = 1 ; $a <= 12; $a++) { + $lastd = $d; + $d -= $mtab[$a] * $_day_power; + if ($d < 0) { + $month = $a; + $ndays = $mtab[$a]; + break; + } + } + $d = $lastd; + $day = ceil(($d+1) / $_day_power); + $d = $d - ($day-1) * $_day_power; + $hour = floor($d /$_hour_power); + } + + $d -= $hour * $_hour_power; + $min = floor($d/$_min_power); + $secs = $d - $min * $_min_power; + if ($fast) { + return array( + 'seconds' => $secs, + 'minutes' => $min, + 'hours' => $hour, + 'mday' => $day, + 'mon' => $month, + 'year' => $year, + 'yday' => floor($secsInYear/$_day_power), + 'leap' => $leaf, + 'ndays' => $ndays + ); + } + + + $dow = adodb_dow($year,$month,$day); + + return array( + 'seconds' => $secs, + 'minutes' => $min, + 'hours' => $hour, + 'mday' => $day, + 'wday' => $dow, + 'mon' => $month, + 'year' => $year, + 'yday' => floor($secsInYear/$_day_power), + 'weekday' => gmdate('l',$_day_power*(3+$dow)), + 'month' => gmdate('F',mktime(0,0,0,$month,2,1971)), + 0 => $origd + ); +} + +function adodb_gmdate($fmt,$d=false) +{ + return adodb_date($fmt,$d,true); +} + +// accepts unix timestamp and iso date format in $d +function adodb_date2($fmt, $d=false, $is_gmt=false) +{ + if ($d !== false) { + if (!preg_match( + "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", + ($d), $rr)) return adodb_date($fmt,false,$is_gmt); + + if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt); + + // h-m-s-MM-DD-YY + if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1],false,$is_gmt); + else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1],false,$is_gmt); + } + + return adodb_date($fmt,$d,$is_gmt); +} + + +/** + Return formatted date based on timestamp $d +*/ +function adodb_date($fmt,$d=false,$is_gmt=false) +{ +static $daylight; + + if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt); + if (!defined('ADODB_TEST_DATES')) { + if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range + if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer + return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d); + + } + } + $_day_power = 86400; + + $arr = _adodb_getdate($d,true,$is_gmt); + + if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv'); + if ($daylight) adodb_daylight_sv($arr, $is_gmt); + + $year = $arr['year']; + $month = $arr['mon']; + $day = $arr['mday']; + $hour = $arr['hours']; + $min = $arr['minutes']; + $secs = $arr['seconds']; + + $max = strlen($fmt); + $dates = ''; + + /* + at this point, we have the following integer vars to manipulate: + $year, $month, $day, $hour, $min, $secs + */ + for ($i=0; $i < $max; $i++) { + switch($fmt[$i]) { + case 'T': $dates .= date('T');break; + // YEAR + case 'L': $dates .= $arr['leap'] ? '1' : '0'; break; + case 'r': // Thu, 21 Dec 2000 16:01:07 +0200 + + // 4.3.11 uses '04 Jun 2004' + // 4.3.8 uses ' 4 Jun 2004' + $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', ' + . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' '; + + if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour; + + if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min; + + if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs; + + $gmt = adodb_get_gmt_diff(); + $dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break; + + case 'Y': $dates .= $year; break; + case 'y': $dates .= substr($year,strlen($year)-2,2); break; + // MONTH + case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break; + case 'Q': $dates .= ($month+3)>>2; break; + case 'n': $dates .= $month; break; + case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break; + case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break; + // DAY + case 't': $dates .= $arr['ndays']; break; + case 'z': $dates .= $arr['yday']; break; + case 'w': $dates .= adodb_dow($year,$month,$day); break; + case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break; + case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break; + case 'j': $dates .= $day; break; + case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break; + case 'S': + $d10 = $day % 10; + if ($d10 == 1) $dates .= 'st'; + else if ($d10 == 2 && $day != 12) $dates .= 'nd'; + else if ($d10 == 3) $dates .= 'rd'; + else $dates .= 'th'; + break; + + // HOUR + case 'Z': + $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break; + case 'O': + $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff(); + $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break; + + case 'H': + if ($hour < 10) $dates .= '0'.$hour; + else $dates .= $hour; + break; + case 'h': + if ($hour > 12) $hh = $hour - 12; + else { + if ($hour == 0) $hh = '12'; + else $hh = $hour; + } + + if ($hh < 10) $dates .= '0'.$hh; + else $dates .= $hh; + break; + + case 'G': + $dates .= $hour; + break; + + case 'g': + if ($hour > 12) $hh = $hour - 12; + else { + if ($hour == 0) $hh = '12'; + else $hh = $hour; + } + $dates .= $hh; + break; + // MINUTES + case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break; + // SECONDS + case 'U': $dates .= $d; break; + case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break; + // AM/PM + // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM + case 'a': + if ($hour>=12) $dates .= 'pm'; + else $dates .= 'am'; + break; + case 'A': + if ($hour>=12) $dates .= 'PM'; + else $dates .= 'AM'; + break; + default: + $dates .= $fmt[$i]; break; + // ESCAPE + case "\\": + $i++; + if ($i < $max) $dates .= $fmt[$i]; + break; + } + } + return $dates; +} + +/** + Returns a timestamp given a GMT/UTC time. + Note that $is_dst is not implemented and is ignored. +*/ +function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false) +{ + return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true); +} + +/** + Return a timestamp given a local time. Originally by jackbbs. + Note that $is_dst is not implemented and is ignored. + + Not a very fast algorithm - O(n) operation. Could be optimized to O(1). +*/ +function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false) +{ + if (!defined('ADODB_TEST_DATES')) { + + if ($mon === false) { + return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec); + } + + // for windows, we don't check 1970 because with timezone differences, + // 1 Jan 1970 could generate negative timestamp, which is illegal + if (1971 < $year && $year < 2038 + || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038) + ) { + return $is_gmt ? + @gmmktime($hr,$min,$sec,$mon,$day,$year): + @mktime($hr,$min,$sec,$mon,$day,$year); + } + } + + $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff(); + + /* + # disabled because some people place large values in $sec. + # however we need it for $mon because we use an array... + $hr = intval($hr); + $min = intval($min); + $sec = intval($sec); + */ + $mon = intval($mon); + $day = intval($day); + $year = intval($year); + + + $year = adodb_year_digit_check($year); + + if ($mon > 12) { + $y = floor($mon / 12); + $year += $y; + $mon -= $y*12; + } + if ($mon < 1) { + $y = ceil((1-$mon) / 12); + $year -= $y; + $mon += $y*12; + } + + $_day_power = 86400; + $_hour_power = 3600; + $_min_power = 60; + + $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); + $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); + + $_total_date = 0; + if ($year >= 1970) { + for ($a = 1970 ; $a <= $year; $a++) { + $leaf = _adodb_is_leap_year($a); + if ($leaf == true) { + $loop_table = $_month_table_leaf; + $_add_date = 366; + } else { + $loop_table = $_month_table_normal; + $_add_date = 365; + } + if ($a < $year) { + $_total_date += $_add_date; + } else { + for($b=1;$b<$mon;$b++) { + $_total_date += $loop_table[$b]; + } + } + } + $_total_date +=$day-1; + $ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different; + + } else { + for ($a = 1969 ; $a >= $year; $a--) { + $leaf = _adodb_is_leap_year($a); + if ($leaf == true) { + $loop_table = $_month_table_leaf; + $_add_date = 366; + } else { + $loop_table = $_month_table_normal; + $_add_date = 365; + } + if ($a > $year) { $_total_date += $_add_date; + } else { + for($b=12;$b>$mon;$b--) { + $_total_date += $loop_table[$b]; + } + } + } + $_total_date += $loop_table[$mon] - $day; + + $_day_time = $hr * $_hour_power + $min * $_min_power + $sec; + $_day_time = $_day_power - $_day_time; + $ret = -( $_total_date * $_day_power + $_day_time - $gmt_different); + if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction + else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582. + } + //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret; + return $ret; +} + +function adodb_gmstrftime($fmt, $ts=false) +{ + return adodb_strftime($fmt,$ts,true); +} + +// hack - convert to adodb_date +function adodb_strftime($fmt, $ts=false,$is_gmt=false) +{ +global $ADODB_DATE_LOCALE; + + if (!defined('ADODB_TEST_DATES')) { + if ((abs($ts) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range + if (!defined('ADODB_NO_NEGATIVE_TS') || $ts >= 0) // if windows, must be +ve integer + return ($is_gmt)? @gmstrftime($fmt,$ts): @strftime($fmt,$ts); + + } + } + + if (empty($ADODB_DATE_LOCALE)) { + $tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am + $sep = substr($tstr,2,1); + $hasAM = strrpos($tstr,'M') !== false; + + $ADODB_DATE_LOCALE = array(); + $ADODB_DATE_LOCALE[] = strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y'; + $ADODB_DATE_LOCALE[] = ($hasAM) ? 'h:i:s a' : 'H:i:s'; + + } + $inpct = false; + $fmtdate = ''; + for ($i=0,$max = strlen($fmt); $i < $max; $i++) { + $ch = $fmt[$i]; + if ($ch == '%') { + if ($inpct) { + $fmtdate .= '%'; + $inpct = false; + } else + $inpct = true; + } else if ($inpct) { + + $inpct = false; + switch($ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'E': + case 'O': + /* ignore format modifiers */ + $inpct = true; + break; + + case 'a': $fmtdate .= 'D'; break; + case 'A': $fmtdate .= 'l'; break; + case 'h': + case 'b': $fmtdate .= 'M'; break; + case 'B': $fmtdate .= 'F'; break; + case 'c': $fmtdate .= $ADODB_DATE_LOCALE[0].$ADODB_DATE_LOCALE[1]; break; + case 'C': $fmtdate .= '\C?'; break; // century + case 'd': $fmtdate .= 'd'; break; + case 'D': $fmtdate .= 'm/d/y'; break; + case 'e': $fmtdate .= 'j'; break; + case 'g': $fmtdate .= '\g?'; break; //? + case 'G': $fmtdate .= '\G?'; break; //? + case 'H': $fmtdate .= 'H'; break; + case 'I': $fmtdate .= 'h'; break; + case 'j': $fmtdate .= '?z'; $parsej = true; break; // wrong as j=1-based, z=0-basd + case 'm': $fmtdate .= 'm'; break; + case 'M': $fmtdate .= 'i'; break; + case 'n': $fmtdate .= "\n"; break; + case 'p': $fmtdate .= 'a'; break; + case 'r': $fmtdate .= 'h:i:s a'; break; + case 'R': $fmtdate .= 'H:i:s'; break; + case 'S': $fmtdate .= 's'; break; + case 't': $fmtdate .= "\t"; break; + case 'T': $fmtdate .= 'H:i:s'; break; + case 'u': $fmtdate .= '?u'; $parseu = true; break; // wrong strftime=1-based, date=0-based + case 'U': $fmtdate .= '?U'; $parseU = true; break;// wrong strftime=1-based, date=0-based + case 'x': $fmtdate .= $ADODB_DATE_LOCALE[0]; break; + case 'X': $fmtdate .= $ADODB_DATE_LOCALE[1]; break; + case 'w': $fmtdate .= '?w'; $parseu = true; break; // wrong strftime=1-based, date=0-based + case 'W': $fmtdate .= '?W'; $parseU = true; break;// wrong strftime=1-based, date=0-based + case 'y': $fmtdate .= 'y'; break; + case 'Y': $fmtdate .= 'Y'; break; + case 'Z': $fmtdate .= 'T'; break; + } + } else if (('A' <= ($ch) && ($ch) <= 'Z' ) || ('a' <= ($ch) && ($ch) <= 'z' )) + $fmtdate .= "\\".$ch; + else + $fmtdate .= $ch; + } + //echo "fmt=",$fmtdate,"<br>"; + if ($ts === false) $ts = time(); + $ret = adodb_date($fmtdate, $ts, $is_gmt); + return $ret; +} + + +?> \ No newline at end of file Deleted: trunk/functions/adodb-time.inc.php =================================================================== --- trunk/functions/adodb-time.inc.php 2007-07-31 00:55:59 UTC (rev 66) +++ trunk/functions/adodb-time.inc.php 2007-07-31 00:56:34 UTC (rev 67) @@ -1,1313 +0,0 @@ -<?php -/** -ADOdb Date Library, part of the ADOdb abstraction library -Download: http://phplens.com/phpeverywhere/ - -PHP native date functions use integer timestamps for computations. -Because of this, dates are restricted to the years 1901-2038 on Unix -and 1970-2038 on Windows due to integer overflow for dates beyond -those years. This library overcomes these limitations by replacing the -native function's signed integers (normally 32-bits) with PHP floating -point numbers (normally 64-bits). - -Dates from 100 A.D. to 3000 A.D. and later -have been tested. The minimum is 100 A.D. as <100 will invoke the -2 => 4 digit year conversion. The maximum is billions of years in the -future, but this is a theoretical limit as the computation of that year -would take too long with the current implementation of adodb_mktime(). - -This library replaces native functions as follows: - -<pre> - getdate() with adodb_getdate() - date() with adodb_date() - gmdate() with adodb_gmdate() - mktime() with adodb_mktime() - gmmktime() with adodb_gmmktime() - strftime() with adodb_strftime() - strftime() with adodb_gmstrftime() -</pre> - -The parameters are identical, except that adodb_date() accepts a subset -of date()'s field formats. Mktime() will convert from local time to GMT, -and date() will convert from GMT to local time, but daylight savings is -not handled currently. - -This library is independant of the rest of ADOdb, and can be used -as standalone code. - -PERFORMANCE - -For high speed, this library uses the native date functions where -possible, and only switches to PHP code when the dates fall outside -the 32-bit signed integer range. - -GREGORIAN CORRECTION - -Pope Gregory shortened October of A.D. 1582 by ten days. Thursday, -October 4, 1582 (Julian) was followed immediately by Friday, October 15, -1582 (Gregorian). - -Since 0.06, we handle this correctly, so: - -adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582) - == 24 * 3600 (1 day) - -============================================================================= - -COPYRIGHT - -(c) 2003-2005 John Lim and released under BSD-style license except for code by -jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year -and originally found at http://www.php.net/manual/en/function.mktime.php - -============================================================================= - -BUG REPORTS - -These should be posted to the ADOdb forums at - - http://phplens.com/lens/lensforum/topics.php?id=4 - -============================================================================= - -FUNCTION DESCRIPTIONS - - -** FUNCTION adodb_getdate($date=false) - -Returns an array containing date information, as getdate(), but supports -dates greater than 1901 to 2038. The local date/time format is derived from a -heuristic the first time adodb_getdate is called. - - -** FUNCTION adodb_date($fmt, $timestamp = false) - -Convert a timestamp to a formatted local date. If $timestamp is not defined, the -current timestamp is used. Unlike the function date(), it supports dates -outside the 1901 to 2038 range. - -The format fields that adodb_date supports: - -<pre> - a - "am" or "pm" - A - "AM" or "PM" - d - day of the month, 2 digits with leading zeros; i.e. "01" to "31" - D - day of the week, textual, 3 letters; e.g. "Fri" - F - month, textual, long; e.g. "January" - g - hour, 12-hour format without leading zeros; i.e. "1" to "12" - G - hour, 24-hour format without leading zeros; i.e. "0" to "23" - h - hour, 12-hour format; i.e. "01" to "12" - H - hour, 24-hour format; i.e. "00" to "23" - i - minutes; i.e. "00" to "59" - j - day of the month without leading zeros; i.e. "1" to "31" - l (lowercase 'L') - day of the week, textual, long; e.g. "Friday" - L - boolean for whether it is a leap year; i.e. "0" or "1" - m - month; i.e. "01" to "12" - M - month, textual, 3 letters; e.g. "Jan" - n - month without leading zeros; i.e. "1" to "12" - O - Difference to Greenwich time in hours; e.g. "+0200" - Q - Quarter, as in 1, 2, 3, 4 - r - RFC 822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200" - s - seconds; i.e. "00" to "59" - S - English ordinal suffix for the day of the month, 2 characters; - i.e. "st", "nd", "rd" or "th" - t - number of days in the given month; i.e. "28" to "31" - T - Timezone setting of this machine; e.g. "EST" or "MDT" - U - seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) - w - day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday) - Y - year, 4 digits; e.g. "1999" - y - year, 2 digits; e.g. "99" - z - day of the year; i.e. "0" to "365" - Z - timezone offset in seconds (i.e. "-43200" to "43200"). - The offset for timezones west of UTC is always negative, - and for those east of UTC is always positive. -</pre> - -Unsupported: -<pre> - B - Swatch Internet time - I (capital i) - "1" if Daylight Savings Time, "0" otherwise. - W - ISO-8601 week number of year, weeks starting on Monday - -</pre> - - -** FUNCTION adodb_date2($fmt, $isoDateString = false) -Same as adodb_date, but 2nd parameter accepts iso date, eg. - - adodb_date2('d-M-Y H:i','2003-12-25 13:01:34'); - - -** FUNCTION adodb_gmdate($fmt, $timestamp = false) - -Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the -current timestamp is used. Unlike the function date(), it supports dates -outside the 1901 to 2038 range. - - -** FUNCTION adodb_mktime($hr, $min, $sec[, $month, $day, $year]) - -Converts a local date to a unix timestamp. Unlike the function mktime(), it supports -dates outside the 1901 to 2038 range. All parameters are optional. - - -** FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year]) - -Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports -dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters -are currently compulsory. - -** FUNCTION adodb_gmstrftime($fmt, $timestamp = false) -Convert a timestamp to a formatted GMT date. - -** FUNCTION adodb_strftime($fmt, $timestamp = false) - -Convert a timestamp to a formatted local date. Internally converts $fmt into -adodb_date format, then echo result. - -For best results, you can define the local date format yourself. Define a global -variable $ADODB_DATE_LOCALE which is an array, 1st element is date format using -adodb_date syntax, and 2nd element is the time format, also in adodb_date syntax. - - eg. $ADODB_DATE_LOCALE = array('d/m/Y','H:i:s'); - - Supported format codes: - -<pre> - %a - abbreviated weekday name according to the current locale - %A - full weekday name according to the current locale - %b - abbreviated month name according to the current locale - %B - full month name according to the current locale - %c - preferred date and time representation for the current locale - %d - day of the month as a decimal number (range 01 to 31) - %D - same as %m/%d/%y - %e - day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31') - %h - same as %b - %H - hour as a decimal number using a 24-hour clock (range 00 to 23) - %I - hour as a decimal number using a 12-hour clock (range 01 to 12) - %m - month as a decimal number (range 01 to 12) - %M - minute as a decimal number - %n - newline character - %p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale - %r - time in a.m. and p.m. notation - %R - time in 24 hour notation - %S - second as a decimal number - %t - tab character - %T - current time, equal to %H:%M:%S - %x - preferred date representation for the current locale without the time - %X - preferred time representation for the current locale without the date - %y - year as a decimal number without a century (range 00 to 99) - %Y - year as a decimal number including the century - %Z - time zone or name or abbreviation - %% - a literal `%' character -</pre> - - Unsupported codes: -<pre> - %C - century number (the year divided by 100 and truncated to an integer, range 00 to 99) - %g - like %G, but without the century. - %G - The 4-digit year corresponding to the ISO week number (see %V). - This has the same format and value as %Y, except that if the ISO week number belongs - to the previous or next year, that year is used instead. - %j - day of the year as a decimal number (range 001 to 366) - %u - weekday as a decimal number [1,7], with 1 representing Monday - %U - week number of the current year as a decimal number, starting - with the first Sunday as the first day of the first week - %V - The ISO 8601:1988 week number of the current year as a decimal number, - range 01 to 53, where week 1 is the first week that has at least 4 days in the - current year, and with Monday as the first day of the week. (Use %G or %g for - the year component that corresponds to the week number for the specified timestamp.) - %w - day of the week as a decimal, Sunday being 0 - %W - week number of the current year as a decimal number, starting with the - first Monday as the first day of the first week -</pre> - -============================================================================= - -NOTES - -Useful url for generating test timestamps: - http://www.4webhelp.net/us/timestamp.php - -Possible future optimizations include - -a. Using an algorithm similar to Plauger's in "The Standard C Library" -(page 428, xttotm.c _Ttotm() function). Plauger's algorithm will not -work outside 32-bit signed range, so i decided not to implement it. - -b. Implement daylight savings, which looks awfully complicated, see - http://webexhibits.org/daylightsaving/ - - -CHANGELOG -- 08 Sept 2005 0.22 -In adodb_date2(), $is_gmt not supported properly. Fixed. - -- 18 July 2005 0.21 -In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat. -Added support for negative months in adodb_mktime(). - -- 24 Feb 2005 0.20 -Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date(). - -- 21 Dec 2004 0.17 -In adodb_getdate(), the timestamp was accidentally converted to gmt when $is_gmt is false. -Also adodb_mktime(0,0,0) did not work properly. Both fixed thx Mauro. - -- 17 Nov 2004 0.16 -Removed intval typecast in adodb_mktime() for secs, allowing: - adodb_mktime(0,0,0 + 2236672153,1,1,1934); -Suggested by Ryan. - -- 18 July 2004 0.15 -All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory. -This brings it more in line with mktime (still not identical). - -- 23 June 2004 0.14 - -Allow you to define your own daylights savings function, adodb_daylight_sv. -If the function is defined (somewhere in an include), then you can correct for daylights savings. - -In this example, we apply daylights savings in June or July, adding one hour. This is extremely -unrealistic as it does not take into account time-zone, geographic location, current year. - -function adodb_daylight_sv(&$arr, $is_gmt) -{ - if ($is_gmt) return; - $m = $arr['mon']; - if ($m == 6 || $m == 7) $arr['hours'] += 1; -} - -This is only called by adodb_date() and not by adodb_mktime(). - -The format of $arr is -Array ( - [seconds] => 0 - [minutes] => 0 - [hours] => 0 - [mday] => 1 # day of month, eg 1st day of the month - [mon] => 2 # month (eg. Feb) - [year] => 2102 - [yday] => 31 # days in current year - [leap] => # true if leap year - [ndays] => 28 # no of days in current month - ) - - -- 28 Apr 2004 0.13 -Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov. - -- 20 Mar 2004 0.12 -Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32. - -- 26 Oct 2003 0.11 -Because of daylight savings problems (some systems apply daylight savings to -January!!!), changed adodb_get_gmt_diff() to ignore daylight savings. - -- 9 Aug 2003 0.10 -Fixed bug with dates after 2038. -See http://phplens.com/lens/lensforum/msgs.php?id=6980 - -- 1 July 2003 0.09 -Added support for Q (Quarter). -Added adodb_date2(), which accepts ISO date in 2nd param - -- 3 March 2003 0.08 -Added support for 'S' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS -if you want PHP to handle negative timestamps between 1901 to 1969. - -- 27 Feb 2003 0.07 -All negative numbers handled by adodb now because of RH 7.3+ problems. -See http://bugs.php.net/bug.php?id=20048&edit=2 - -- 4 Feb 2003 0.06 -Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates -are now correctly handled. - -- 29 Jan 2003 0.05 - -Leap year checking differs under Julian calendar (pre 1582). Also -leap year code optimized by checking for most common case first. - -We also handle month overflow correctly in mktime (eg month set to 13). - -Day overflow for less than one month's days is supported. - -- 28 Jan 2003 0.04 - -Gregorian correction handled. In PHP5, we might throw an error if -mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10. -Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582. - -- 27 Jan 2003 0.03 - -Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION. -Fixed calculation of days since start of year for <1970. - -- 27 Jan 2003 0.02 - -Changed _adodb_getdate() to inline leap year checking for better performance. -Fixed problem with time-zones west of GMT +0000. - -- 24 Jan 2003 0.01 - -First implementation. -*/ - - -/* Initialization */ - -/* - Version Number -*/ -define('ADODB_DATE_VERSION',0.22); - -/* - This code was originally for windows. But apparently this problem happens - also with Linux, RH 7.3 and later! - - glibc-2.2.5-34 and greater has been changed to return -1 for dates < - 1970. This used to work. The problem exists with RedHat 7.3 and 8.0 - echo (mktime(0, 0, 0, 1, 1, 1960)); // prints -1 - - References: - http://bugs.php.net/bug.php?id=20048&edit=2 - http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html -*/ - -if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1); - -function adodb_date_test_date($y1,$m,$d=13) -{ - $t = adodb_mktime(0,0,0,$m,$d,$y1); - $rez = adodb_date('Y-n-j H:i:s',$t); - if ("$y1-$m-$d 00:00:00" != $rez) { - print "<b>$y1 error, expected=$y1-$m-$d 00:00:00, adodb=$rez</b><br>"; - return false; - } - return true; -} - -function adodb_date_test_strftime($fmt) -{ - $s1 = strftime($fmt); - $s2 = adodb_strftime($fmt); - - if ($s1 == $s2) return true; - - echo "error for $fmt, strftime=$s1, $adodb=$s2<br>"; - return false; -} - -/** - Test Suite -*/ -function adodb_date_test() -{ - - error_reporting(E_ALL); - print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."</h4>"; - @set_time_limit(0); - $fail = false; - - // This flag disables calling of PHP native functions, so we can properly test the code - if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1); - - adodb_date_test_strftime('%Y %m %x %X'); - adodb_date_test_strftime("%A %d %B %Y"); - adodb_date_test_strftime("%H %M S"); - - $t = adodb_mktime(0,0,0); - if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>'; - - $t = adodb_mktime(0,0,0,6,1,2102); - if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>'; - - $t = adodb_mktime(0,0,0,2,1,2102); - if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>'; - - - print "<p>Testing gregorian <=> julian conversion<p>"; - $t = adodb_mktime(0,0,0,10,11,1492); - //http://www.holidayorigins.com/html/columbus_day.html - Friday check - if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing<br>'; - - $t = adodb_mktime(0,0,0,2,29,1500); - if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years<br>'; - - $t = adodb_mktime(0,0,0,2,29,1700); - if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years<br>'; - - print adodb_mktime(0,0,0,10,4,1582).' '; - print adodb_mktime(0,0,0,10,15,1582); - $diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)); - if ($diff != 3600*24) print " <b>Error in gregorian correction = ".($diff/3600/24)." days </b><br>"; - - print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : '<b>Error</b>')."<br>"; - print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : '<b>Error</b>')."<br>"; - - print "<p>Testing overflow<p>"; - - $t = adodb_mktime(0,0,0,3,33,1965); - if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1 <br>'; - $t = adodb_mktime(0,0,0,4,33,1971); - if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2 <br>'; - $t = adodb_mktime(0,0,0,1,60,1965); - if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).' <br>'; - $t = adodb_mktime(0,0,0,12,32,1965); - if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).' <br>'; - $t = adodb_mktime(0,0,0,12,63,1965); - if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).' <br>'; - $t = adodb_mktime(0,0,0,13,3,1965); - if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1 <br>'; - - print "Testing 2-digit => 4-digit year conversion<p>"; - if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000<br>"; - if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010<br>"; - if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020<br>"; - if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030<br>"; - if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940<br>"; - if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>"; - if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>"; - - // Test string formating - print "<p>Testing date formating</p>"; - $fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C822 r s t U w y Y z Z 2003'; - $s1 = date($fmt,0); - $s2 = adodb_date($fmt,0); - if ($s1 != $s2) { - print " date() 0 failed<br>$s1<br>$s2<br>"; - } - flush(); - for ($i=100; --$i > 0; ) { - - $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000); - $s1 = date($fmt,$ts); - $s2 = adodb_date($fmt,$ts); - //print "$s1 <br>$s2 <p>"; - $pos = strcmp($s1,$s2); - - if (($s1) != ($s2)) { - for ($j=0,$k=strlen($s1); $j < $k; $j++) { - if ($s1[$j] != $s2[$j]) { - print substr($s1,$j).' '; - break; - } - } - print "<b>Error date(): $ts<br><pre> - \"$s1\" (date len=".strlen($s1).") - \"$s2\" (adodb_date len=".strlen($s2).")</b></pre><br>"; - $fail = true; - } - - $a1 = getdate($ts); - $a2 = adodb_getdate($ts); - $rez = array_diff($a1,$a2); - if (sizeof($rez)>0) { - print "<b>Error getdate() $ts</b><br>"; - print_r($a1); - print "<br>"; - print_r($a2); - print "<p>"; - $fail = true; - } - } - - // Test generation of dates outside 1901-2038 - print "<p>Testing random dates between 100 and 4000</p>"; - adodb_date_test_date(100,1); - for ($i=100; --$i >= 0;) { - $y1 = 100+rand(0,1970-100); - $m = rand(1,12); - adodb_date_test_date($y1,$m); - - $y1 = 3000-rand(0,3000-1970); - adodb_date_test_date($y1,$m); - } - print '<p>'; - $start = 1960+ra... [truncated message content] |
From: <cal...@us...> - 2007-07-31 00:56:41
|
Revision: 68 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=68&view=rev Author: caleb870 Date: 2007-07-30 17:56:43 -0700 (Mon, 30 Jul 2007) Log Message: ----------- Moved remotely Added Paths: ----------- trunk/functions/adodb/adodb-xmlschema.inc.php Removed Paths: ------------- trunk/functions/adodb-xmlschema.inc.php Copied: trunk/functions/adodb/adodb-xmlschema.inc.php (from rev 67, trunk/functions/adodb-xmlschema.inc.php) =================================================================== --- trunk/functions/adodb/adodb-xmlschema.inc.php (rev 0) +++ trunk/functions/adodb/adodb-xmlschema.inc.php 2007-07-31 00:56:43 UTC (rev 68) @@ -0,0 +1,2338 @@ +<?php +// Copyright (c) 2004 ars Cognita Inc., 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. +*******************************************************************************/ +/** + * xmlschema is a class that allows the user to quickly and easily + * build a database on any ADOdb-supported platform using a simple + * XML schema. + * + * Last Editor: $Author: Mark Dickenson $ + * @author Richard Tango-Lowy & Dan Cech + * @version $Revision: 1.13 $ + * + * @package axmls + * @tutorial getting_started.pkg + */ + +/** +* Debug on or off +*/ +if( !defined( 'XMLS_DEBUG' ) ) { + define( 'XMLS_DEBUG', FALSE ); +} + +/** +* Default prefix key +*/ +if( !defined( 'XMLS_PREFIX' ) ) { + define( 'XMLS_PREFIX', '%%P' ); +} + +/** +* Maximum length allowed for object prefix +*/ +if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) { + define( 'XMLS_PREFIX_MAXLEN', 10 ); +} + +/** +* Execute SQL inline as it is generated +*/ +if( !defined( 'XMLS_EXECUTE_INLINE' ) ) { + define( 'XMLS_EXECUTE_INLINE', FALSE ); +} + +/** +* Continue SQL Execution if an error occurs? +*/ +if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) { + define( 'XMLS_CONTINUE_ON_ERROR', FALSE ); +} + +/** +* Current Schema Version +*/ +if( !defined( 'XMLS_SCHEMA_VERSION' ) ) { + define( 'XMLS_SCHEMA_VERSION', '0.2' ); +} + +/** +* Default Schema Version. Used for Schemas without an explicit version set. +*/ +if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) { + define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' ); +} + +/** +* Default Schema Version. Used for Schemas without an explicit version set. +*/ +if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) { + define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' ); +} + +/** +* Include the main ADODB library +*/ +if( !defined( '_ADODB_LAYER' ) ) { + include_once( 'adodb.inc.php' ); + include_once( 'adodb-datadict.inc.php' ); +} + +/** +* Abstract DB Object. This class provides basic methods for database objects, such +* as tables and indexes. +* +* @package axmls +* @access private +*/ +class dbObject { + + /** + * var object Parent + */ + var $parent; + + /** + * var string current element + */ + var $currentElement; + + /** + * NOP + */ + function dbObject( &$parent, $attributes = NULL ) { + $this->parent =& $parent; + } + + /** + * XML Callback to process start elements + * + * @access private + */ + function _tag_open( &$parser, $tag, $attributes ) { + + } + + /** + * XML Callback to process CDATA elements + * + * @access private + */ + function _tag_cdata( &$parser, $cdata ) { + + } + + /** + * XML Callback to process end elements + * + * @access private + */ + function _tag_close( &$parser, $tag ) { + + } + + function create() { + return array(); + } + + /** + * Destroys the object + */ + function destroy() { + unset( $this ); + } + + /** + * Checks whether the specified RDBMS is supported by the current + * database object or its ranking ancestor. + * + * @param string $platform RDBMS platform name (from ADODB platform list). + * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE. + */ + function supportedPlatform( $platform = NULL ) { + return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE; + } + + /** + * Returns the prefix set by the ranking ancestor of the database object. + * + * @param string $name Prefix string. + * @return string Prefix. + */ + function prefix( $name = '' ) { + return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name; + } + + /** + * Extracts a field ID from the specified field. + * + * @param string $field Field. + * @return string Field ID. + */ + function FieldID( $field ) { + return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) ); + } +} + +/** +* Creates a table object in ADOdb's datadict format +* +* This class stores information about a database table. As charactaristics +* of the table are loaded from the external source, methods and properties +* of this class are used to build up the table description in ADOdb's +* datadict format. +* +* @package axmls +* @access private +*/ +class dbTable extends dbObject { + + /** + * @var string Table name + */ + var $name; + + /** + * @var array Field specifier: Meta-information about each field + */ + var $fields = array(); + + /** + * @var array List of table indexes. + */ + var $indexes = array(); + + /** + * @var array Table options: Table-level options + */ + var $opts = array(); + + /** + * @var string Field index: Keeps track of which field is currently being processed + */ + var $current_field; + + /** + * @var boolean Mark table for destruction + * @access private + */ + var $drop_table; + + /** + * @var boolean Mark field for destruction (not yet implemented) + * @access private + */ + var $drop_field = array(); + + /** + * Iniitializes a new table object. + * + * @param string $prefix DB Object prefix + * @param array $attributes Array of table attributes. + */ + function dbTable( &$parent, $attributes = NULL ) { + $this->parent =& $parent; + $this->name = $this->prefix($attributes['NAME']); + } + + /** + * XML Callback to process start elements. Elements currently + * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT. + * + * @access private + */ + function _tag_open( &$parser, $tag, $attributes ) { + $this->currentElement = strtoupper( $tag ); + + switch( $this->currentElement ) { + case 'INDEX': + if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) { + xml_set_object( $parser, $this->addIndex( $attributes ) ); + } + break; + case 'DATA': + if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) { + xml_set_object( $parser, $this->addData( $attributes ) ); + } + break; + case 'DROP': + $this->drop(); + break; + case 'FIELD': + // Add a field + $fieldName = $attributes['NAME']; + $fieldType = $attributes['TYPE']; + $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL; + $fieldOpts = isset( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL; + + $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts ); + break; + case 'KEY': + case 'NOTNULL': + case 'AUTOINCREMENT': + // Add a field option + $this->addFieldOpt( $this->current_field, $this->currentElement ); + break; + case 'DEFAULT': + // Add a field option to the table object + + // Work around ADOdb datadict issue that misinterprets empty strings. + if( $attributes['VALUE'] == '' ) { + $attributes['VALUE'] = " '' "; + } + + $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] ); + break; + case 'DEFDATE': + case 'DEFTIMESTAMP': + // Add a field option to the table object + $this->addFieldOpt( $this->current_field, $this->currentElement ); + break; + default: + // print_r( array( $tag, $attributes ) ); + } + } + + /** + * XML Callback to process CDATA elements + * + * @access private + */ + function _tag_cdata( &$parser, $cdata ) { + switch( $this->currentElement ) { + // Table constraint + case 'CONSTRAINT': + if( isset( $this->current_field ) ) { + $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata ); + } else { + $this->addTableOpt( $cdata ); + } + break; + // Table option + case 'OPT': + $this->addTableOpt( $cdata ); + break; + default: + + } + } + + /** + * XML Callback to process end elements + * + * @access private + */ + function _tag_close( &$parser, $tag ) { + $this->currentElement = ''; + + switch( strtoupper( $tag ) ) { + case 'TABLE': + $this->parent->addSQL( $this->create( $this->parent ) ); + xml_set_object( $parser, $this->parent ); + $this->destroy(); + break; + case 'FIELD': + unset($this->current_field); + break; + + } + } + + /** + * Adds an index to a table object + * + * @param array $attributes Index attributes + * @return object dbIndex object + */ + function &addIndex( $attributes ) { + $name = strtoupper( $attributes['NAME'] ); + $this->indexes[$name] =& new dbIndex( $this, $attributes ); + return $this->indexes[$name]; + } + + /** + * Adds data to a table object + * + * @param array $attributes Data attributes + * @return object dbData object + */ + function &addData( $attributes ) { + if( !isset( $this->data ) ) { + $this->data =& new dbData( $this, $attributes ); + } + return $this->data; + } + + /** + * Adds a field to a table object + * + * $name is the name of the table to which the field should be added. + * $type is an ADODB datadict field type. The following field types + * are supported as of ADODB 3.40: + * - C: varchar + * - X: CLOB (character large object) or largest varchar size + * if CLOB is not supported + * - C2: Multibyte varchar + * - X2: Multibyte CLOB + * - B: BLOB (binary large object) + * - D: Date (some databases do not support this, and we return a datetime type) + * - T: Datetime or Timestamp + * - L: Integer field suitable for storing booleans (0 or 1) + * - I: Integer (mapped to I4) + * - I1: 1-byte integer + * - I2: 2-byte integer + * - I4: 4-byte integer + * - I8: 8-byte integer + * - F: Floating point number + * - N: Numeric or decimal number + * + * @param string $name Name of the table to which the field will be added. + * @param string $type ADODB datadict field type. + * @param string $size Field size + * @param array $opts Field options array + * @return array Field specifier array + */ + function addField( $name, $type, $size = NULL, $opts = NULL ) { + $field_id = $this->FieldID( $name ); + + // Set the field index so we know where we are + $this->current_field = $field_id; + + // Set the field name (required) + $this->fields[$field_id]['NAME'] = $name; + + // Set the field type (required) + $this->fields[$field_id]['TYPE'] = $type; + + // Set the field size (optional) + if( isset( $size ) ) { + $this->fields[$field_id]['SIZE'] = $size; + } + + // Set the field options + if( isset( $opts ) ) { + $this->fields[$field_id]['OPTS'][] = $opts; + } + } + + /** + * Adds a field option to the current field specifier + * + * This method adds a field option allowed by the ADOdb datadict + * and appends it to the given field. + * + * @param string $field Field name + * @param string $opt ADOdb field option + * @param mixed $value Field option value + * @return array Field specifier array + */ + function addFieldOpt( $field, $opt, $value = NULL ) { + if( !isset( $value ) ) { + $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt; + // Add the option and value + } else { + $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value ); + } + } + + /** + * Adds an option to the table + * + * This method takes a comma-separated list of table-level options + * and appends them to the table object. + * + * @param string $opt Table option + * @return array Options + */ + function addTableOpt( $opt ) { + $this->opts[] = $opt; + + return $this->opts; + } + + /** + * Generates the SQL that will create the table in the database + * + * @param object $xmls adoSchema object + * @return array Array containing table creation SQL + */ + function create( &$xmls ) { + $sql = array(); + + // drop any existing indexes + if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) { + foreach( $legacy_indexes as $index => $index_details ) { + $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name ); + } + } + + // remove fields to be dropped from table object + foreach( $this->drop_field as $field ) { + unset( $this->fields[$field] ); + } + + // if table exists + if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) { + // drop table + if( $this->drop_table ) { + $sql[] = $xmls->dict->DropTableSQL( $this->name ); + + return $sql; + } + + // drop any existing fields not in schema + foreach( $legacy_fields as $field_id => $field ) { + if( !isset( $this->fields[$field_id] ) ) { + $sql[] = $xmls->dict->DropColumnSQL( $this->name, '`'.$field->name.'`' ); + } + } + // if table doesn't exist + } else { + if( $this->drop_table ) { + return $sql; + } + + $legacy_fields = array(); + } + + // Loop through the field specifier array, building the associative array for the field options + $fldarray = array(); + + foreach( $this->fields as $field_id => $finfo ) { + // Set an empty size if it isn't supplied + if( !isset( $finfo['SIZE'] ) ) { + $finfo['SIZE'] = ''; + } + + // Initialize the field array with the type and size + $fldarray[$field_id] = array( + 'NAME' => $finfo['NAME'], + 'TYPE' => $finfo['TYPE'], + 'SIZE' => $finfo['SIZE'] + ); + + // Loop through the options array and add the field options. + if( isset( $finfo['OPTS'] ) ) { + foreach( $finfo['OPTS'] as $opt ) { + // Option has an argument. + if( is_array( $opt ) ) { + $key = key( $opt ); + $value = $opt[key( $opt )]; + @$fldarray[$field_id][$key] .= $value; + // Option doesn't have arguments + } else { + $fldarray[$field_id][$opt] = $opt; + } + } + } + } + + if( empty( $legacy_fields ) ) { + // Create the new table + $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts ); + logMsg( end( $sql ), 'Generated CreateTableSQL' ); + } else { + // Upgrade an existing table + logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" ); + switch( $xmls->upgrade ) { + // Use ChangeTableSQL + case 'ALTER': + logMsg( 'Generated ChangeTableSQL (ALTERing table)' ); + $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts ); + break; + case 'REPLACE': + logMsg( 'Doing upgrade REPLACE (testing)' ); + $sql[] = $xmls->dict->DropTableSQL( $this->name ); + $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts ); + break; + // ignore table + default: + return array(); + } + } + + foreach( $this->indexes as $index ) { + $sql[] = $index->create( $xmls ); + } + + if( isset( $this->data ) ) { + $sql[] = $this->data->create( $xmls ); + } + + return $sql; + } + + /** + * Marks a field or table for destruction + */ + function drop() { + if( isset( $this->current_field ) ) { + // Drop the current field + logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" ); + // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field ); + $this->drop_field[$this->current_field] = $this->current_field; + } else { + // Drop the current table + logMsg( "Dropping table '{$this->name}'" ); + // $this->drop_table = $xmls->dict->DropTableSQL( $this->name ); + $this->drop_table = TRUE; + } + } +} + +/** +* Creates an index object in ADOdb's datadict format +* +* This class stores information about a database index. As charactaristics +* of the index are loaded from the external source, methods and properties +* of this class are used to build up the index description in ADOdb's +* datadict format. +* +* @package axmls +* @access private +*/ +class dbIndex extends dbObject { + + /** + * @var string Index name + */ + var $name; + + /** + * @var array Index options: Index-level options + */ + var $opts = array(); + + /** + * @var array Indexed fields: Table columns included in this index + */ + var $columns = array(); + + /** + * @var boolean Mark index for destruction + * @access private + */ + var $drop = FALSE; + + /** + * Initializes the new dbIndex object. + * + * @param object $parent Parent object + * @param array $attributes Attributes + * + * @internal + */ + function dbIndex( &$parent, $attributes = NULL ) { + $this->parent =& $parent; + + $this->name = $this->prefix ($attributes['NAME']); + } + + /** + * XML Callback to process start elements + * + * Processes XML opening tags. + * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. + * + * @access private + */ + function _tag_open( &$parser, $tag, $attributes ) { + $this->currentElement = strtoupper( $tag ); + + switch( $this->currentElement ) { + case 'DROP': + $this->drop(); + break; + case 'CLUSTERED': + case 'BITMAP': + case 'UNIQUE': + case 'FULLTEXT': + case 'HASH': + // Add index Option + $this->addIndexOpt( $this->currentElement ); + break; + default: + // print_r( array( $tag, $attributes ) ); + } + } + + /** + * XML Callback to process CDATA elements + * + * Processes XML cdata. + * + * @access private + */ + function _tag_cdata( &$parser, $cdata ) { + switch( $this->currentElement ) { + // Index field name + case 'COL': + $this->addField( $cdata ); + break; + default: + + } + } + + /** + * XML Callback to process end elements + * + * @access private + */ + function _tag_close( &$parser, $tag ) { + $this->currentElement = ''; + + switch( strtoupper( $tag ) ) { + case 'INDEX': + xml_set_object( $parser, $this->parent ); + break; + } + } + + /** + * Adds a field to the index + * + * @param string $name Field name + * @return string Field list + */ + function addField( $name ) { + $this->columns[$this->FieldID( $name )] = $name; + + // Return the field list + return $this->columns; + } + + /** + * Adds options to the index + * + * @param string $opt Comma-separated list of index options. + * @return string Option list + */ + function addIndexOpt( $opt ) { + $this->opts[] = $opt; + + // Return the options list + return $this->opts; + } + + /** + * Generates the SQL that will create the index in the database + * + * @param object $xmls adoSchema object + * @return array Array containing index creation SQL + */ + function create( &$xmls ) { + if( $this->drop ) { + return NULL; + } + + // eliminate any columns that aren't in the table + foreach( $this->columns as $id => $col ) { + if( !isset( $this->parent->fields[$id] ) ) { + unset( $this->columns[$id] ); + } + } + + return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts ); + } + + /** + * Marks an index for destruction + */ + function drop() { + $this->drop = TRUE; + } +} + +/** +* Creates a data object in ADOdb's datadict format +* +* This class stores information about table data. +* +* @package axmls +* @access private +*/ +class dbData extends dbObject { + + var $data = array(); + + var $row; + + /** + * Initializes the new dbIndex object. + * + * @param object $parent Parent object + * @param array $attributes Attributes + * + * @internal + */ + function dbData( &$parent, $attributes = NULL ) { + $this->parent =& $parent; + } + + /** + * XML Callback to process start elements + * + * Processes XML opening tags. + * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. + * + * @access private + */ + function _tag_open( &$parser, $tag, $attributes ) { + $this->currentElement = strtoupper( $tag ); + + switch( $this->currentElement ) { + case 'ROW': + $this->row = count( $this->data ); + $this->data[$this->row] = array(); + break; + case 'F': + $this->addField($attributes); + default: + // print_r( array( $tag, $attributes ) ); + } + } + + /** + * XML Callback to process CDATA elements + * + * Processes XML cdata. + * + * @access private + */ + function _tag_cdata( &$parser, $cdata ) { + switch( $this->currentElement ) { + // Index field name + case 'F': + $this->addData( $cdata ); + break; + default: + + } + } + + /** + * XML Callback to process end elements + * + * @access private + */ + function _tag_close( &$parser, $tag ) { + $this->currentElement = ''; + + switch( strtoupper( $tag ) ) { + case 'DATA': + xml_set_object( $parser, $this->parent ); + break; + } + } + + /** + * Adds a field to the index + * + * @param string $name Field name + * @return string Field list + */ + function addField( $attributes ) { + if( isset( $attributes['NAME'] ) ) { + $name = $attributes['NAME']; + } else { + $name = count($this->data[$this->row]); + } + + // Set the field index so we know where we are + $this->current_field = $this->FieldID( $name ); + } + + /** + * Adds options to the index + * + * @param string $opt Comma-separated list of index options. + * @return string Option list + */ + function addData( $cdata ) { + if( !isset( $this->data[$this->row] ) ) { + $this->data[$this->row] = array(); + } + + if( !isset( $this->data[$this->row][$this->current_field] ) ) { + $this->data[$this->row][$this->current_field] = ''; + } + + $this->data[$this->row][$this->current_field] .= $cdata; + } + + /** + * Generates the SQL that will create the index in the database + * + * @param object $xmls adoSchema object + * @return array Array containing index creation SQL + */ + function create( &$xmls ) { + $table = $xmls->dict->TableName($this->parent->name); + $table_field_count = count($this->parent->fields); + $sql = array(); + + // eliminate any columns that aren't in the table + foreach( $this->data as $row ) { + $table_fields = $this->parent->fields; + $fields = array(); + + foreach( $row as $field_id => $field_data ) { + if( !array_key_exists( $field_id, $table_fields ) ) { + if( is_numeric( $field_id ) ) { + $field_id = reset( array_keys( $table_fields ) ); + } else { + continue; + } + } + + $name = $table_fields[$field_id]['NAME']; + + switch( $table_fields[$field_id]['TYPE'] ) { + case 'C': + case 'C2': + case 'X': + case 'X2': + $fields[$name] = $xmls->db->qstr( $field_data ); + break; + case 'I': + case 'I1': + case 'I2': + case 'I4': + case 'I8': + $fields[$name] = intval($field_data); + break; + default: + $fields[$name] = $field_data; + } + + unset($table_fields[$field_id]); + } + + // check that at least 1 column is specified + if( empty( $fields ) ) { + continue; + } + + // check that no required columns are missing + if( count( $fields ) < $table_field_count ) { + foreach( $table_fields as $field ) { + if (isset( $field['OPTS'] )) + if( ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) { + continue(2); + } + } + } + + $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')'; + } + + return $sql; + } +} + +/** +* Creates the SQL to execute a list of provided SQL queries +* +* @package axmls +* @access private +*/ +class dbQuerySet extends dbObject { + + /** + * @var array List of SQL queries + */ + var $queries = array(); + + /** + * @var string String used to build of a query line by line + */ + var $query; + + /** + * @var string Query prefix key + */ + var $prefixKey = ''; + + /** + * @var boolean Auto prefix enable (TRUE) + */ + var $prefixMethod = 'AUTO'; + + /** + * Initializes the query set. + * + * @param object $parent Parent object + * @param array $attributes Attributes + */ + function dbQuerySet( &$parent, $attributes = NULL ) { + $this->parent =& $parent; + + // Overrides the manual prefix key + if( isset( $attributes['KEY'] ) ) { + $this->prefixKey = $attributes['KEY']; + } + + $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : ''; + + // Enables or disables automatic prefix prepending + switch( $prefixMethod ) { + case 'AUTO': + $this->prefixMethod = 'AUTO'; + break; + case 'MANUAL': + $this->prefixMethod = 'MANUAL'; + break; + case 'NONE': + $this->prefixMethod = 'NONE'; + break; + } + } + + /** + * XML Callback to process start elements. Elements currently + * processed are: QUERY. + * + * @access private + */ + function _tag_open( &$parser, $tag, $attributes ) { + $this->currentElement = strtoupper( $tag ); + + switch( $this->currentElement ) { + case 'QUERY': + // Create a new query in a SQL queryset. + // Ignore this query set if a platform is specified and it's different than the + // current connection platform. + if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) { + $this->newQuery(); + } else { + $this->discardQuery(); + } + break; + default: + // print_r( array( $tag, $attributes ) ); + } + } + + /** + * XML Callback to process CDATA elements + */ + function _tag_cdata( &$parser, $cdata ) { + switch( $this->currentElement ) { + // Line of queryset SQL data + case 'QUERY': + $this->buildQuery( $cdata ); + break; + default: + + } + } + + /** + * XML Callback to process end elements + * + * @access private + */ + function _tag_close( &$parser, $tag ) { + $this->currentElement = ''; + + switch( strtoupper( $tag ) ) { + case 'QUERY': + // Add the finished query to the open query set. + $this->addQuery(); + break; + case 'SQL': + $this->parent->addSQL( $this->create( $this->parent ) ); + xml_set_object( $parser, $this->parent ); + $this->destroy(); + break; + default: + + } + } + + /** + * Re-initializes the query. + * + * @return boolean TRUE + */ + function newQuery() { + $this->query = ''; + + return TRUE; + } + + /** + * Discards the existing query. + * + * @return boolean TRUE + */ + function discardQuery() { + unset( $this->query ); + + return TRUE; + } + + /** + * Appends a line to a query that is being built line by line + * + * @param string $data Line of SQL data or NULL to initialize a new query + * @return string SQL query string. + */ + function buildQuery( $sql = NULL ) { + if( !isset( $this->query ) OR empty( $sql ) ) { + return FALSE; + } + + $this->query .= $sql; + + return $this->query; + } + + /** + * Adds a completed query to the query list + * + * @return string SQL of added query + */ + function addQuery() { + if( !isset( $this->query ) ) { + return FALSE; + } + + $this->queries[] = $return = trim($this->query); + + unset( $this->query ); + + return $return; + } + + /** + * Creates and returns the current query set + * + * @param object $xmls adoSchema object + * @return array Query set + */ + function create( &$xmls ) { + foreach( $this->queries as $id => $query ) { + switch( $this->prefixMethod ) { + case 'AUTO': + // Enable auto prefix replacement + + // Process object prefix. + // Evaluate SQL statements to prepend prefix to objects + $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix ); + $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix ); + $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix ); + + // SELECT statements aren't working yet + #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data ); + + case 'MANUAL': + // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX. + // If prefixKey is not set, we use the default constant XMLS_PREFIX + if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) { + // Enable prefix override + $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query ); + } else { + // Use default replacement + $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query ); + } + } + + $this->queries[$id] = trim( $query ); + } + + // Return the query set array + return $this->queries; + } + + /** + * Rebuilds the query with the prefix attached to any objects + * + * @param string $regex Regex used to add prefix + * @param string $query SQL query string + * @param string $prefix Prefix to be appended to tables, indices, etc. + * @return string Prefixed SQL query string. + */ + function prefixQuery( $regex, $query, $prefix = NULL ) { + if( !isset( $prefix ) ) { + return $query; + } + + if( preg_match( $regex, $query, $match ) ) { + $preamble = $match[1]; + $postamble = $match[5]; + $objectList = explode( ',', $match[3] ); + // $prefix = $prefix . '_'; + + $prefixedList = ''; + + foreach( $objectList as $object ) { + if( $prefixedList !== '' ) { + $prefixedList .= ', '; + } + + $prefixedList .= $prefix . trim( $object ); + } + + $query = $preamble . ' ' . $prefixedList . ' ' . $postamble; + } + + return $query; + } +} + +/** +* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements +* +* This class is used to load and parse the XML file, to create an array of SQL statements +* that can be used to build a database, and to build the database using the SQL array. +* +* @tutorial getting_started.pkg +* +* @author Richard Tango-Lowy & Dan Cech +* @version $Revision: 1.12 $ +* +* @package axmls +*/ +class adoSchema { + + /** + * @var array Array containing SQL queries to generate all objects + * @access private + */ + var $sqlArray; + + /** + * @var object ADOdb connection object + * @access private + */ + var $db; + + /** + * @var object ADOdb Data Dictionary + * @access private + */ + var $dict; + + /** + * @var string Current XML element + * @access private + */ + var $currentElement = ''; + + /** + * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database + * @access private + */ + var $upgrade = ''; + + /** + * @var string Optional object prefix + * @access private + */ + var $objectPrefix = ''; + + /** + * @var long Original Magic Quotes Runtime value + * @access private + */ + var $mgq; + + /** + * @var long System debug + * @access private + */ + var $debug; + + /** + * @var string Regular expression to find schema version + * @access private + */ + var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/'; + + /** + * @var string Current schema version + * @access private + */ + var $schemaVersion; + + /** + * @var int Success of last Schema execution + */ + var $success; + + /** + * @var bool Execute SQL inline as it is generated + */ + var $executeInline; + + /** + * @var bool Continue SQL execution if errors occur + */ + var $continueOnError; + + /** + * Creates an adoSchema object + * + * Creating an adoSchema object is the first step in processing an XML schema. + * The only parameter is an ADOdb database connection object, which must already + * have been created. + * + * @param object $db ADOdb database connection object. + */ + function adoSchema( &$db ) { + // Initialize the environment + $this->mgq = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + + $this->db =& $db; + $this->debug = $this->db->debug; + $this->dict = NewDataDictionary( $this->db ); + $this->sqlArray = array(); + $this->schemaVersion = XMLS_SCHEMA_VERSION; + $this->executeInline( XMLS_EXECUTE_INLINE ); + $this->continueOnError( XMLS_CONTINUE_ON_ERROR ); + $this->setUpgradeMethod(); + } + + /** + * Sets the method to be used for upgrading an existing database + * + * Use this method to specify how existing database objects should be upgraded. + * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to + * alter each database object directly, REPLACE attempts to rebuild each object + * from scratch, BEST attempts to determine the best upgrade method for each + * object, and NONE disables upgrading. + * + * This method is not yet used by AXMLS, but exists for backward compatibility. + * The ALTER method is automatically assumed when the adoSchema object is + * instantiated; other upgrade methods are not currently supported. + * + * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE) + * @returns string Upgrade method used + */ + function SetUpgradeMethod( $method = '' ) { + if( !is_string( $method ) ) { + return FALSE; + } + + $method = strtoupper( $method ); + + // Handle the upgrade methods + switch( $method ) { + case 'ALTER': + $this->upgrade = $method; + break; + case 'REPLACE': + $this->upgrade = $method; + break; + case 'BEST': + $this->upgrade = 'ALTER'; + break; + case 'NONE': + $this->upgrade = 'NONE'; + break; + default: + // Use default if no legitimate method is passed. + $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD; + } + + return $this->upgrade; + } + + /** + * Enables/disables inline SQL execution. + * + * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution), + * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode + * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema() + * to apply the schema to the database. + * + * @param bool $mode execute + * @return bool current execution mode + * + * @see ParseSchema(), ExecuteSchema() + */ + function ExecuteInline( $mode = NULL ) { + if( is_bool( $mode ) ) { + $this->executeInline = $mode; + } + + return $this->executeInline; + } + + /** + * Enables/disables SQL continue on error. + * + * Call this method to enable or disable continuation of SQL execution if an error occurs. + * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs. + * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing + * of the schema will continue. + * + * @param bool $mode execute + * @return bool current continueOnError mode + * + * @see addSQL(), ExecuteSchema() + */ + function ContinueOnError( $mode = NULL ) { + if( is_bool( $mode ) ) { + $this->continueOnError = $mode; + } + + return $this->continueOnError; + } + + /** + * Loads an XML schema from a file and converts it to SQL. + * + * Call this method to load the specified schema (see the DTD for the proper format) from + * the filesystem and generate the SQL necessary to create the database described. + * @see ParseSchemaString() + * + * @param string $file Name of XML schema file. + * @param bool $returnSchema Return schema rather than parsing. + * @return array Array of SQL queries, ready to execute + */ + function ParseSchema( $filename, $returnSchema = FALSE ) { + return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema ); + } + + /** + * Loads an XML schema from a file and converts it to SQL. + * + * Call this method to load the specified schema from a file (see the DTD for the proper format) + * and generate the SQL necessary to create the database described by the schema. + * + * @param string $file Name of XML schema file. + * @param bool $returnSchema Return schema rather than parsing. + * @return array Array of SQL queries, ready to execute. + * + * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString() + * @see ParseSchema(), ParseSchemaString() + */ + function ParseSchemaFile( $filename, $returnSchema = FALSE ) { + // Open the file + if( !($fp = fopen( $filename, 'r' )) ) { + // die( 'Unable to open file' ); + return FALSE; + } + + // do version detection here + if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) { + return FALSE; + } + + if ( $returnSchema ) + { + return $xmlstring; + } + + $this->success = 2; + + $xmlParser = $this->create_parser(); + + // Process the file + while( $data = fread( $fp, 4096 ) ) { + if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) { + die( sprintf( + "XML error: %s at line %d", + xml_error_string( xml_get_error_code( $xmlParser) ), + xml_get_current_line_number( $xmlParser) + ) ); + } + } + + xml_parser_free( $xmlParser ); + + return $this->sqlArray; + } + + /** + * Converts an XML schema string to SQL. + * + * Call this method to parse a string containing an XML schema (see the DTD for the proper format) + * and generate the SQL necessary to create the database described by the schema. + * @see ParseSchema() + * + * @param string $xmlstring XML schema string. + * @param bool $returnSchema Return schema rather than parsing. + * @return array Array of SQL queries, ready to execute. + */ + function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) { + if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) { + return FALSE; + } + + // do version detection here + if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) { + return FALSE; + } + + if ( $returnSchema ) + { + return $xmlstring; + } + + $this->success = 2; + + $xmlParser = $this->create_parser(); + + if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) { + die( sprintf( + "XML error: %s at line %d", + xml_error_string( xml_get_error_code( $xmlParser) ), + xml_get_current_line_number( $xmlParser) + ) ); + } + + xml_parser_free( $xmlParser ); + + return $this->sqlArray; + } + + /** + * Loads an XML schema from a file and converts it to uninstallation SQL. + * + * Call this method to load the specified schema (see the DTD for the proper format) from + * the filesystem and generate the SQL necessary to remove the database described. + * @see RemoveSchemaString() + * + * @param string $file Name of XML schema file. + * @param bool $returnSchema Return schema rather than parsing. + * @return array Array of SQL queries, ready to execute + */ + function RemoveSchema( $filename, $returnSchema = FALSE ) { + return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema ); + } + + /** + * Converts an XML schema string to uninstallation SQL. + * + * Call this method to parse a string containing an XML schema (see the DTD for the proper format) + * and generate the SQL necessary to uninstall the database described by the schema. + * @see RemoveSchema() + * + * @param string $schema XML schema string. + * @param bool $returnSchema Return schema rather than parsing. + * @return array Array of SQL queries, ready to execute. + */ + function RemoveSchemaString( $schema, $returnSchema = FALSE ) { + + // grab current version + if( !( $version = $this->SchemaStringVersion( $schema ) ) ) { + return FALSE; + } + + return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema ); + } + + /** + * Applies the current XML schema to the database (post execution). + * + * Call this method to apply the current schema (generally created by calling + * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes, + * and executing other SQL specified in the schema) after parsing. + * @see ParseSchema(), ParseSchemaString(), ExecuteInline() + * + * @param array $sqlArray Array of SQL statements that will be applied rather than + * the current schema. + * @param boolean $continueOnErr Continue to apply the schema even if an error occurs. + * @returns integer 0 if failure, 1 if errors, 2 if successful. + */ + function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) { + if( !is_bool( $continueOnErr ) ) { + $continueOnErr = $this->ContinueOnError(); + } + + if( !isset( $sqlArray ) ) { + $sqlArray = $this->sqlArray; + } + + if( !is_array( $sqlArray ) ) { + $this->success = 0; + } else { + $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr ); + } + + return $this->success; + } + + /** + * Returns the current SQL array. + * + * Call this method to fetch the array of SQL queries resulting from + * ParseSchema() or ParseSchemaString(). + * + * @param string $format Format: HTML, TEXT, or NONE (PHP array) + * @return array Array of SQL statements or FALSE if an error occurs + */ + function PrintSQL( $format = 'NONE' ) { + return $this->getSQL( $format, $sqlArray ); + } + + /** + * Saves the current SQL array to the local filesystem as a list of SQL queries. + * + * Call this method to save the array of SQL queries (generally resulting from a + * parsed XML schema) to the filesystem. + * + * @param string $filename Path and name where the file should be saved. + * @return boolean TRUE if save is successful, else FALSE. + */ + function SaveSQL( $filename = './schema.sql' ) { + + if( !isset( $sqlArray ) ) { + $sqlArray = $this->sqlArray; + } + if( !isset( $sqlArray ) ) { + return FALSE; + } + + $fp = fopen( $filename, "w" ); + + foreach( $sqlArray as $key => $query ) { + fwrite( $fp, $query . ";\n" ); + } + fclose( $fp ); + } + + /** + * Create an xml parser + * + * @return object PHP XML parser object + * + * @access private + */ + function &create_parser() { + // Create the parser + $xmlParser = xml_parser_create(); + xml_set_object( $xmlParser, $this ); + + // Initialize the XML callback functions + xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' ); + xml_set_character_data_handler( $xmlParser, '_tag_cdata' ); + + return $xmlParser; + } + + /** + * XML Callback to process start elements + * + * @access private + */ + function _tag_open( &$parser, $tag, $attributes ) { + switch( strtoupper( $tag ) ) { + case 'TABLE': + $this->obj = new dbTable( $this, $attributes ); + xml_set_object( $parser, $this->obj ); + break; + case 'SQL': + if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) { + $this->obj = new dbQuerySet( $this, $attributes ); + xml_set_object( $parser, $this->obj ); + } + break; + default: + // print_r( array( $tag, $attributes ) ); + } + + } + + /** + * XML Callback to process CDATA elements + * + * @access private + */ + function _tag_cdata( &$parser, $cdata ) { + } + + /** + * XML Callback to process end elements + * + * @access private + * @internal + */ + function _tag_close( &$parser, $tag ) { + + } + + /** + * Converts an XML schema string to the specified DTD version. + * + * Call this method to convert a string containing an XML schema to a different AXMLS + * DTD version. For instance, to convert a schema created for an pre-1.0 version for + * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version + * parameter is specified, the schema will be converted to the current DTD version. + * If the newFile parameter is provided, the converted schema will be written to the specified + * file. + * @see ConvertSchemaFile() + * + * @param string $schema String containing XML schema that will be converted. + * @param string $newVersion DTD version to convert to. + * @param string $newFile File name of (converted) output file. + * @return string Converted XML schema or FALSE if an error occurs. + */ + function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) { + + // grab current version + if( !( $version = $this->SchemaStringVersion( $schema ) ) ) { + return FALSE; + } + + if( !isset ($newVersion) ) { + $newVersion = $this->schemaVersion; + } + + if( $version == $newVersion ) { + $result = $schema; + } else { + $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion); + } + + if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) { + fwrite( $fp, $result ); + fclose( $fp ); + } + + return $result; + } + + /** + * Converts an XML schema file to the specified DTD version. + * + * Call this method to convert the specified XML schema file to a different AXMLS + * DTD version. For instance, to convert a schema created for an pre-1.0 version for + * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version + * parameter is specified, the schema will be converted to the current DTD version. + * If the newFile parameter is provided, the converted schema will be written to the specified + * file. + * @see ConvertSchemaString() + * + * @param string $filename Name of XML schema file that will be converted. + * @param string $newVersion DTD version to convert to. + * @param string $newFile File name of (converted) output file. + * @return string Converted XML schema or FALSE if an error occurs. + */ + function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) { + + // grab current version + if( !( $version = $this->SchemaFileVersion( $filename ) ) ) { + return FALSE; + } + + if( !isset ($newVersion) ) { + $newVersion = $this->schemaVersion; + } + + if( $version == $newVersion ) { + $result = implode('', file( $filename )); + + // remove unicode BOM if present + if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) { + $result = substr( $result, 3 ); + } + } else { + $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' ); + } + + if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) { + fwrite( $fp, $result ); + fclose( $fp ); + } + + return $result; + } + + function TransformSchema( $schema, $xsl, $schematype='string' ) + { + // Fail if XSLT extension is not available + if( ! function_exists( 'xslt_create' ) ) { + return FALSE; + } + + $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl'; + + // look for xsl + if( !is_readable( $xsl_file ) ) { + return FALSE; + } + + switch( $schematype ) + { + case 'file': + if( !is_readable( $schema ) ) { + return FALSE; + } + + $schema = implode('', file( $schema )); + break; + case 'string': + default: + if( !is_string( $schema ) ) { + return FALSE; + } + } + + $arguments = array ( + '/_xml' => $schema, + '/_xsl' => implode('', file( $xsl_file )) + ); + + // create an XSLT processor + $xh = xslt_create (); + + // set error handler + xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler')); + + // process the schema + $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); + + xslt_free ($xh); + + return $result; + } + + /** + * Processes XSLT transformation errors + * + * @param object $parser XML parser object + * @param integer $errno Error number + * @param integer $level Error level + * @param array $fields Error information fields + * + * @access private + */ + function xslt_error_handler( $parser, $errno, $level, $fields ) { + if( is_array( $fields ) ) { + $msg = array( + 'Message Type' => ucfirst( $fields['msgtype'] ), + 'Message Code' => $fields['code'], + 'Message' => $fields['msg'], + 'Error Number' => $errno, + 'Level' => $level + ); + + switch( $fields['URI'] ) { + case 'arg:/_xml': + $msg['Input'] = 'XML'; + break; + case 'arg:/_xsl': + $msg['Input'] = 'XSL'; + break; + default: + $msg['Input'] = $fields['URI']; + } + + $msg['Line'] = $fields['line']; + } else { + $msg = array( + 'Message Type' => 'Error', + 'Error Number' => $errno, + 'Level' => $level, + 'Fields' => var_export( $fields, TRUE ) + ); + } + + $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n" + . '<table>' . "\n"; + + foreach( $msg as $label => $details ) { + $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n"; + } + + $error_details .= '</table>'; + + trigger_error( $error_details, E_USER_ERROR ); + } + + /** + * Returns the AXMLS Schema Version of the requested XML schema file. + * + * Call this method to obtain the AXMLS DTD version of the requested XML schema file. + * @see SchemaStringVersion() + * + * @param string $filename AXMLS schema file + * @return string Schema version number or FALSE on error + */ + function SchemaFileVersion( $filename ) { + // Open the file + if( !($fp = fopen( $filename, 'r' )) ) { + // die( 'Unable to open file' ); + return FALSE; + } + + // Process the file + while( $data = fread( $fp, 4096 ) ) { + if( preg_match( $this->versionRegex, $data, $matches ) ) { + return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION; + } + } + + return FALSE; + } + + /** + * Returns the AXMLS Schema Version of the provided XML schema string. + * + * Call this method to obtain the AXMLS DTD version of the provided XML schema string. + * @see SchemaFileVersion() + * + * @param string $xmlstring XML schema string + * @return string Schema version number or FALSE on error + */ + function SchemaStringVersion( $xmlstring ) { + if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) { + return FALSE; + } + + if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) { + return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION; + } + + return FALSE; + } + + /** + * Extracts an XML schema from an existing database. + * + * Call this method to create an XML schema string from an existing database. + * If the data parameter is set to TRUE, AXMLS will include the data from the database + * in the schema. + * + * @param boolean $data Include data in schema dump + * @return string Generated XML schema + */ + function ExtractSchema( $data = FALSE, $sep_tables = FALSE ) { + $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM ); + + if($sep_tables) + { + $xml_table_array = array(); + $schema_header = '<?xml version="1.0"?>' . "\n" + . '<schema version="' . $this->schemaVersion . '">' . "\n"; + $schema_footer .= '</schema>'; + } + + $schema = '<?xml version="1.0"?>' . "\n" + . '<schema version="' . $this->schemaVersion . '">' . "\n"; + + if( is_array( $tables = $this->dict->MetaTables( 'TABLES' ) ) ) { + foreach( $tables as $table ) { + $schema_temp = ' <table name="' . $table . '">' . "\n"; + + // grab details from database + $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE 1=1' ); + $fields = $this->dict->MetaColumns( $table ); + $indexes = $this->dict->MetaIndexes( $table ); + + if( is_array( $fields ) ) { + foreach( $fields as $details ) { + $extra = ''; + $content = array(); + + if( $details->max_length > 0 ) { + $extra .= ' size="' . $details->max_length . '"'; + } + + if( $details->primary_key ) { + $content[] = '<KEY/>'; + } elseif( $details->not_null ) { + $content[] = '<NOTNULL/>'; + } + + if( $details->has_default ) { + $content[] = '<DEFAULT value="' . $details->default_value . '"/>'; + } + + if( $details->auto_increment ) { + $content[] = '<AUTOINCREMENT/>'; + } + + // this stops the creation of 'R' columns, + // AUTOINCREMENT is used to create auto columns + $details->primary_key = 0; + //$type = $rs->MetaType( $details ); + $type = $this->dict->MetaType($details); + + $schema_temp .= ' <field name="' . $details->name . '" type="' . $type . '"' . $extra . '>'; + + if( !empty( $content ) ) { + $schema_temp .= "\n " . implode( "\n ", $content ) . "\n "; + } + + $schema_temp .= '</field>' . "\n"; + } + } + + if( is_array( $indexes ) ) { + foreach( $indexes as $index => $details ) { + $schema_temp .= ' <index name="' . $index . '">' . "\n"; + + if( $details['unique'] ) { + $schema_temp .= ' <UNIQUE/>' . "\n"; + } + + foreach( $details['columns'] as $column ) { + $schema_temp .= ' <col>' . $column . '</col>' . "\n"; + } + + $schema_temp .= ' </index>' . "\n"; + } + } + + if( $data ) { + $rs = $this->db->Execute( 'SELECT * FROM ' . $table ); + + if( is_object( $rs ) ) { + $schema_temp .= ' <data>' . "\n"; + + while(!$rs->EOF) + { + $row = $rs->fields; + + foreach( $row as $key => $val ) + { + $row[$key] = htmlentities($val); + } + + $schema_temp .= ' <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n"; + $rs->MoveNext(); + } + + $schema_temp .= ' </data>' . "\n"; + } + } + + $schema_temp .= ' </table>' . "\n"; + $schema .= $schema_temp; + $xml_table_array[] = $schema_header . $schema_temp . $schema_footer; + } + } + + $this->db->SetFetchMode( $old_mode ); + + $schema .= '</schema>'; + if($sep_tables) + { + return $xml_table_array; + } + else + { + return $schema; + } + } + + + function ExtractTableSchema($tables, $data = FALSE ) + { + $schema = '<?xml version="1.0"?>' . "\n" + . '<schema version="' . $this->schemaVersion . '">' . "\n"; + + if(is_array($tables)) + { + foreach($tables as $table) + { + $schema .= $this->_ExtractTableSchema($table,$data); + } + } + else + { + $schema .= $this->_ExtractTableSchema($tables,$data); + } + + $schema .= '</schema>'; + return $schema; + + } + function _ExtractTableSchema($table, $data = FALSE ) + { + $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM ); + $schema = ""; + + $schema .= ' <table name="' . $table . '">' . "\n"; + + // grab details from database + $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE 1=1' ); + $fields = $this->dict->MetaColumns( $table ); + $indexes = $this->dict->MetaIndexes( $table ); + + if( is_array( $fields ) ) { + foreach( $fields as $details ) { + $extra = ''; + $content = array(); + + if( $details->max_length > 0 ) { + $extra .= ' size="' . $details->max_length . '"'; + } + + if( $details->primary_key ) { + $content[] = '<KEY/>'; + } elseif( $details->not_null ) { + $content[] = '<NOTNULL/>'; + } + + if( $details->has_default ) { + $content[] = '<DEFAULT value="' . $details->default_value . '"/>'; + } + + if( $details->auto_increment ) { + $content[] = '<AUTOINCREMENT/>'; + } + + // this stops the creation of 'R' columns, + // AUTOINCREMENT is used to create auto columns + $details->primary_key = 0; + //$type = $rs->MetaType( $details ); + $type = $this->dict->MetaType($details); + + $schema .= ' <field name="' . $details->name . '" type="' . $type . '"' . $extra . '>'; + + if( !empty( $content ) ) { + $schema .= "\n " . implode( "\n ", $content ) . "\n "; + } + + $schema .= '</field>' . "\n"; + } + } + + if( is_array( $indexes ) ) { + foreach( $indexes as $index => $details ) { + $schema .= ' <index name="' . $index . '">' . "\n"; + + if( $details['unique'] ) { + $schema .= ' <UNIQUE/>' . "\n"; + } + + foreach( $details['columns'] as $column ) { + $schema .= ' <col>' . $column . '</col>' . "\n"; + } + + $schema .= ' </index>' . "\n"; + } + } + + if( $data ) { + $rs = $this->db->Execute( 'SELECT * FROM ' . $table ); + + if( is_object( $rs ) ) { + $schema .= ' <data>' . "\n"; + + while(!$rs->EOF) + { + $row = $rs->fields; + + foreach( $row as $key => $val ) + { + $row[$key] = htmlentities($val); + } + + $schema .= ' <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n"; + $rs->MoveNext(); + } + + $schema .= ' </data>' . "\n"; + } + } + + $schema .= ' </table>' . "\n"; + + + + $this->db->SetFetchMode( $old_mode ); + return $schema; + } + + /** + * Sets a prefix for database objects + * + * Call this method to set a standard prefix that will be prepended to all database tables + * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix. + * + * @param string $prefix Prefix that will be prepended. + * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix. + * @return boolean TRUE if successful, else FALSE + */ + function SetPrefix( $prefix = '', $underscore = TRUE ) { + switch( TRUE ) { + // clear prefix + case empty( $prefix ): + logMsg( 'Cleared prefix' ); + $this->objectPrefix = ''; + return TRUE; + // prefix too long + case strlen( $prefix ) > XMLS_PREFIX_MAXLEN: + // prefix contains invalid characters + case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ): + logMsg( 'Invalid prefix: ' . $prefix ); + return FALSE; + } + + if( $underscore AND substr( $prefix, -1 ) != '_' ) { + $prefix .= '_'; + } + + // prefix valid + logMsg( 'Set prefix: ' . $prefix ); + $this->objectPrefix = $prefix; + return TRUE; + } + + /** + * Returns an object name with the current prefix prepended. + * + * @param string $name Name + * @return string Prefixed name + * + * @access private + */ + function prefix( $name = '' ) { + // if prefix is set + if( !empty( $this->objectPrefix ) ) { + // Prepend the object prefix to the table name + // prepend after quote if used + return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name ); + } + + // No prefix set. Use name provided. + return $name; + } + + /** + * Checks if element references a specific platform + * + * @param string $platform Requested platform + * @returns boolean TRUE if platform check succeeds + * + * @access private + */ + function supportedPlatform( $platform = NULL ) { + $regex = '/^(\w*\|)*' . $this->db->dbtype . '(\|\w*)*$/'; + + if( !isset( $platform ) OR preg_match( $regex, $platform ) ) { + logMsg( "Platform $platform is supported" ); + return TRUE; + } else { + logMsg( "Platform $platform is NOT supported" ); + return FALSE; + } + } + + /** + * Clears the array of generated SQL. + * + * @access private + */ + function clearSQL() { + $this->sqlArray = array(); + } + + /** + * Adds SQL into the SQL array. + * + * @param mixed $sql SQL to Add + * @return boolean TRUE if successful, else FALSE. + * + * @access private + */ + function addSQL( $sql = NULL ) { + if( is_array( $sql ) ) { + foreach( $sql as $line ) { + $this->addSQL( $line ); + } + + return TRUE; + } + + if( is_string( $sql ) ) { + $this->sqlArray[] = $sql; + + // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL. + if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) { + $saved = $this->db->debug; + $this->db->debug = $this->debug; + $ok = $this->db->Execute( $sql ); + $this->db->debug = $saved; + + if( !$ok ) { + if( $this->debug ) { + ADOConnection::outp( $this->db->ErrorMsg() ); + } + + $this->success = 1; + } + } + + return TRUE; + } + + return FALSE; + } + + /** + * Gets the SQL array in the specified format. + * + * @param string $format Format + * @return mixed SQL + * + * @access private + */ + function getSQL( $format = NULL, $sqlArray = NULL ) { + if( !is_array( $sqlArray ) ) { + $sqlArray = $this->sqlArray; + } + + if( !is_array( $sqlArray ) ) { + return FALSE; + } + + switch( strtolower( $format ) ) { + case 'string': + case 'text': + return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : ''; + case'html': + return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : ''; + } + + return $this->sqlArray; + } + + /** + * Destroys an adoSchema object. + * + * Call this method to clean up after an adoSchema object that is no longer... [truncated message content] |
From: <p3...@us...> - 2007-08-01 15:11:10
|
Revision: 82 http://astrospaces.svn.sourceforge.net/astrospaces/?rev=82&view=rev Author: p3net Date: 2007-08-01 08:11:05 -0700 (Wed, 01 Aug 2007) Log Message: ----------- Rename session.php to user.php and change the class call to . I think I got all of the calls, if not, please fix them as you find the problems. Added Paths: ----------- trunk/functions/user.php Removed Paths: ------------- trunk/functions/session.php Deleted: trunk/functions/session.php =================================================================== --- trunk/functions/session.php 2007-08-01 00:15:01 UTC (rev 81) +++ trunk/functions/session.php 2007-08-01 15:11:05 UTC (rev 82) @@ -1,434 +0,0 @@ -<?php -/******************************************************* - * Copyright (C) 2007 http://p3net.net - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - @id: $Id$ -*********************************************************/ -/******************************************************** -The name here is a bit of a misnomer. The session class -handles all user-interaction related processes -- both -interaction between user and server and interaction -between user and user -**********************************************************/ -class session -{ - /* - Function Name: create - Arguments: none - Purpose: create session - */ - function create() - { - /* We don't have a session and aren't logged in. Let's create it */ - $id = md5(time() . rand(1,1000)); - /* Check to make sure it's unique */ - $_query = 'INSERT INTO '.AS_TBL_SESSION.' (id, user_id, ip, last_update) VALUES(' . $id . ','.$db->qstr('-1').',' . $db->qstr($_SERVER['REMOTE_ADDR']) . ',' . time() . ')'; - if ($db->Execute($_query) === false) - { - $error->general('<b>DB Error!</b>', 'session.php - create(): '.$db->ErrorMsg()); - return false; - } - $_COOKIE['session_id'] = $id; - } - /* - Function Name: check - Arguments: none - Purpose: Check if a session exists - */ - function check() - { - /* We need to check if a session exists by looking for the session cookie. If that's not there, - then we return false (since the user isn't logged in). We also match the IP */ - $ip = $_SERVER['REMOTE_ADDR']; - $_query = 'SELECT * FROM '.AS_TBL_SESSION.' WHERE ip = ' . $db->qstr($ip); - $res = $db->Execute($_query); - $count = $res->RecordCount(); - if($count == 0) - { - $session->create(); - } - else - { - /* Get an array of our session info */ - $res = $res->GetArray(); - if($res[0]['id'] != $_COOKIE['session_id']) - { - $session->create(); - } - else - { - $array = $res->GetArray(); - foreach($array[0] as $key => $value) - { - if (!is_numeric($key)) - { - $user->data[$key] = $value; - } - } - /* Update our updated time */ - $_query = 'UPDATE '.AS_TBL_SESSION.' SET last_update = ' . time() . ' WHERE id = ' . $user->data['id'] . ' LIMIT 1'; - if ($db->Execute($_query) === false) - { - $error->general('<b>DB Error!</b>', 'session.php - check(): '.$db->ErrorMsg()); - return false; - } - } - } - /* We also need to get rid of users who haven't done anything in the last half-hour */ - $_query = 'DELETE FROM '.AS_TBL_SESSION.' WHERE last_update < ' . (time() - (60*30)); - if ($db->Execute($_query) === false) - { - $error->general('<b>DB Error!</b>', 'session.php - check(): '.$db->ErrorMsg()); - return false; - } - } - /* - Function Name: logged_in - Arguments: none - Purpose: check if user is logged in - */ - function logged_in() - { - if($user->data['id'] != "-1") - { - return true; - } - else - { - return false; - } - } - /* - Function Name: login - Arguments: (int) user_id -- ID of user to login - Purpose: Updates session table to reflect that a user is logged in - */ - function login($user_id) - { - if (!is_numeric($user_id) and $user_id != null) - { - $error->general('Invalid userID', "Invalid userID = Possible hack! Input value: \"".$user_id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - $session->check(); - if($session->logged_in()) - { - /* Wait - what? */ - $error->general("Already logged in", "Session already populated"); - } - else - { - $_query = 'UPDATE '.AS_TBL_SESSION.' SET user_id = ' . $user_id . ' WHERE id = ' . $db->qstr($_COOKIE["session_id"]) . ' LIMIT 1'; - if ($db->Execute($_query) === false) - { - $error->general('<b>DB Error!</b>', 'session.php - login(): '.$db->ErrorMsg()); - return false; - } - /* Run the session check again. It'll make the row and populate $user->data */ - $session->check(); - } - } - /* - Function Name: logout - Arguments: none - Purpose: Edit session table to reflect that user is logged out - */ - function logout() - { - if($session->logged_in()) - { - $_query = 'UPDATE '.AS_TBL_SESSION.' SET user_id = '.$db->qstr('-1').' WHERE id = ' . $user->data['id'] . ' AND ip = ' . $db->qstr($user->data['ip']) . ' LIMIT 1'; - $db->query($_query); - $user->data = null; - } - else - { - $error->general('Not logged in', 'User ID = -1'); - } - } - /* - Function Name: is_friend - Arguments: (int) id -- ID of our suspected friend - Purpose: Check if user is your friend - */ - function is_friend($id) - { - if (!is_numeric($id)) - { - $error->general('Invalid userID', "Invalid userID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - if(!$user->logged_in()) - { - return false; - } - else - { - $_query = 'SELECT count(*) FROM '.AS_TBL_FRIEND.' WHERE party_1 = ' . $user->data['user_id'] . ' AND party_2 = ' . $id . ' AND accepted = 1'; - $_query = $db->Execute($_query); - if($_query->fields[0] > 0) - { - return true; - } - else - { - $_query = 'SELECT count(*) FROM '.AS_TBL_FRIEND.' WHERE party_2 = ' . $user->data['user_id'] . ' AND party_1 = ' . $id . ' AND accepted = 1'; - $_query = $db->Execute($_query); - if($_query->fields[0] > 0) - { - return true; - } - else - { - return false; - } - } - } - } - /* - Function Name: action - Arguments: (int) action -- Add action to action table; (int) who -- ID of friend action is made towards. If unspecified, applies to all - Purpose: - */ - function action($action, $who = null) - { - if (!is_numeric($action) and $action != null) - { - $error->general('Invalid actionID', "Invalid actionID = Possible hack! Input value: \"".$action."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - - if (!is_numeric($who) and $who != null) - { - $error->general('Invalid whoID', "Invalid whoID = Possible hack! Input value: \"".$who."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - /*List of actions: - 1. Updated Space - 2. Left you a comment - 3. Left a comment on one of your pictures - 4. Uploaded a picture - 5. Added you as a friend - 6. New blog post - 7. Left you a comment on a blog post - 8. Joined a group - 9. Created a group */ - $_query = 'INSERT INTO '.AS_TBL_ACTION.' (time, who, action, for) VALUES(' . time() . ',' . $user->data['user_id'] . ', ' . $action . ', ' . $who . ')'; - $db->query($_query); - return true; - } - /* - Function Name: add_friend - Arguments: (int) id -- ID of user to add as our friend - Purpose: Add user as (unapproved) friend - */ - function add_friend($id) - { - if (!is_numeric($id) and $id != null) - { - $error->general('Invalid friendID', "Invalid friendID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - - if(!$user->logged_in()) - { - $error->general("Not logged in", "Add as friend"); - } - else - { - if($user->is_friend($id)) - { - $error->general("Already friend", "Add as friend"); - } - else - { - $_query = 'SELECT count(*) FROM '.AS_TBL_FRIEND.' WHERE (party_1 = ' . $user->data['user_id'] . ' AND party_2 = ' . $id; - $_query = $db->query($_query); - if ($_query->fields[0] > 0) - { - $error->general("Already added as friend, awaiting acception", "Add as friend"); - } - else - { - $_query = 'SELECT count(*) FROM '.AS_TBL_FRIEND.' WHERE party_2 = ' . $user->data['user_id'] . ' AND party_1 = ' . $id; - $_query = $db->Execute($_query); - if ($_query->fields[0] > 0) - { - $error->general("User has already added you as a friend. Accept them in your friend control panel.", "Add as friend"); - } - else - { - $_query='INSERT INTO '.AS_TBL_FRIEND.' VALUES(' . $user->data['user_id'] . ',' . $id . ',0)'; - if ($db->Execute($_query) === false) - { - $error->general('<b>DB Error!</b>', 'session.php - add_friend(): '.$db->ErrorMsg()); - return false; - } - $message->thank("adding this user as your friend. You will be alerted when they accept you as a friend.", "to go back", "javascript:history.go(-1)"); - } - } - } - } - } - /* - Function Name: accept_friend - Arguments: (int) id -- ID of user to accept as friend - Purpose: Accept friend - */ - function accept_friend($id) - { - if (!is_numeric($id) and $id != null) - { - $error->general('Invalid friendID', "Invalid friendID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - $_query= 'UPDATE '.AS_TBL_FRIEND.' SET accepted = 1 WHERE party_2 = '.$data->user['user_id'].' AND party_1 = '.$id.' LIMIT 1'; - $db->query($_query); - $user->action(5, $id); - } - /* - Function Name: can_view - Arguments: (int) id -- ID of user who permissions are being checked for - Purpose: Check if we have permissions to view this users space - */ - function can_view($id) - { - if (!is_numeric($id) and $id != null) - { - $error->general('Invalid friendID', "Invalid friendID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - /*We're simply checking whether or not we have the permissions to view this space */ - /*First we need to figure out what the space privacy setting is*/ - $_query = 'SELECT privacy FROM '.AS_TBL_USER.' WHERE id = ' . $id . ' LIMIT 1'; - $_query = $db->Execute($_query); - $_query = $db->GetArray($_query); - $res = $_query[0]['privacy']; - if($res == '0') - { - /* All users can view this space */ - return true; - } - else - { - /* We need to check if we're they're friend */ - if($session->is_friend($id)) - { - return true; - } - else - { - return false; - } - } - } - /* - Function Name: add_coment - Arguments: (int) id -- ID of user who comment is directed to - Purpose: Add comment - */ - function add_comment($id) - { - if (!is_numeric($id) and $id != null) - { - $error->general('Invalid userID', "Invalid userD = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - if($session->is_friend($id)) - { - /* Okay, we have permission to leave this comment */ - $_query = 'INSERT INTO '.AS_TBL_CMT.' (comment_timestamp, poster_id, recipient_id, comment) VALUES(' . - time() . ',' . $user->data['user_id'] . ',' . $id . ',' . $db->qstr($_POST['body']).')'; - if ($db->Execute($_query) === false) - { - $error->general('<b>DB Error!</b>', 'session.php - add_comment(): '.$db->ErrorMsg()); - return false; - } - $session->action('2', $id); - } - } - /* - Function Name: get_username - Arguments: (int) id -- User ID - Purpose: Fetch username of user based on their unique ID - */ - function get_username($id) - { - if (!is_numeric($id) and $id != null) - { - $error->general('Invalid userID', "Invalid userID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - $_query = 'SELECT display_name FROM '.AS_TBL_USER.' WHERE id = ' . $id; - $_query = $db->Execute($_query); - $res = $db->GetArray($_query); - return $res[0]['display_name']; - } - /* - Function Name: add_image_comment - Arguments: (int) id -- Image ID - Purpose: Add comment to image - */ - function add_image_comment($id) - { - if (!is_numeric($id) and $id != null) - { - $error->general('Invalid imageID', "Invalid imageID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - - $owner = 'SELECT owner_id FROM '.AS_TBL_IMG.' WHERE id = ' . $id; - $owner = $db->query($owner); - $owner = $db->fetch_array($owner); - $owner = $owner['owner']; - if ($session->is_friend($owner)) - { - $_query = 'INSERT INTO '.AS_TBL_IMG_CMT.' (image_id, post_timestamp, author, comment) VALUES('. $id . ',' . time() . ',' . $user->data['user_id'] . ',' . $db->qstr($_POST['comment'],get_magic_quotes_gpc()) . ')'; - if ($db->Execute($_query) === false) - { - $error->general('<b>DB Error!</b>', 'session.php - add_img_comment(): '.$db->ErrorMsg()); - return false; - } - } - } - /* - Function Name: generate_timestamp - Arguments: (int) time -- time to parse - Purpose: Generate datestamp of time passed, taking user's time offset into consideration - */ - function generate_timestamp($time) - { - if (!is_numeric($time) and $time != null) - { - $error->general('Invalid timestamp', "Invalid timestamp = Possible hack! Input value: \"".$time."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); - return false; - } - - if($session->logged_in()) - { - $_query = 'SELECT time_offset FROM '.AS_TBL_USER.' WHERE id = ' . $user->data['user_id']; - $_query = $db->Execute($_query); - $_query = $query->GetArray($_query); - $offset = $_query[0]['time_offset']; - - $diff = $offset * 60 * 60; - } - $time = $time + $diff; - return date('m/d/Y G:i:s', $time); - } -} -?> \ No newline at end of file Copied: trunk/functions/user.php (from rev 78, trunk/functions/session.php) =================================================================== --- trunk/functions/user.php (rev 0) +++ trunk/functions/user.php 2007-08-01 15:11:05 UTC (rev 82) @@ -0,0 +1,428 @@ +<?php +/******************************************************* + * Copyright (C) 2007 http://p3net.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @id: $Id$ +*********************************************************/ +class user +{ + /* + Function Name: create + Arguments: none + Purpose: create session + */ + function create() + { + /* We don't have a session and aren't logged in. Let's create it */ + $id = md5(time() . rand(1,1000)); + /* Check to make sure it's unique */ + $_query = 'INSERT INTO '.AS_TBL_SESSION.' (id, user_id, ip, last_update) VALUES(' . $id . ','.$db->qstr('-1').',' . $db->qstr($_SERVER['REMOTE_ADDR']) . ',' . time() . ')'; + if ($db->Execute($_query) === false) + { + $error->general('<b>DB Error!</b>', 'session.php - create(): '.$db->ErrorMsg()); + return false; + } + $_COOKIE['session_id'] = $id; + } + /* + Function Name: check + Arguments: none + Purpose: Check if a session exists + */ + function check() + { + /* We need to check if a session exists by looking for the session cookie. If that's not there, + then we return false (since the user isn't logged in). We also match the IP */ + $ip = $_SERVER['REMOTE_ADDR']; + $_query = 'SELECT * FROM '.AS_TBL_SESSION.' WHERE ip = ' . $db->qstr($ip); + $res = $db->Execute($_query); + $count = $res->RecordCount(); + if($count == 0) + { + $session->create(); + } + else + { + /* Get an array of our session info */ + $res = $res->GetArray(); + if($res[0]['id'] != $_COOKIE['session_id']) + { + $session->create(); + } + else + { + $array = $res->GetArray(); + foreach($array[0] as $key => $value) + { + if (!is_numeric($key)) + { + $user->data[$key] = $value; + } + } + /* Update our updated time */ + $_query = 'UPDATE '.AS_TBL_SESSION.' SET last_update = ' . time() . ' WHERE id = ' . $user->data['id'] . ' LIMIT 1'; + if ($db->Execute($_query) === false) + { + $error->general('<b>DB Error!</b>', 'session.php - check(): '.$db->ErrorMsg()); + return false; + } + } + } + /* We also need to get rid of users who haven't done anything in the last half-hour */ + $_query = 'DELETE FROM '.AS_TBL_SESSION.' WHERE last_update < ' . (time() - (60*30)); + if ($db->Execute($_query) === false) + { + $error->general('<b>DB Error!</b>', 'session.php - check(): '.$db->ErrorMsg()); + return false; + } + } + /* + Function Name: logged_in + Arguments: none + Purpose: check if user is logged in + */ + function logged_in() + { + if($user->data['id'] != "-1") + { + return true; + } + else + { + return false; + } + } + /* + Function Name: login + Arguments: (int) user_id -- ID of user to login + Purpose: Updates session table to reflect that a user is logged in + */ + function login($user_id) + { + if (!is_numeric($user_id) and $user_id != null) + { + $error->general('Invalid userID', "Invalid userID = Possible hack! Input value: \"".$user_id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + $session->check(); + if($session->logged_in()) + { + /* Wait - what? */ + $error->general("Already logged in", "Session already populated"); + } + else + { + $_query = 'UPDATE '.AS_TBL_SESSION.' SET user_id = ' . $user_id . ' WHERE id = ' . $db->qstr($_COOKIE["session_id"]) . ' LIMIT 1'; + if ($db->Execute($_query) === false) + { + $error->general('<b>DB Error!</b>', 'session.php - login(): '.$db->ErrorMsg()); + return false; + } + /* Run the session check again. It'll make the row and populate $user->data */ + $session->check(); + } + } + /* + Function Name: logout + Arguments: none + Purpose: Edit session table to reflect that user is logged out + */ + function logout() + { + if($session->logged_in()) + { + $_query = 'UPDATE '.AS_TBL_SESSION.' SET user_id = '.$db->qstr('-1').' WHERE id = ' . $user->data['id'] . ' AND ip = ' . $db->qstr($user->data['ip']) . ' LIMIT 1'; + $db->query($_query); + $user->data = null; + } + else + { + $error->general('Not logged in', 'User ID = -1'); + } + } + /* + Function Name: is_friend + Arguments: (int) id -- ID of our suspected friend + Purpose: Check if user is your friend + */ + function is_friend($id) + { + if (!is_numeric($id)) + { + $error->general('Invalid userID', "Invalid userID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + if(!$user->logged_in()) + { + return false; + } + else + { + $_query = 'SELECT count(*) FROM '.AS_TBL_FRIEND.' WHERE party_1 = ' . $user->data['user_id'] . ' AND party_2 = ' . $id . ' AND accepted = 1'; + $_query = $db->Execute($_query); + if($_query->fields[0] > 0) + { + return true; + } + else + { + $_query = 'SELECT count(*) FROM '.AS_TBL_FRIEND.' WHERE party_2 = ' . $user->data['user_id'] . ' AND party_1 = ' . $id . ' AND accepted = 1'; + $_query = $db->Execute($_query); + if($_query->fields[0] > 0) + { + return true; + } + else + { + return false; + } + } + } + } + /* + Function Name: action + Arguments: (int) action -- Add action to action table; (int) who -- ID of friend action is made towards. If unspecified, applies to all + Purpose: + */ + function action($action, $who = null) + { + if (!is_numeric($action) and $action != null) + { + $error->general('Invalid actionID', "Invalid actionID = Possible hack! Input value: \"".$action."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + + if (!is_numeric($who) and $who != null) + { + $error->general('Invalid whoID', "Invalid whoID = Possible hack! Input value: \"".$who."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + /*List of actions: + 1. Updated Space + 2. Left you a comment + 3. Left a comment on one of your pictures + 4. Uploaded a picture + 5. Added you as a friend + 6. New blog post + 7. Left you a comment on a blog post + 8. Joined a group + 9. Created a group */ + $_query = 'INSERT INTO '.AS_TBL_ACTION.' (time, who, action, for) VALUES(' . time() . ',' . $user->data['user_id'] . ', ' . $action . ', ' . $who . ')'; + $db->query($_query); + return true; + } + /* + Function Name: add_friend + Arguments: (int) id -- ID of user to add as our friend + Purpose: Add user as (unapproved) friend + */ + function add_friend($id) + { + if (!is_numeric($id) and $id != null) + { + $error->general('Invalid friendID', "Invalid friendID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + + if(!$user->logged_in()) + { + $error->general("Not logged in", "Add as friend"); + } + else + { + if($user->is_friend($id)) + { + $error->general("Already friend", "Add as friend"); + } + else + { + $_query = 'SELECT count(*) FROM '.AS_TBL_FRIEND.' WHERE (party_1 = ' . $user->data['user_id'] . ' AND party_2 = ' . $id; + $_query = $db->query($_query); + if ($_query->fields[0] > 0) + { + $error->general("Already added as friend, awaiting acception", "Add as friend"); + } + else + { + $_query = 'SELECT count(*) FROM '.AS_TBL_FRIEND.' WHERE party_2 = ' . $user->data['user_id'] . ' AND party_1 = ' . $id; + $_query = $db->Execute($_query); + if ($_query->fields[0] > 0) + { + $error->general("User has already added you as a friend. Accept them in your friend control panel.", "Add as friend"); + } + else + { + $_query='INSERT INTO '.AS_TBL_FRIEND.' VALUES(' . $user->data['user_id'] . ',' . $id . ',0)'; + if ($db->Execute($_query) === false) + { + $error->general('<b>DB Error!</b>', 'session.php - add_friend(): '.$db->ErrorMsg()); + return false; + } + $message->thank("adding this user as your friend. You will be alerted when they accept you as a friend.", "to go back", "javascript:history.go(-1)"); + } + } + } + } + } + /* + Function Name: accept_friend + Arguments: (int) id -- ID of user to accept as friend + Purpose: Accept friend + */ + function accept_friend($id) + { + if (!is_numeric($id) and $id != null) + { + $error->general('Invalid friendID', "Invalid friendID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + $_query= 'UPDATE '.AS_TBL_FRIEND.' SET accepted = 1 WHERE party_2 = '.$data->user['user_id'].' AND party_1 = '.$id.' LIMIT 1'; + $db->query($_query); + $user->action(5, $id); + } + /* + Function Name: can_view + Arguments: (int) id -- ID of user who permissions are being checked for + Purpose: Check if we have permissions to view this users space + */ + function can_view($id) + { + if (!is_numeric($id) and $id != null) + { + $error->general('Invalid friendID', "Invalid friendID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + /*We're simply checking whether or not we have the permissions to view this space */ + /*First we need to figure out what the space privacy setting is*/ + $_query = 'SELECT privacy FROM '.AS_TBL_USER.' WHERE id = ' . $id . ' LIMIT 1'; + $_query = $db->Execute($_query); + $_query = $db->GetArray($_query); + $res = $_query[0]['privacy']; + if($res == '0') + { + /* All users can view this space */ + return true; + } + else + { + /* We need to check if we're they're friend */ + if($session->is_friend($id)) + { + return true; + } + else + { + return false; + } + } + } + /* + Function Name: add_coment + Arguments: (int) id -- ID of user who comment is directed to + Purpose: Add comment + */ + function add_comment($id) + { + if (!is_numeric($id) and $id != null) + { + $error->general('Invalid userID', "Invalid userD = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + if($session->is_friend($id)) + { + /* Okay, we have permission to leave this comment */ + $_query = 'INSERT INTO '.AS_TBL_CMT.' (comment_timestamp, poster_id, recipient_id, comment) VALUES(' . + time() . ',' . $user->data['user_id'] . ',' . $id . ',' . $db->qstr($_POST['body']).')'; + if ($db->Execute($_query) === false) + { + $error->general('<b>DB Error!</b>', 'session.php - add_comment(): '.$db->ErrorMsg()); + return false; + } + $session->action('2', $id); + } + } + /* + Function Name: get_username + Arguments: (int) id -- User ID + Purpose: Fetch username of user based on their unique ID + */ + function get_username($id) + { + if (!is_numeric($id) and $id != null) + { + $error->general('Invalid userID', "Invalid userID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + $_query = 'SELECT display_name FROM '.AS_TBL_USER.' WHERE id = ' . $id; + $_query = $db->Execute($_query); + $res = $db->GetArray($_query); + return $res[0]['display_name']; + } + /* + Function Name: add_image_comment + Arguments: (int) id -- Image ID + Purpose: Add comment to image + */ + function add_image_comment($id) + { + if (!is_numeric($id) and $id != null) + { + $error->general('Invalid imageID', "Invalid imageID = Possible hack! Input value: \"".$id."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + + $owner = 'SELECT owner_id FROM '.AS_TBL_IMG.' WHERE id = ' . $id; + $owner = $db->query($owner); + $owner = $db->fetch_array($owner); + $owner = $owner['owner']; + if ($session->is_friend($owner)) + { + $_query = 'INSERT INTO '.AS_TBL_IMG_CMT.' (image_id, post_timestamp, author, comment) VALUES('. $id . ',' . time() . ',' . $user->data['user_id'] . ',' . $db->qstr($_POST['comment'],get_magic_quotes_gpc()) . ')'; + if ($db->Execute($_query) === false) + { + $error->general('<b>DB Error!</b>', 'session.php - add_img_comment(): '.$db->ErrorMsg()); + return false; + } + } + } + /* + Function Name: generate_timestamp + Arguments: (int) time -- time to parse + Purpose: Generate datestamp of time passed, taking user's time offset into consideration + */ + function generate_timestamp($time) + { + if (!is_numeric($time) and $time != null) + { + $error->general('Invalid timestamp', "Invalid timestamp = Possible hack! Input value: \"".$time."\" User Hostname: ".$_SERVER['REMOTE_ADDR']); + return false; + } + + if($session->logged_in()) + { + $_query = 'SELECT time_offset FROM '.AS_TBL_USER.' WHERE id = ' . $user->data['user_id']; + $_query = $db->Execute($_query); + $_query = $query->GetArray($_query); + $offset = $_query[0]['time_offset']; + + $diff = $offset * 60 * 60; + } + $time = $time + $diff; + return date('m/d/Y G:i:s', $time); + } +} +?> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |