Add new directory structure. Tags will contain current and past releases, and stable will contain any bug fixes to the current stable release so users won't have to get the potentially broken trunk build to fix a screwup in stable.
Trunk updated to 0.9 git-svn-id: http://kusabax.cultnet.net/svn/repo/stable@176 73d99b7e-4f53-4972-b7b7-2ecd3c4d89ee
This commit is contained in:
commit
88bacfad9c
316 files changed
+79806
No files matched your search
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
V4.65 22 July 2005 (c) 2000-2005 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.
|
||||
|
||||
Modified 28 August, 2005 for use with ADOdb Lite by Mark Dickenson
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_mysql extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'mysql';
|
||||
var $alterCol = ' MODIFY COLUMN';
|
||||
var $alterTableAddIndex = true;
|
||||
var $dropTable = 'DROP TABLE IF EXISTS %s'; // requires mysql 3.22 or later
|
||||
|
||||
var $dropIndex = 'DROP INDEX %s ON %s';
|
||||
var $renameColumn = 'ALTER TABLE %s CHANGE COLUMN %s %s %s'; // needs column-definition!
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch(strtoupper($meta)) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':return 'LONGTEXT';
|
||||
case 'X': return 'TEXT';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'LONGTEXT';
|
||||
|
||||
case 'B': return 'LONGBLOB';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'DT': return 'DATETIME';
|
||||
case 'T': return 'TIME';
|
||||
case 'TS': return 'TIMESTAMP';
|
||||
case 'L': return 'TINYINT';
|
||||
|
||||
case 'R':
|
||||
case 'I4':
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'TINYINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I8': return 'BIGINT';
|
||||
|
||||
case 'F': return 'DOUBLE';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
|
||||
{
|
||||
$suffix = '';
|
||||
if ($funsigned) $suffix .= ' UNSIGNED';
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fautoinc) $suffix .= ' AUTO_INCREMENT';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
|
||||
if ($this->alterTableAddIndex) $sql[] = "ALTER TABLE $tabname DROP INDEX $idxname";
|
||||
else $sql[] = sprintf($this->dropIndex, $idxname, $tabname);
|
||||
|
||||
if ( isset($idxoptions['DROP']) )
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if ( empty ($flds) ) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if (isset($idxoptions['FULLTEXT'])) {
|
||||
$unique = ' FULLTEXT';
|
||||
} elseif (isset($idxoptions['UNIQUE'])) {
|
||||
$unique = ' UNIQUE';
|
||||
} else {
|
||||
$unique = '';
|
||||
}
|
||||
|
||||
if ( is_array($flds) ) $flds = implode(', ',$flds);
|
||||
|
||||
if ($this->alterTableAddIndex) $s = "ALTER TABLE $tabname ADD $unique INDEX $idxname ";
|
||||
else $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname;
|
||||
|
||||
$s .= ' (' . $flds . ')';
|
||||
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
|
||||
$sql[] = $s;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,321 @@
|
||||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for Mysql
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
eval('class mysql_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysql_date_ADOConnection extends mysql_date_EXTENDER
|
||||
{
|
||||
var $fmtDate = "'Y-m-d'"; /// used by DBDate() as the default date format used by the database
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
var $emptyDate = ' ';
|
||||
var $emptyTimeStamp = ' ';
|
||||
var $sysDate = 'CURDATE()';
|
||||
var $sysTimeStamp = 'NOW()';
|
||||
var $isoDates = true; // accepts dates in ISO format
|
||||
|
||||
function Time()
|
||||
{
|
||||
$rs =& $this->_Execute("select $this->sysTimeStamp");
|
||||
if ($rs && !$rs->EOF)
|
||||
return $this->UnixTimeStamp(reset($rs->fields));
|
||||
else return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
|
||||
$fraction = $dayFraction * 24 * 3600;
|
||||
return "from_unixtime(unix_timestamp($date)+$fraction)";
|
||||
}
|
||||
|
||||
function SetDateLocale($locale = 'En')
|
||||
{
|
||||
$this->locale = $locale;
|
||||
switch (strtoupper($locale))
|
||||
{
|
||||
case 'EN':
|
||||
$this->fmtDate="'Y-m-d'";
|
||||
$this->fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
break;
|
||||
|
||||
case 'US':
|
||||
$this->fmtDate = "'m-d-Y'";
|
||||
$this->fmtTimeStamp = "'m-d-Y H:i:s'";
|
||||
break;
|
||||
|
||||
case 'NL':
|
||||
case 'FR':
|
||||
case 'RO':
|
||||
case 'IT':
|
||||
$this->fmtDate="'d-m-Y'";
|
||||
$this->fmtTimeStamp = "'d-m-Y H:i:s'";
|
||||
break;
|
||||
|
||||
case 'GE':
|
||||
$this->fmtDate="'d.m.Y'";
|
||||
$this->fmtTimeStamp = "'d.m.Y H:i:s'";
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->fmtDate="'Y-m-d'";
|
||||
$this->fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function DBDate($date)
|
||||
{
|
||||
if (empty($date) && $date !== 0)
|
||||
return 'null';
|
||||
|
||||
if (is_string($date) && !is_numeric($date)) {
|
||||
if ($date === 'null' || strncmp($date, "'", 1) === 0)
|
||||
return $date;
|
||||
|
||||
if ($this->isoDates)
|
||||
return "'$date'";
|
||||
|
||||
$date = $this->UnixDate($date);
|
||||
}
|
||||
return adodb_date($this->fmtDate, $date);
|
||||
}
|
||||
|
||||
function DBTimeStamp($timestamp)
|
||||
{
|
||||
if (empty($timestamp) && $timestamp !== 0)
|
||||
return 'null';
|
||||
|
||||
# strlen(14) allows YYYYMMDDHHMMSS format
|
||||
if (!is_string($timestamp) || (is_numeric($timestamp) && strlen($timestamp)<14))
|
||||
return adodb_date($this->fmtTimeStamp, $timestamp);
|
||||
|
||||
if ($timestamp === 'null')
|
||||
return $timestamp;
|
||||
|
||||
if ($this->isoDates && strlen($timestamp) !== 14)
|
||||
return "'$timestamp'";
|
||||
|
||||
return adodb_date($this->fmtTimeStamp, $this->UnixTimeStamp($timestamp));
|
||||
}
|
||||
|
||||
function UnixDate($v)
|
||||
{
|
||||
if (is_object($v)) {
|
||||
// odbtp support
|
||||
//( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 )
|
||||
return adodb_mktime($v->hour, $v->minute, $v->second, $v->month, $v->day, $v->year);
|
||||
}
|
||||
if (is_numeric($v) && strlen($v) !== 8)
|
||||
return $v;
|
||||
|
||||
if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", ($v), $rr))
|
||||
return false;
|
||||
|
||||
if ($rr[1] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
// h-m-s-MM-DD-YY
|
||||
return adodb_mktime(0, 0, 0, $rr[2], $rr[3], $rr[1]);
|
||||
}
|
||||
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
if (is_object($v)) {
|
||||
// odbtp support
|
||||
//( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 )
|
||||
return adodb_mktime($v->hour, $v->minute, $v->second, $v->month, $v->day, $v->year);
|
||||
}
|
||||
|
||||
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}))?|", ($v), $rr))
|
||||
return false;
|
||||
|
||||
if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1)
|
||||
return 0;
|
||||
|
||||
// h-m-s-MM-DD-YY
|
||||
if (!isset($rr[5]))
|
||||
return adodb_mktime(0, 0, 0, $rr[2], $rr[3], $rr[1]);
|
||||
|
||||
return adodb_mktime($rr[5], $rr[6], $rr[7], $rr[2], $rr[3], $rr[1]);
|
||||
}
|
||||
|
||||
function UserDate($v, $fmt='Y-m-d', $gmt=false)
|
||||
{
|
||||
$tt = $this->UnixDate($v);
|
||||
|
||||
// $tt == -1 if pre TIMESTAMP_FIRST_YEAR
|
||||
if (($tt === false || $tt == -1) && $v != false)
|
||||
return $v;
|
||||
else if ($tt == 0)
|
||||
return $this->emptyDate;
|
||||
else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR
|
||||
}
|
||||
|
||||
return ($gmt) ? adodb_gmdate($fmt, $tt) : adodb_date($fmt, $tt);
|
||||
}
|
||||
|
||||
function UserTimeStamp($v, $fmt='Y-m-d H:i:s', $gmt=false)
|
||||
{
|
||||
if (!isset($v))
|
||||
return $this->emptyTimeStamp;
|
||||
|
||||
# strlen(14) allows YYYYMMDDHHMMSS format
|
||||
if (is_numeric($v) && strlen($v)<14)
|
||||
return ($gmt) ? adodb_gmdate($fmt, $v) : adodb_date($fmt,$v);
|
||||
|
||||
$tt = $this->UnixTimeStamp($v);
|
||||
// $tt == -1 if pre TIMESTAMP_FIRST_YEAR
|
||||
if (($tt === false || $tt == -1) && $v != false)
|
||||
return $v;
|
||||
|
||||
if ($tt == 0)
|
||||
return $this->emptyTimeStamp;
|
||||
|
||||
return ($gmt) ? adodb_gmdate($fmt, $tt) : adodb_date($fmt, $tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col)
|
||||
$col = $this->sysTimeStamp;
|
||||
|
||||
$s = 'DATE_FORMAT('.$col.",'";
|
||||
$concat = false;
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt, $i, 1);
|
||||
}
|
||||
|
||||
/** FALL THROUGH */
|
||||
case '-':
|
||||
case '/':
|
||||
$s .= $ch;
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= '%Y';
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
$s .= '%b';
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
$s .= '%m';
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= '%d';
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "'),Quarter($col)";
|
||||
if ($len > $i+1)
|
||||
$s .= ",DATE_FORMAT($col,'";
|
||||
else $s .= ",('";
|
||||
$concat = true;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s .= '%H';
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
$s .= '%I';
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= '%i';
|
||||
break;
|
||||
|
||||
case 's':
|
||||
$s .= '%s';
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= '%p';
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
$s .= '%w';
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
$s .= '%W';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$s.="')";
|
||||
if ($concat)
|
||||
$s = "CONCAT($s)";
|
||||
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
eval('class mysql_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysql_date_ResultSet extends mysql_date_resultset_EXTENDER
|
||||
{
|
||||
var $emptyTimeStamp = ' '; /// what to display when $time==0
|
||||
var $emptyDate = ' '; /// what to display when $time==0
|
||||
var $datetime = false;
|
||||
|
||||
function UserTimeStamp($v, $fmt='Y-m-d H:i:s')
|
||||
{
|
||||
if (is_numeric($v) && strlen($v)<14)
|
||||
return adodb_date($fmt, $v);
|
||||
|
||||
$tt = $this->UnixTimeStamp($v);
|
||||
// $tt == -1 if pre TIMESTAMP_FIRST_YEAR
|
||||
if (($tt === false || $tt == -1) && $v != false)
|
||||
return $v;
|
||||
|
||||
if ($tt === 0)
|
||||
return $this->emptyTimeStamp;
|
||||
else return adodb_date($fmt, $tt);
|
||||
}
|
||||
|
||||
function UserDate($v,$fmt='Y-m-d')
|
||||
{
|
||||
$tt = $this->UnixDate($v);
|
||||
// $tt == -1 if pre TIMESTAMP_FIRST_YEAR
|
||||
if (($tt === false || $tt == -1) && $v != false)
|
||||
return $v;
|
||||
else if ($tt == 0)
|
||||
return $this->emptyDate;
|
||||
else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR
|
||||
}
|
||||
return adodb_date($fmt, $tt);
|
||||
}
|
||||
|
||||
function UnixDate($v)
|
||||
{
|
||||
return mysql_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return mysql_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,660 @@
|
||||
<?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, SqLite and Sybase.
|
||||
*
|
||||
*/
|
||||
|
||||
class mysql_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
var $nameQuote = '`';
|
||||
var $sysDate = 'CURDATE()';
|
||||
var $sysTimeStamp = 'NOW()';
|
||||
|
||||
function mysql_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'mysql';
|
||||
$this->dataProvider = 'mysql';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('mysql_connect')) {
|
||||
echo "ERROR: Function 'mysql_connect' not found! Check if MySQL is properly set up. And that PHP has the MySQL extension installed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->host = $host;
|
||||
if (!empty($this->port)) $this->host .= ":" . $this->port;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->database = $database;
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
if($this->persistent == 1)
|
||||
{
|
||||
if (strnatcmp(PHP_VERSION, '4.3.0') >= 0)
|
||||
$this->connectionId = @mysql_pconnect( $this->host, $this->username, $this->password, $this->clientFlags );
|
||||
else
|
||||
$this->connectionId = @mysql_pconnect( $this->host, $this->username, $this->password );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strnatcmp(PHP_VERSION, '4.3.0') >= 0)
|
||||
$this->connectionId = @mysql_connect( $this->host, $this->username, $this->password, $this->forcenewconnection, $this->clientFlags );
|
||||
else if (strnatcmp(PHP_VERSION, '4.2.0') >= 0)
|
||||
$this->connectionId = @mysql_connect( $this->host, $this->username, $this->password, $this->forcenewconnection );
|
||||
else
|
||||
$this->connectionId = @mysql_connect( $this->host, $this->username, $this->password );
|
||||
}
|
||||
|
||||
if ($this->connectionId === false)
|
||||
{
|
||||
if ($fn = $this->raiseErrorFn)
|
||||
$fn($this->dbtype, 'CONNECT', $this->ErrorNo(), $this->ErrorMsg(), $this->host, $this->database, $this);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($this->database))
|
||||
{
|
||||
if($this->SelectDB( $this->database ) == false)
|
||||
{
|
||||
$this->connectionId = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose a database to connect.
|
||||
*
|
||||
* @param dbname is the name of the database to select
|
||||
* @return true or false
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function SelectDB($dbname)
|
||||
{
|
||||
$this->database = $dbname;
|
||||
|
||||
if ($this->connectionId === false)
|
||||
{
|
||||
$this->connectionId = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = @mysql_select_db( $this->database, $this->connectionId );
|
||||
|
||||
if($result === false)
|
||||
{
|
||||
if($this->createdatabase == true)
|
||||
{
|
||||
$result = @mysql_query( "CREATE DATABASE IF NOT EXISTS " . $this->database, $this->connectionId );
|
||||
if ($result === false) { // error handling if query fails
|
||||
return false;
|
||||
}
|
||||
$result = @mysql_select_db( $this->database, $this->connectionId );
|
||||
if($result === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error message
|
||||
* Usage: $errormessage =& $db->ErrorMsg();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if ($this->connectionId === false)
|
||||
{
|
||||
return @mysql_error();
|
||||
}
|
||||
else
|
||||
{
|
||||
return @mysql_error($this->connectionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
if ($this->connectionId === false)
|
||||
{
|
||||
return @mysql_errno();
|
||||
}
|
||||
else
|
||||
{
|
||||
return @mysql_errno($this->connectionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @mysql_affected_rows($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return @mysql_insert_id($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Correctly quotes a string so that all strings are escape coded.
|
||||
* An example is $db->qstr("Haven't a clue.");
|
||||
*
|
||||
* @param string the string to quote
|
||||
* @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc().
|
||||
*
|
||||
* @return single-quoted string IE: 'Haven\'t a clue.'
|
||||
*/
|
||||
|
||||
function qstr($string, $magic_quotes=false)
|
||||
{
|
||||
if (!$magic_quotes) {
|
||||
if (strnatcmp(PHP_VERSION, '4.3.0') >= 0) {
|
||||
return "'" . mysql_real_escape_string($string, $this->connectionId) . "'";
|
||||
}
|
||||
$string = str_replace("'", "\\'" , str_replace('\\', '\\\\', str_replace("\0", "\\\0", $string)));
|
||||
return "'" . $string . "'";
|
||||
}
|
||||
return "'" . str_replace('\\"', '"', $string) . "'";
|
||||
}
|
||||
|
||||
function QMagic($string)
|
||||
{
|
||||
return $this->qstr($string, get_magic_quotes_gpc());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns concatenated string
|
||||
* Usage: $db->Concat($str1,$str2);
|
||||
*
|
||||
* @return concatenated string
|
||||
*/
|
||||
function Concat()
|
||||
{
|
||||
$arr = func_get_args();
|
||||
$list = implode(', ', $arr);
|
||||
|
||||
if (strlen($list) > 0) return "CONCAT($list)";
|
||||
else return '';
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " IFNULL($field, $ifNull) ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@mysql_close( $this->connectionId );
|
||||
$this->connectionId = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns All Records in an array
|
||||
*
|
||||
* Usage: $db->GetAll($sql);
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function &GetAll($sql, $inputarr = false)
|
||||
{
|
||||
$data =& $this->GetArray($sql, $inputarr);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns All Records in an array
|
||||
*
|
||||
* Usage: $db->GetArray($sql);
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function &GetArray($sql, $inputarr = false)
|
||||
{
|
||||
$data = false;
|
||||
$result =& $this->Execute($sql, $inputarr);
|
||||
if ($result)
|
||||
{
|
||||
$data =& $result->GetArray();
|
||||
$result->Close();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes SQL query and instantiates resultset methods
|
||||
*
|
||||
* @access private
|
||||
* @return mixed Resultset methods
|
||||
*/
|
||||
|
||||
function &do_query( $sql, $offset, $nrows, $inputarr=false )
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
|
||||
$limit = '';
|
||||
if ($offset >= 0 || $nrows >= 0)
|
||||
{
|
||||
$offset = ($offset >= 0) ? $offset . "," : '';
|
||||
$nrows = ($nrows >= 0) ? $nrows : '18446744073709551615';
|
||||
$limit = ' LIMIT ' . $offset . ' ' . $nrows;
|
||||
}
|
||||
|
||||
if ($inputarr && is_array($inputarr)) {
|
||||
$sqlarr = explode('?', $sql);
|
||||
if (!is_array(reset($inputarr))) $inputarr = array($inputarr);
|
||||
foreach($inputarr as $arr) {
|
||||
$sql = ''; $i = 0;
|
||||
foreach($arr as $v) {
|
||||
$sql .= $sqlarr[$i];
|
||||
switch(gettype($v)){
|
||||
case 'string':
|
||||
$sql .= $this->qstr($v);
|
||||
break;
|
||||
case 'double':
|
||||
$sql .= str_replace(',', '.', $v);
|
||||
break;
|
||||
case 'boolean':
|
||||
$sql .= $v ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
if ($v === null)
|
||||
$sql .= 'NULL';
|
||||
else $sql .= $v;
|
||||
}
|
||||
$i += 1;
|
||||
}
|
||||
$sql .= $sqlarr[$i];
|
||||
if ($i+1 != sizeof($sqlarr))
|
||||
return $false;
|
||||
$this->sql = $sql . $limit;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @mysql_query( $this->sql, $this->connectionId );
|
||||
$time_total = (array_sum(explode(' ', microtime())) - $time_start);
|
||||
$this->query_time_total += $time_total;
|
||||
if($this->debug_console)
|
||||
{
|
||||
$this->query_list[] = $this->sql;
|
||||
$this->query_list_time[] = $time_total;
|
||||
$this->query_list_errors[] = $this->ErrorMsg();
|
||||
}
|
||||
if($this->debug)
|
||||
{
|
||||
$this->outp($sql . $limit);
|
||||
}
|
||||
if ($resultId === false) { // error handling if query fails
|
||||
if ($fn = $this->raiseErrorFn)
|
||||
$fn($this->dbtype, 'EXECUTE', $this->ErrorNo(), $this->ErrorMsg(), $this->sql, $inputarr, $this);
|
||||
return $false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->sql = $sql . $limit;
|
||||
$this->sql = $sql . $limit;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @mysql_query( $this->sql, $this->connectionId );
|
||||
$time_total = (array_sum(explode(' ', microtime())) - $time_start);
|
||||
$this->query_time_total += $time_total;
|
||||
if($this->debug_console)
|
||||
{
|
||||
$this->query_list[] = $this->sql;
|
||||
$this->query_list_time[] = $time_total;
|
||||
$this->query_list_errors[] = $this->ErrorMsg();
|
||||
}
|
||||
if($this->debug)
|
||||
{
|
||||
$this->outp($sql . $limit);
|
||||
}
|
||||
}
|
||||
|
||||
if ($resultId === false) { // error handling if query fails
|
||||
if ($fn = $this->raiseErrorFn)
|
||||
$fn($this->dbtype, 'EXECUTE', $this->ErrorNo(), $this->ErrorMsg(), $this->sql, $inputarr, $this);
|
||||
return $false;
|
||||
}
|
||||
|
||||
if ($resultId === true) { // return simplified recordset for inserts/updates/deletes with lower overhead
|
||||
$recordset = new ADORecordSet_empty();
|
||||
return $recordset;
|
||||
}
|
||||
|
||||
$resultset_name = $this->last_module_name . "_ResultSet";
|
||||
$recordset = new $resultset_name( $resultId, $this->connectionId );
|
||||
|
||||
$recordset->_currentRow = 0;
|
||||
|
||||
switch ($ADODB_FETCH_MODE)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $recordset->fetchMode = MYSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC: $recordset->fetchMode = MYSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH: $recordset->fetchMode = MYSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @mysql_num_rows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @mysql_num_fields( $resultId );
|
||||
$recordset->_fetch();
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class mysql_driver_ResultSet
|
||||
{
|
||||
var $connectionId;
|
||||
var $fields;
|
||||
var $resultId;
|
||||
var $_currentRow = 0;
|
||||
var $_numOfRows = -1;
|
||||
var $_numOfFields = -1;
|
||||
var $fetchMode;
|
||||
var $EOF;
|
||||
|
||||
/**
|
||||
* mysqlResultSet Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $record
|
||||
* @param string $resultId
|
||||
*/
|
||||
|
||||
function mysql_driver_ResultSet( $resultId, $connectionId )
|
||||
{
|
||||
$this->fields = array();
|
||||
$this->connectionId = $connectionId;
|
||||
$this->record = array();
|
||||
$this->resultId = $resultId;
|
||||
$this->EOF = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees resultset
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@mysql_free_result( $this->resultId );
|
||||
$this->fields = array();
|
||||
$this->resultId = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns field name from select query
|
||||
*
|
||||
* @access public
|
||||
* @param string $field
|
||||
* @return string Field name
|
||||
*/
|
||||
|
||||
function fields( $field )
|
||||
{
|
||||
if(empty($field))
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->fields[$field];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns numrows from select query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Numrows
|
||||
*/
|
||||
|
||||
function RecordCount()
|
||||
{
|
||||
return $this->_numOfRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns num of fields from select query
|
||||
*
|
||||
* @access public
|
||||
* @return integer numfields
|
||||
*/
|
||||
|
||||
function FieldCount()
|
||||
{
|
||||
return $this->_numOfFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next record
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function MoveNext()
|
||||
{
|
||||
if (@$this->fields = mysql_fetch_array($this->resultId,$this->fetchMode)) {
|
||||
$this->_currentRow += 1;
|
||||
return true;
|
||||
}
|
||||
if (!$this->EOF) {
|
||||
$this->_currentRow += 1;
|
||||
$this->EOF = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move to the first row in the recordset. Many databases do NOT support this.
|
||||
*
|
||||
* @return true or false
|
||||
*/
|
||||
|
||||
function MoveFirst()
|
||||
{
|
||||
if ($this->_currentRow == 0) return true;
|
||||
return $this->Move(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Last Record
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function MoveLast()
|
||||
{
|
||||
if ($this->EOF) return false;
|
||||
return $this->Move($this->_numOfRows - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Random access to a specific row in the recordset. Some databases do not support
|
||||
* access to previous rows in the databases (no scrolling backwards).
|
||||
*
|
||||
* @param rowNumber is the row to move to (0-based)
|
||||
*
|
||||
* @return true if there still rows available, or false if there are no more rows (EOF).
|
||||
*/
|
||||
|
||||
function Move($rowNumber = 0)
|
||||
{
|
||||
if ($rowNumber == $this->_currentRow) return true;
|
||||
$this->EOF = false;
|
||||
if ($this->_numOfRows > 0){
|
||||
if ($rowNumber >= $this->_numOfRows - 1){
|
||||
$rowNumber = $this->_numOfRows - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_seek($rowNumber)) {
|
||||
$this->_currentRow = $rowNumber;
|
||||
if ($this->_fetch()) {
|
||||
return true;
|
||||
}
|
||||
$this->fields = false;
|
||||
}
|
||||
$this->EOF = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform Seek to specific row
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
if ($this->_numOfRows == 0) return false;
|
||||
return @mysql_data_seek($this->resultId,$row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @mysql_fetch_array($this->resultId,$this->fetchMode);
|
||||
return is_array($this->fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if last record reached
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function EOF()
|
||||
{
|
||||
if( $this->_currentRow < $this->_numOfRows)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->EOF = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns All Records in an array
|
||||
*
|
||||
* @access public
|
||||
* @param [nRows] is the number of rows to return. -1 means every row.
|
||||
*/
|
||||
|
||||
function &GetArray($nRows = -1)
|
||||
{
|
||||
$results = array();
|
||||
$cnt = 0;
|
||||
while (!$this->EOF && $nRows != $cnt) {
|
||||
$results[] = $this->fields;
|
||||
$this->MoveNext();
|
||||
$cnt++;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
function &GetRows($nRows = -1)
|
||||
{
|
||||
$arr =& $this->GetArray($nRows);
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function &GetAll($nRows = -1)
|
||||
{
|
||||
$arr =& $this->GetArray($nRows);
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch field information for a table.
|
||||
*
|
||||
* @return object containing the name, type and max_length
|
||||
*/
|
||||
function FetchField($fieldOffset = -1)
|
||||
{
|
||||
if ($fieldOffset != -1) {
|
||||
$fieldObject = @mysql_fetch_field($this->resultId, $fieldOffset);
|
||||
$fieldObject->max_length = @mysql_field_len($this->resultId,$fieldOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$fieldObject = @mysql_fetch_field($this->resultId);
|
||||
$fieldObject->max_length = @mysql_field_len($this->resultId);
|
||||
}
|
||||
return $fieldObject;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mysql_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysql_extend_ADOConnection extends mysql_extend_EXTENDER
|
||||
{
|
||||
function &GetAssoc($sql, $inputarr=false, $force_array = false, $first2cols = false)
|
||||
{
|
||||
$data = false;
|
||||
$result =& $this->Execute($sql, $inputarr);
|
||||
if ($result) {
|
||||
$data =& $result->GetAssoc($force_array, $first2cols);
|
||||
$result->Close();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a sequence id and stores it in $this->genID;
|
||||
* GenID is only available if $this->hasGenID = true;
|
||||
*
|
||||
* @param seqname name of sequence to use
|
||||
* @param startID if sequence does not exist, start at this ID
|
||||
* @return 0 if not supported, otherwise a sequence id
|
||||
*/
|
||||
|
||||
var $genID = 0;
|
||||
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
|
||||
var $_genSeqSQL = "create table %s (id int not null)";
|
||||
var $_genSeq2SQL = "insert into %s values (%s)";
|
||||
var $_dropSeqSQL = "drop table %s";
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
$getnext = sprintf($this->_genIDSQL, $seqname);
|
||||
$holdtransOK = $this->transaction_status;
|
||||
$result = @$this->Execute($getnext);
|
||||
if (!$result) {
|
||||
if ($holdtransOK)
|
||||
$this->transaction_status = true;
|
||||
// $u = strtoupper($seqname);
|
||||
$this->Execute(sprintf($this->_genSeqSQL, $seqname));
|
||||
$this->Execute(sprintf($this->_genSeq2SQL, $seqname, $startID-1));
|
||||
$result = $this->Execute($getnext);
|
||||
}
|
||||
$this->genID = mysql_insert_id($this->connectionId);
|
||||
|
||||
if ($result)
|
||||
$result->Close();
|
||||
|
||||
return $this->genID;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
$u = strtoupper($seqname);
|
||||
|
||||
$ok = $this->Execute(sprintf($this->_genSeqSQL, $seqname));
|
||||
if (!$ok)
|
||||
return false;
|
||||
return $this->Execute(sprintf($this->_genSeq2SQL, $seqname, $startID-1));
|
||||
}
|
||||
|
||||
function DropSequence($seqname='adodbseq')
|
||||
{
|
||||
return $this->Execute(sprintf($this->_dropSeqSQL, $seqname));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class mysql_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysql_extend_ResultSet extends mysql_extend_resultset_EXTENDER
|
||||
{
|
||||
function &GetAssoc($force_array = false, $first2cols = false)
|
||||
{
|
||||
$results = false;
|
||||
|
||||
if ($this->_numOfFields > 1) {
|
||||
$numIndex = isset($this->fields[0]);
|
||||
$results = array();
|
||||
if (!$first2cols && ($this->_numOfFields > 2 || $force_array)) {
|
||||
if ($numIndex) {
|
||||
while (!$this->EOF) {
|
||||
$results[trim($this->fields[0])] = array_slice($this->fields, 1);
|
||||
$this->MoveNext();
|
||||
}
|
||||
} else {
|
||||
while (!$this->EOF) {
|
||||
$results[trim(reset($this->fields))] = array_slice($this->fields, 1);
|
||||
$this->MoveNext();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($numIndex) {
|
||||
while (!$this->EOF) {
|
||||
$results[trim(($this->fields[0]))] = $this->fields[1];
|
||||
$this->MoveNext();
|
||||
}
|
||||
} else {
|
||||
while (!$this->EOF) {
|
||||
$v1 = trim(reset($this->fields));
|
||||
$v2 = ''.next($this->fields);
|
||||
$results[$v1] = $v2;
|
||||
$this->MoveNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
function PO_RecordCount($table="", $condition="")
|
||||
{
|
||||
$lnumrows = $this->_numOfRows;
|
||||
if($lnumrows == -1 && $this->connectionId)
|
||||
{
|
||||
if($table)
|
||||
{
|
||||
if ($condition)
|
||||
$condition = " WHERE " . $condition;
|
||||
$resultrows = &$this->connectionId->Execute("SELECT COUNT(*) FROM $table $condition");
|
||||
if ($resultrows)
|
||||
$lnumrows = reset($resultrows->fields);
|
||||
}
|
||||
}
|
||||
return $lnumrows;
|
||||
}
|
||||
|
||||
function CurrentRow()
|
||||
{
|
||||
return $this->_currentRow;
|
||||
}
|
||||
|
||||
function AbsolutePosition()
|
||||
{
|
||||
return $this->_currentRow;
|
||||
}
|
||||
|
||||
function NextRecordSet()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,623 @@
|
||||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for Mysql
|
||||
*
|
||||
* Portions of the Meta Coding came from ADOdb
|
||||
*/
|
||||
|
||||
/*
|
||||
(c) 2000-2005 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. See License.txt.
|
||||
*/
|
||||
|
||||
eval('class mysql_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysql_meta_ADOConnection extends mysql_meta_EXTENDER
|
||||
{
|
||||
var $metaTablesSQL = "SHOW TABLES";
|
||||
var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
|
||||
|
||||
function MetaError($err=false)
|
||||
{
|
||||
include_once(ADODB_DIR."/adodb-error.inc.php");
|
||||
if ($err === false)
|
||||
$err = $this->ErrorNo();
|
||||
|
||||
return adodb_error($this->dataProvider,$this->databaseType,$err);
|
||||
}
|
||||
|
||||
function MetaErrorMsg($errno)
|
||||
{
|
||||
include_once(ADODB_DIR."/adodb-error.inc.php");
|
||||
return adodb_errormsg($errno);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns an array with the primary key columns in it.
|
||||
*/
|
||||
function MetaPrimaryKeys($table, $owner=false)
|
||||
{
|
||||
// owner not used in base class - see oci8
|
||||
$p = array();
|
||||
$objs =& $this->MetaColumns($table);
|
||||
if ($objs) {
|
||||
foreach($objs as $v) {
|
||||
if (!empty($v->primary_key))
|
||||
$p[] = $v->name;
|
||||
}
|
||||
}
|
||||
if (sizeof($p))
|
||||
return $p;
|
||||
if (function_exists('ADODB_VIEW_PRIMARYKEYS'))
|
||||
return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns assoc array where keys are tables, and values are foreign keys
|
||||
*/
|
||||
function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
|
||||
{
|
||||
if ( !empty($owner) ) {
|
||||
$table = "$owner.$table";
|
||||
}
|
||||
$a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
|
||||
if ($associative) $create_sql = $a_create_table["Create Table"];
|
||||
else $create_sql = $a_create_table[1];
|
||||
|
||||
$matches = array();
|
||||
|
||||
if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
|
||||
$foreign_keys = array();
|
||||
$num_keys = count($matches[0]);
|
||||
for ( $i = 0; $i < $num_keys; $i ++ ) {
|
||||
$my_field = explode('`, `', $matches[1][$i]);
|
||||
$ref_table = $matches[2][$i];
|
||||
$ref_field = explode('`, `', $matches[3][$i]);
|
||||
|
||||
if ( $upper ) {
|
||||
$ref_table = strtoupper($ref_table);
|
||||
}
|
||||
|
||||
$foreign_keys[$ref_table] = array();
|
||||
$num_fields = count($my_field);
|
||||
for ( $j = 0; $j < $num_fields; $j ++ ) {
|
||||
if ( $associative ) {
|
||||
$foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
|
||||
} else {
|
||||
$foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $foreign_keys;
|
||||
}
|
||||
|
||||
// not the fastest implementation - quick and dirty - jlim
|
||||
// for best performance, use the actual $rs->MetaType().
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (empty($this->_metars)) {
|
||||
$rsclass = $this->last_module_name . "_ResultSet";
|
||||
$this->_metars =& new $rsclass(false,$this->fetchMode);
|
||||
}
|
||||
|
||||
return $this->_metars->MetaType($t,$len,$fieldobj);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the databases that the driver can connect to.
|
||||
* Some databases will return an empty array.
|
||||
*
|
||||
* @return an array of database names.
|
||||
*/
|
||||
function &MetaDatabases()
|
||||
{
|
||||
$qid = mysql_list_dbs($this->connectionId);
|
||||
$arr = array();
|
||||
$i = 0;
|
||||
$max = mysql_num_rows($qid);
|
||||
while ($i < $max) {
|
||||
$db = mysql_tablename($qid,$i);
|
||||
if ($db != 'mysql') $arr[] = $db;
|
||||
$i += 1;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
$save = $this->metaTablesSQL;
|
||||
if ($showSchema && is_string($showSchema)) {
|
||||
$this->metaTablesSQL .= " from $showSchema";
|
||||
}
|
||||
|
||||
if ($mask) {
|
||||
$mask = $this->qstr($mask);
|
||||
$this->metaTablesSQL .= " like $mask";
|
||||
}
|
||||
$ret =& $this->_MetaTables($ttype,$showSchema);
|
||||
|
||||
$this->metaTablesSQL = $save;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function &_MetaTables($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
if ($mask) {
|
||||
return $false;
|
||||
}
|
||||
if ($this->metaTablesSQL) {
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$rs = $this->Execute($this->metaTablesSQL);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rs === false) return $false;
|
||||
$arr =& $rs->GetArray();
|
||||
$arr2 = array();
|
||||
|
||||
if ($hast = ($ttype && isset($arr[0][1]))) {
|
||||
$showt = strncmp($ttype,'T',1);
|
||||
}
|
||||
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
if ($hast) {
|
||||
if ($showt == 0) {
|
||||
if (strncmp($arr[$i][1],'T',1) == 0) $arr2[] = trim($arr[$i][0]);
|
||||
} else {
|
||||
if (strncmp($arr[$i][1],'V',1) == 0) $arr2[] = trim($arr[$i][0]);
|
||||
}
|
||||
} else
|
||||
$arr2[] = trim($arr[$i][0]);
|
||||
}
|
||||
$rs->Close();
|
||||
return $arr2;
|
||||
}
|
||||
return $false;
|
||||
}
|
||||
|
||||
function _findschema(&$table,&$schema)
|
||||
{
|
||||
if (!$schema && ($at = strpos($table,'.')) !== false) {
|
||||
$schema = substr($table,0,$at);
|
||||
$table = substr($table,$at+1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $normalize makes table name case-insensitive (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($table)
|
||||
{
|
||||
$this->_findschema($table,$schema);
|
||||
if ($schema) {
|
||||
$dbName = $this->database;
|
||||
$this->connection->SelectDB($schema);
|
||||
}
|
||||
global $ADODB_FETCH_MODE;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
|
||||
|
||||
if ($schema) {
|
||||
$this->SelectDB($dbName);
|
||||
}
|
||||
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if (!is_object($rs)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF){
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$type = $rs->fields[1];
|
||||
|
||||
// split type into type(length):
|
||||
$fld->scale = null;
|
||||
if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
|
||||
$fld->type = $query_array[1];
|
||||
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
|
||||
$fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
|
||||
} elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
|
||||
$fld->type = $query_array[1];
|
||||
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
|
||||
} elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) {
|
||||
$fld->type = $query_array[1];
|
||||
$arr = explode(",",$query_array[2]);
|
||||
$fld->enums = $arr;
|
||||
$zlen = max(array_map("strlen",$arr)) - 2; // PHP >= 4.0.6
|
||||
$fld->max_length = ($zlen > 0) ? $zlen : 1;
|
||||
} else {
|
||||
$fld->type = $type;
|
||||
$fld->max_length = -1;
|
||||
}
|
||||
$fld->not_null = ($rs->fields[2] != 'YES');
|
||||
$fld->primary_key = ($rs->fields[3] == 'PRI');
|
||||
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
|
||||
$fld->binary = (strpos($type,'blob') !== false);
|
||||
$fld->unsigned = (strpos($type,'unsigned') !== false);
|
||||
|
||||
if (!$fld->binary) {
|
||||
$d = $rs->fields[4];
|
||||
if ($d != '' && $d != 'NULL') {
|
||||
$fld->has_default = true;
|
||||
$fld->default_value = $d;
|
||||
} else {
|
||||
$fld->has_default = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($save == ADODB_FETCH_NUM) {
|
||||
$retarr[] = $fld;
|
||||
} else {
|
||||
$retarr[strtoupper($fld->name)] = $fld;
|
||||
}
|
||||
$rs->MoveNext();
|
||||
}
|
||||
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
// save old fetch mode
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== FALSE) {
|
||||
$savem = $this->SetFetchMode(FALSE);
|
||||
}
|
||||
|
||||
// get index details
|
||||
$rs =& $this->Execute(sprintf('SHOW INDEX FROM %s',$table));
|
||||
|
||||
// restore fetchmode
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!is_object($rs)) {
|
||||
return $false;
|
||||
}
|
||||
|
||||
$indexes = array ();
|
||||
|
||||
// parse index data into array
|
||||
while (!$rs->EOF)
|
||||
{
|
||||
if ($primary == FALSE AND $rs->fields[2] == 'PRIMARY') {
|
||||
$rs->MoveNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($indexes[$rs->fields[2]])) {
|
||||
$indexes[$rs->fields[2]] = array(
|
||||
'unique' => ($rs->fields[1] == 0),
|
||||
'columns' => array()
|
||||
);
|
||||
}
|
||||
|
||||
$indexes[$rs->fields[2]]['columns'][$rs->fields[3] - 1] = $rs->fields[4];
|
||||
|
||||
$rs->MoveNext();
|
||||
}
|
||||
|
||||
// sort columns by order in the index
|
||||
foreach ( array_keys ($indexes) as $index )
|
||||
{
|
||||
ksort ($indexes[$index]['columns']);
|
||||
}
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* List columns names in a table as an array.
|
||||
* @param table table name to query
|
||||
*
|
||||
* @return array of column names for current table.
|
||||
*/
|
||||
function &MetaColumnNames($table, $numIndexes=false)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
foreach($objarr as $v) $arr[$i++] = $v->name;
|
||||
} else
|
||||
foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function MetaTransaction($mode,$db)
|
||||
{
|
||||
$mode = strtoupper($mode);
|
||||
$mode = str_replace('ISOLATION LEVEL ','',$mode);
|
||||
|
||||
switch($mode) {
|
||||
|
||||
case 'READ UNCOMMITTED':
|
||||
switch($db) {
|
||||
case 'oci8':
|
||||
case 'oracle':
|
||||
return 'ISOLATION LEVEL READ COMMITTED';
|
||||
default:
|
||||
return 'ISOLATION LEVEL READ UNCOMMITTED';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'READ COMMITTED':
|
||||
return 'ISOLATION LEVEL READ COMMITTED';
|
||||
break;
|
||||
|
||||
case 'REPEATABLE READ':
|
||||
switch($db) {
|
||||
case 'oci8':
|
||||
case 'oracle':
|
||||
return 'ISOLATION LEVEL SERIALIZABLE';
|
||||
default:
|
||||
return 'ISOLATION LEVEL REPEATABLE READ';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'SERIALIZABLE':
|
||||
return 'ISOLATION LEVEL SERIALIZABLE';
|
||||
break;
|
||||
|
||||
default:
|
||||
return $mode;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class mysql_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysql_meta_ResultSet extends mysql_meta_resultset_EXTENDER
|
||||
{
|
||||
/**
|
||||
* Get the metatype of the column. This is used for formatting. This is because
|
||||
* many databases use different names for the same type, so we transform the original
|
||||
* type to our standardised version which uses 1 character codes:
|
||||
*
|
||||
* @param t is the type passed in. Normally is ADOFieldObject->type.
|
||||
* @param len is the maximum length of that field. This is because we treat character
|
||||
* fields bigger than a certain size as a 'B' (blob).
|
||||
* @param fieldobj is the field object returned by the database driver. Can hold
|
||||
* additional info (eg. primary_key for mysql).
|
||||
*
|
||||
* @return the general type of the data:
|
||||
* C for character < 250 chars
|
||||
* X for teXt (>= 250 chars)
|
||||
* B for Binary
|
||||
* N for numeric or floating point
|
||||
* D for date
|
||||
* T for timestamp
|
||||
* L for logical/Boolean
|
||||
* I for integer
|
||||
* R for autoincrement counter/integer
|
||||
*
|
||||
*
|
||||
*/
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
$len = -1; // mysql max_length is not accurate
|
||||
switch (strtoupper($t)) {
|
||||
case 'STRING':
|
||||
case 'CHAR':
|
||||
case 'VARCHAR':
|
||||
case 'TINYBLOB':
|
||||
case 'TINYTEXT':
|
||||
case 'ENUM':
|
||||
case 'SET':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 'TEXT':
|
||||
case 'LONGTEXT':
|
||||
case 'MEDIUMTEXT':
|
||||
return 'X';
|
||||
|
||||
// php_mysql extension always returns 'blob' even if 'text'
|
||||
// so we have to check whether binary...
|
||||
case 'IMAGE':
|
||||
case 'LONGBLOB':
|
||||
case 'BLOB':
|
||||
case 'MEDIUMBLOB':
|
||||
return !empty($fieldobj->binary) ? 'B' : 'X';
|
||||
|
||||
case 'YEAR':
|
||||
case 'DATE': return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP': return 'T';
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER':
|
||||
case 'BIGINT':
|
||||
case 'TINYINT':
|
||||
case 'MEDIUMINT':
|
||||
case 'SMALLINT':
|
||||
|
||||
if (!empty($fieldobj->primary_key)) return 'R';
|
||||
else return 'I';
|
||||
|
||||
default:
|
||||
static $typeMap = array(
|
||||
'VARCHAR' => 'C',
|
||||
'VARCHAR2' => 'C',
|
||||
'CHAR' => 'C',
|
||||
'C' => 'C',
|
||||
'STRING' => 'C',
|
||||
'NCHAR' => 'C',
|
||||
'NVARCHAR' => 'C',
|
||||
'VARYING' => 'C',
|
||||
'BPCHAR' => 'C',
|
||||
'CHARACTER' => 'C',
|
||||
'INTERVAL' => 'C', # Postgres
|
||||
'MACADDR' => 'C', # postgres
|
||||
##
|
||||
'LONGCHAR' => 'X',
|
||||
'TEXT' => 'X',
|
||||
'NTEXT' => 'X',
|
||||
'M' => 'X',
|
||||
'X' => 'X',
|
||||
'CLOB' => 'X',
|
||||
'NCLOB' => 'X',
|
||||
'LVARCHAR' => 'X',
|
||||
##
|
||||
'BLOB' => 'B',
|
||||
'IMAGE' => 'B',
|
||||
'BINARY' => 'B',
|
||||
'VARBINARY' => 'B',
|
||||
'LONGBINARY' => 'B',
|
||||
'B' => 'B',
|
||||
##
|
||||
'YEAR' => 'D', // mysql
|
||||
'DATE' => 'D',
|
||||
'D' => 'D',
|
||||
##
|
||||
'UNIQUEIDENTIFIER' => 'C', # MS SQL Server
|
||||
##
|
||||
'TIME' => 'T',
|
||||
'TIMESTAMP' => 'T',
|
||||
'DATETIME' => 'T',
|
||||
'TIMESTAMPTZ' => 'T',
|
||||
'T' => 'T',
|
||||
'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql
|
||||
##
|
||||
'BOOL' => 'L',
|
||||
'BOOLEAN' => 'L',
|
||||
'BIT' => 'L',
|
||||
'L' => 'L',
|
||||
##
|
||||
'COUNTER' => 'R',
|
||||
'R' => 'R',
|
||||
'SERIAL' => 'R', // ifx
|
||||
'INT IDENTITY' => 'R',
|
||||
##
|
||||
'INT' => 'I',
|
||||
'INT2' => 'I',
|
||||
'INT4' => 'I',
|
||||
'INT8' => 'I',
|
||||
'INTEGER' => 'I',
|
||||
'INTEGER UNSIGNED' => 'I',
|
||||
'SHORT' => 'I',
|
||||
'TINYINT' => 'I',
|
||||
'SMALLINT' => 'I',
|
||||
'I' => 'I',
|
||||
##
|
||||
'LONG' => 'N', // interbase is numeric, oci8 is blob
|
||||
'BIGINT' => 'N', // this is bigger than PHP 32-bit integers
|
||||
'DECIMAL' => 'N',
|
||||
'DEC' => 'N',
|
||||
'REAL' => 'N',
|
||||
'DOUBLE' => 'N',
|
||||
'DOUBLE PRECISION' => 'N',
|
||||
'SMALLFLOAT' => 'N',
|
||||
'FLOAT' => 'N',
|
||||
'NUMBER' => 'N',
|
||||
'NUM' => 'N',
|
||||
'NUMERIC' => 'N',
|
||||
'MONEY' => 'N',
|
||||
|
||||
## informix 9.2
|
||||
'SQLINT' => 'I',
|
||||
'SQLSERIAL' => 'I',
|
||||
'SQLSMINT' => 'I',
|
||||
'SQLSMFLOAT' => 'N',
|
||||
'SQLFLOAT' => 'N',
|
||||
'SQLMONEY' => 'N',
|
||||
'SQLDECIMAL' => 'N',
|
||||
'SQLDATE' => 'D',
|
||||
'SQLVCHAR' => 'C',
|
||||
'SQLCHAR' => 'C',
|
||||
'SQLDTIME' => 'T',
|
||||
'SQLINTERVAL' => 'N',
|
||||
'SQLBYTES' => 'B',
|
||||
'SQLTEXT' => 'X',
|
||||
## informix 10
|
||||
"SQLINT8" => 'I8',
|
||||
"SQLSERIAL8" => 'I8',
|
||||
"SQLNCHAR" => 'C',
|
||||
"SQLNVCHAR" => 'C',
|
||||
"SQLLVARCHAR" => 'X',
|
||||
"SQLBOOL" => 'L'
|
||||
);
|
||||
|
||||
$tmap = false;
|
||||
$t = strtoupper($t);
|
||||
$tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,426 @@
|
||||
<?php
|
||||
/*
|
||||
V4.65 22 July 2005 (c) 2000-2005 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. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Library for basic performance monitoring and tuning.
|
||||
|
||||
Modified 17 March 2006 for use with ADOdb Lite by Pádraic Brady
|
||||
Such modifications as listed (c) 2006 Pádraic Brady (maugrimtr@hotmail.com)
|
||||
|
||||
Modifications:
|
||||
- Moved adodb_perf class to $dbtype_perfmon_module.inc as the $dbtype_perfmon_ADOConnection class
|
||||
- restricted adodb_perf class to tracking table name to use (for BC) - it's an alias for perfmon_parent_ADOConnection::table()
|
||||
- Added LogSQL() method, and _logsql property
|
||||
- general formatting changes and replacement of htmlspecialchars() woth htmlentities()
|
||||
- parent class for specific driver modules added in adodb-perf-module.inc.php
|
||||
|
||||
*/
|
||||
|
||||
// required to allow a common parent for all perfmon dbtype specific modules to extend
|
||||
$thisDBType = 'mysql';
|
||||
|
||||
require_once(ADODB_DIR . '/adodb-perf.inc.php');
|
||||
require_once(ADODB_DIR . '/adodb-perf-module.inc.php');
|
||||
|
||||
// not really needed, we already know the parent class name?
|
||||
eval('class mysql_perfmon_EXTENDER extends perfmon_parent_ADOConnection { }');
|
||||
|
||||
class mysql_perfmon_ADOConnection extends mysql_perfmon_EXTENDER
|
||||
{
|
||||
var $upperCase = 'upper';
|
||||
var $substr = "substring";
|
||||
|
||||
var $tablesSQL = 'show table status';
|
||||
|
||||
var $createTableSQL = "CREATE TABLE adodb_logsql (
|
||||
created datetime NOT NULL,
|
||||
sql0 varchar(250) NOT NULL,
|
||||
sql1 text NOT NULL,
|
||||
params text NOT NULL,
|
||||
tracer text NOT NULL,
|
||||
timer decimal(16,6) NOT NULL
|
||||
)";
|
||||
|
||||
var $settings = array(
|
||||
'Ratios',
|
||||
'MyISAM cache hit ratio' => array('RATIO',
|
||||
'=GetKeyHitRatio',
|
||||
'=WarnCacheRatio'),
|
||||
'InnoDB cache hit ratio' => array('RATIO',
|
||||
'=GetInnoDBHitRatio',
|
||||
'=WarnCacheRatio'),
|
||||
'data cache hit ratio' => array('HIDE', # only if called
|
||||
'=FindDBHitRatio',
|
||||
'=WarnCacheRatio'),
|
||||
'sql cache hit ratio' => array('RATIO',
|
||||
'=GetQHitRatio',
|
||||
''),
|
||||
'IO',
|
||||
'data reads' => array('IO',
|
||||
'=GetReads',
|
||||
'Number of selects (Key_reads is not accurate)'),
|
||||
'data writes' => array('IO',
|
||||
'=GetWrites',
|
||||
'Number of inserts/updates/deletes * coef (Key_writes is not accurate)'),
|
||||
|
||||
'Data Cache',
|
||||
'MyISAM data cache size' => array('DATAC',
|
||||
array("show variables", 'key_buffer_size'),
|
||||
'' ),
|
||||
'BDB data cache size' => array('DATAC',
|
||||
array("show variables", 'bdb_cache_size'),
|
||||
'' ),
|
||||
'InnoDB data cache size' => array('DATAC',
|
||||
array("show variables", 'innodb_buffer_pool_size'),
|
||||
'' ),
|
||||
'Memory Usage',
|
||||
'read buffer size' => array('CACHE',
|
||||
array("show variables", 'read_buffer_size'),
|
||||
'(per session)'),
|
||||
'sort buffer size' => array('CACHE',
|
||||
array("show variables", 'sort_buffer_size'),
|
||||
'Size of sort buffer (per session)' ),
|
||||
'table cache' => array('CACHE',
|
||||
array("show variables", 'table_cache'),
|
||||
'Number of tables to keep open'),
|
||||
'Connections',
|
||||
'current connections' => array('SESS',
|
||||
array('show status','Threads_connected'),
|
||||
''),
|
||||
'max connections' => array( 'SESS',
|
||||
array("show variables",'max_connections'),
|
||||
''),
|
||||
|
||||
false
|
||||
);
|
||||
|
||||
/**
|
||||
Get server version info...
|
||||
|
||||
@returns An array with 2 elements: $arr['description'] is the description string,
|
||||
and $arr['version'] is the version (also a string).
|
||||
*/
|
||||
function ServerInfo()
|
||||
{
|
||||
$arr = array();
|
||||
$result = $this->do_query('select version()', -1, -1, false);
|
||||
if (!$result->EOF) $data = $result->fields;
|
||||
else $data = array();
|
||||
$arr['version'] = $arr['description'] = $data[0];
|
||||
//****// Where does $arr come from in ADOdb - doesn't appear global, maybe null? A possible bug?
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
$perf_table = perfmon_parent_ADOConnection::table(); // this was missing in the original ADOdb perf class - bug?
|
||||
|
||||
if (strtoupper(substr(trim($sql),0,6)) !== 'SELECT') return '<p>Unable to EXPLAIN a non-select statement</p>';
|
||||
$save = $this->LogSQL(false);
|
||||
if ($partial) {
|
||||
$sqlq = $this->qstr($sql.'%');
|
||||
$arr = $this->GetArray("select distinct sql1 from $perf_table where sql1 like $sqlq");
|
||||
if ($arr)
|
||||
{
|
||||
foreach($arr as $row)
|
||||
{
|
||||
$sql = reset($row);
|
||||
if (crc32($sql) == $partial) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$sql = str_replace('?',"''",$sql);
|
||||
|
||||
if ($partial)
|
||||
{
|
||||
$sqlq = $this->qstr($sql.'%');
|
||||
$sql = $this->GetOne("select sql1 from $perf_table where sql1 like $sqlq");
|
||||
}
|
||||
|
||||
$s = '<p><strong>Explain</strong>: '.htmlentities($sql, ENT_QUOTES, 'UTF-8').'</p>';
|
||||
$rs = $this->Execute('EXPLAIN '.$sql);
|
||||
$s .= rs2html($rs,false,false,false,false);
|
||||
$this->LogSQL($save);
|
||||
$s .= $this->Tracer($sql);
|
||||
return $s;
|
||||
}
|
||||
|
||||
function Tables()
|
||||
{
|
||||
if (!$this->tablesSQL) return false;
|
||||
|
||||
$rs = $this->Execute($this->tablesSQL);
|
||||
if (!$rs) return false;
|
||||
|
||||
$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 GetReads()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
$rs = $this->Execute('show status');
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!$rs) return 0;
|
||||
$val = 0;
|
||||
while (!$rs->EOF)
|
||||
{
|
||||
switch($rs->fields[0])
|
||||
{
|
||||
case 'Com_select':
|
||||
$val = $rs->fields[1];
|
||||
$rs->Close();
|
||||
return $val;
|
||||
}
|
||||
$rs->MoveNext();
|
||||
}
|
||||
|
||||
$rs->Close();
|
||||
return $val;
|
||||
}
|
||||
|
||||
function GetWrites()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
$rs = $this->Execute('show status');
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!$rs) return 0;
|
||||
$val = 0.0;
|
||||
while (!$rs->EOF)
|
||||
{
|
||||
switch($rs->fields[0])
|
||||
{
|
||||
case 'Com_insert':
|
||||
$val += $rs->fields[1];
|
||||
break;
|
||||
case 'Com_delete':
|
||||
$val += $rs->fields[1];
|
||||
break;
|
||||
case 'Com_update':
|
||||
$val += $rs->fields[1]/2;
|
||||
$rs->Close();
|
||||
return $val;
|
||||
}
|
||||
$rs->MoveNext();
|
||||
}
|
||||
|
||||
$rs->Close();
|
||||
return $val;
|
||||
}
|
||||
|
||||
function FindDBHitRatio()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
$rs = $this->Execute('show table status');
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!$rs) return '';
|
||||
$type = strtoupper($rs->fields[1]);
|
||||
$rs->Close();
|
||||
switch($type)
|
||||
{
|
||||
case 'MYISAM':
|
||||
case 'ISAM':
|
||||
return $this->DBParameter('MyISAM cache hit ratio').' (MyISAM)';
|
||||
case 'INNODB':
|
||||
return $this->DBParameter('InnoDB cache hit ratio').' (InnoDB)';
|
||||
default:
|
||||
return $type.' not supported';
|
||||
}
|
||||
}
|
||||
|
||||
function GetQHitRatio()
|
||||
{
|
||||
//Total number of queries = Qcache_inserts + Qcache_hits + Qcache_not_cached
|
||||
$hits = $this->_DBParameter(array("show status","Qcache_hits"));
|
||||
$total = $this->_DBParameter(array("show status","Qcache_inserts"));
|
||||
$total += $this->_DBParameter(array("show status","Qcache_not_cached"));
|
||||
|
||||
$total += $hits;
|
||||
if ($total) return round(($hits*100)/$total,2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Use session variable to store Hit percentage, because MySQL
|
||||
does not remember last value of SHOW INNODB STATUS hit ratio
|
||||
|
||||
# 1st query to SHOW INNODB STATUS
|
||||
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
|
||||
Buffer pool hit rate 1000 / 1000
|
||||
|
||||
# 2nd query to SHOW INNODB STATUS
|
||||
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
|
||||
No buffer pool activity since the last printout
|
||||
*/
|
||||
function GetInnoDBHitRatio()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
$rs = $this->Execute('show innodb status');
|
||||
;
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!$rs || $rs->EOF) return 0;
|
||||
$stat = $rs->fields[0];
|
||||
$rs->Close();
|
||||
$at = strpos($stat,'Buffer pool hit rate');
|
||||
$stat = substr($stat,$at,200);
|
||||
if (preg_match('!Buffer pool hit rate\s*([0-9]*) / ([0-9]*)!',$stat,$arr))
|
||||
{
|
||||
$val = 100*$arr[1]/$arr[2];
|
||||
$_SESSION['INNODB_HIT_PCT'] = $val;
|
||||
return round($val,2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($_SESSION['INNODB_HIT_PCT'])) return $_SESSION['INNODB_HIT_PCT'];
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function GetKeyHitRatio()
|
||||
{
|
||||
$hits = $this->_DBParameter(array("show status","Key_read_requests"));
|
||||
$reqs = $this->_DBParameter(array("show status","Key_reads"));
|
||||
if ($reqs == 0) return 0;
|
||||
|
||||
return round(($hits/($reqs+$hits))*100,2);
|
||||
}
|
||||
|
||||
// start hack
|
||||
var $optimizeTableLow = 'CHECK TABLE %s FAST QUICK';
|
||||
var $optimizeTableHigh = 'OPTIMIZE TABLE %s';
|
||||
|
||||
/**
|
||||
* @see adodb_perf#optimizeTable
|
||||
*/
|
||||
function optimizeTable( $table, $mode = ADODB_OPT_LOW)
|
||||
{
|
||||
if ( !is_string( $table)) return false;
|
||||
|
||||
$sql = '';
|
||||
switch( $mode)
|
||||
{
|
||||
case ADODB_OPT_LOW:
|
||||
$sql = $this->optimizeTableLow;
|
||||
break;
|
||||
case ADODB_OPT_HIGH:
|
||||
$sql = $this->optimizeTableHigh;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// May dont use __FUNCTION__ constant for BC (__FUNCTION__ Added in PHP 4.3.0)
|
||||
trigger_error(sprintf( "<p>%s: '%s' using of undefined mode '%s'</p>", __CLASS__, __FUNCTION__, $mode), E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$sql = sprintf( $sql, $table);
|
||||
|
||||
return $this->Execute( $sql) !== false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
eval('class mysql_perfmon_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysql_perfmon_ResultSet extends mysql_perfmon_resultset_EXTENDER
|
||||
{
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
$len = -1; // mysql max_length is not accurate
|
||||
switch (strtoupper($t)) {
|
||||
case 'STRING':
|
||||
case 'CHAR':
|
||||
case 'VARCHAR':
|
||||
case 'TINYBLOB':
|
||||
case 'TINYTEXT':
|
||||
case 'ENUM':
|
||||
case 'SET':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 'TEXT':
|
||||
case 'LONGTEXT':
|
||||
case 'MEDIUMTEXT':
|
||||
return 'X';
|
||||
|
||||
// php_mysql extension always returns 'blob' even if 'text'
|
||||
// so we have to check whether binary...
|
||||
case 'IMAGE':
|
||||
case 'LONGBLOB':
|
||||
case 'BLOB':
|
||||
case 'MEDIUMBLOB':
|
||||
return !empty($fieldobj->binary) ? 'B' : 'X';
|
||||
|
||||
case 'YEAR':
|
||||
case 'DATE': return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP': return 'T';
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER':
|
||||
case 'BIGINT':
|
||||
case 'TINYINT':
|
||||
case 'MEDIUMINT':
|
||||
case 'SMALLINT':
|
||||
|
||||
if (!empty($fieldobj->primary_key)) return 'R';
|
||||
else return 'I';
|
||||
|
||||
default: return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for Mysql
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mysql_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysql_transaction_ADOConnection extends mysql_transaction_EXTENDER
|
||||
{
|
||||
var $autoCommit = true;
|
||||
var $transOff = 0;
|
||||
var $transCnt = 0;
|
||||
var $transaction_status = true;
|
||||
|
||||
function StartTrans($errfn = 'ADODB_TransMonitor')
|
||||
{
|
||||
if ($this->transOff > 0) {
|
||||
$this->transOff += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->transaction_status = true;
|
||||
|
||||
if ($this->debug && $this->transCnt > 0)
|
||||
ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans");
|
||||
|
||||
$this->BeginTrans();
|
||||
$this->transOff = 1;
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function CompleteTrans($autoComplete = true)
|
||||
{
|
||||
if ($this->transOff > 1) {
|
||||
$this->transOff -= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->transOff = 0;
|
||||
if ($this->transaction_status && $autoComplete) {
|
||||
if (!$this->CommitTrans()) {
|
||||
$this->transaction_status = false;
|
||||
if ($this->debug)
|
||||
ADOConnection::outp("Smart Commit failed");
|
||||
} else
|
||||
if ($this->debug)
|
||||
ADOConnection::outp("Smart Commit occurred");
|
||||
} else {
|
||||
$this->transaction_status = false;
|
||||
$this->RollbackTrans();
|
||||
if ($this->debug)
|
||||
ADOCOnnection::outp("Smart Rollback occurred");
|
||||
}
|
||||
|
||||
return $this->transaction_status;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function FailTrans()
|
||||
{
|
||||
if ($this->debug)
|
||||
if ($this->transOff == 0) {
|
||||
ADOConnection::outp("FailTrans outside StartTrans/CompleteTrans");
|
||||
} else {
|
||||
ADOConnection::outp("FailTrans was called");
|
||||
}
|
||||
$this->transaction_status = false;
|
||||
}
|
||||
|
||||
function HasFailedTrans()
|
||||
{
|
||||
if ($this->transOff > 0)
|
||||
return $this->transaction_status == false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function RowLock($table,$where)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function CommitLock($table)
|
||||
{
|
||||
return $this->CommitTrans();
|
||||
}
|
||||
|
||||
function RollbackLock($table)
|
||||
{
|
||||
return $this->RollbackTrans();
|
||||
}
|
||||
}
|
||||
|
||||
eval('class mysql_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysql_transaction_ResultSet extends mysql_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
||||
Reference in new issue
Block a user