Added code for test website. Including:
* Smarty 2.6.19 * ASOdb Lite 1.42
This commit is contained in:
parent
bb78154265
commit
36d7c8e39e
312 changed files with 73558 additions and 0 deletions
1
utils/tests/autotester/.gitignore
vendored
Normal file
1
utils/tests/autotester/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
run_unit_tests.sh
|
40
utils/tests/autotester/run_unit_tests.php
Normal file
40
utils/tests/autotester/run_unit_tests.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
if ($argc != 2)
|
||||
{
|
||||
echo "Wrong number of parameters given";
|
||||
die;
|
||||
}
|
||||
$root_dir = $argv[1];
|
||||
|
||||
require_once $root_dir . 'include/config.php';
|
||||
|
||||
// used to show all queries to db when debuging;
|
||||
//$db->debug = true;
|
||||
// Upgrade the database format to the newest
|
||||
$creator = new DBCreator();
|
||||
$creator->checkDB();
|
||||
|
||||
// do svn up
|
||||
$svn = new SVNUpdater();
|
||||
|
||||
if ($svn->getRevision() === false)
|
||||
{
|
||||
trigger_error("SVN is down", E_USER_ERROR);
|
||||
}
|
||||
|
||||
$build = new Build($svn->getRevision());
|
||||
|
||||
if (!$build->Exists())
|
||||
{
|
||||
// Only run tests if build doesn't exists
|
||||
if ($build->compile($svn->getRevision()))
|
||||
{
|
||||
$test_runner = new TestRunner();
|
||||
$test_runner->run($build);
|
||||
}
|
||||
$db->CompleteTrans();
|
||||
}
|
||||
|
||||
$config = new Config('last_autotest_run_time');
|
||||
$config->set(time());
|
||||
?>
|
7
utils/tests/autotester/run_unit_tests.sh
Executable file
7
utils/tests/autotester/run_unit_tests.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
SVNDIR="/home/coren/wesnoth/trunk/"
|
||||
WEBDIR="/home/coren/wesnoth/trunk/utils/tests/htdocs/"
|
||||
AUTOTESTDIR="/home/coren/wesnoth/trunk/utils/tests/autotester/"
|
||||
cd $SVNDIR
|
||||
nice php -f $AUTOTESTDIR/run_unit_tests.php $WEBDIR
|
1
utils/tests/htdocs/include/.gitignore
vendored
Normal file
1
utils/tests/htdocs/include/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
config.php
|
219
utils/tests/htdocs/include/Build.php
Normal file
219
utils/tests/htdocs/include/Build.php
Normal file
|
@ -0,0 +1,219 @@
|
|||
<?php
|
||||
|
||||
class Build {
|
||||
private $db;
|
||||
private $id;
|
||||
private $svn_version;
|
||||
private $time;
|
||||
private $status;
|
||||
private $error_msg;
|
||||
|
||||
private $binary_name;
|
||||
private $previous_id;
|
||||
private $result;
|
||||
private $errors;
|
||||
|
||||
const S_GOOD = 0;
|
||||
const S_ERROR = 1;
|
||||
|
||||
function __construct($revision = -1)
|
||||
{
|
||||
global $db;
|
||||
$this->db = $db;
|
||||
$this->binary_name = false;
|
||||
$this->previous_id = -1;
|
||||
$this->result = null;
|
||||
$this->errors = array();
|
||||
if ($revision > 0)
|
||||
$this->fetch("WHERE svn_version=?", array($revision));
|
||||
}
|
||||
|
||||
private function fetch($where, $params = array())
|
||||
{
|
||||
$result = $this->db->Execute('SELECT * FROM builds ' . $where . ' LIMIT 1',$params);
|
||||
if ($result !== false && !$result->EOF())
|
||||
{
|
||||
$this->init($result->fields);
|
||||
} else {
|
||||
$this->reset();
|
||||
}
|
||||
}
|
||||
|
||||
public function fetchLast()
|
||||
{
|
||||
$this->fetch('ORDER BY id DESC');
|
||||
}
|
||||
|
||||
public function init($values)
|
||||
{
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
$this->$key = $value;
|
||||
}
|
||||
$this->time = $this->db->UnixTimeStamp($this->time);
|
||||
$this->result = null;
|
||||
$this->errors = array();
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->init(array('id' => -1,
|
||||
'svn_version' => -1,
|
||||
'time' => $this->db->DBTimeStamp(0),
|
||||
'status' => -1,
|
||||
'error_msg' => ""));
|
||||
$this->previous_id = -1;
|
||||
}
|
||||
|
||||
public function exists()
|
||||
{
|
||||
return $this->id > -1;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function getPreviousId()
|
||||
{
|
||||
if ($this->previous_id == -1)
|
||||
{
|
||||
$result = $this->db->Execute('SELECT MAX(id) as previous_id
|
||||
FROM builds
|
||||
WHERE id<?
|
||||
AND status=?',
|
||||
array($this->id,
|
||||
self::S_GOOD));
|
||||
$this->previous_id = $result->fields['previous_id'];
|
||||
}
|
||||
return $this->previous_id;
|
||||
}
|
||||
public function getLastWorkingId()
|
||||
{
|
||||
if ($this->status == self::S_GOOD)
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
return $this->getPreviousId();
|
||||
}
|
||||
|
||||
public function compile($revision)
|
||||
{
|
||||
$compiler_log = shell_exec('scons test 2>&1');
|
||||
$m =array();
|
||||
$this->error_msg = '';
|
||||
$this->status = self::S_GOOD;
|
||||
if (strpos($compiler_log, "`test' is up to date.") !== false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (preg_match_all('/^.*(error:|warning:|undefined reference|ld returned \d exit status).*$/mi',$compiler_log, $m,PREG_SET_ORDER))
|
||||
{
|
||||
|
||||
foreach($m as $match)
|
||||
{
|
||||
$this->error_msg .= $match[0] . "\n";
|
||||
}
|
||||
if (strpos($this->error_msg,'error') !== false
|
||||
|| strpos($this->error_msg,'ld returned'))
|
||||
$this->status = self::S_ERROR;
|
||||
}
|
||||
|
||||
if(preg_match('/test to \.\/([a-zA-Z0-9_-]*)/',$compiler_log, $m))
|
||||
{
|
||||
$this->binary_name = $m[1];
|
||||
}
|
||||
|
||||
$this->time = time();
|
||||
$this->svn_revision = $revision;
|
||||
|
||||
$this->db->StartTrans();
|
||||
|
||||
$this->insert();
|
||||
return $this->status == self::S_GOOD;
|
||||
}
|
||||
|
||||
public function getTestName()
|
||||
{
|
||||
return $this->binary_name;
|
||||
}
|
||||
|
||||
private function insert()
|
||||
{
|
||||
$result = $this->db->Execute('INSERT INTO builds
|
||||
(svn_version, status, error_msg)
|
||||
VALUES (?, ?, ?)',
|
||||
array($this->svn_revision,
|
||||
$this->status,
|
||||
$this->error_msg));
|
||||
|
||||
$this->id = $this->db->Insert_ID();
|
||||
}
|
||||
|
||||
public function insertNull()
|
||||
{
|
||||
if ($result = $this->db->Execute('SELECT id FROM builds WHERE id=?', array(0)))
|
||||
{
|
||||
if ($result->EOF())
|
||||
{
|
||||
$result = $this->db->Execute('INSERT INTO builds
|
||||
(svn_version, status, error_msg)
|
||||
VALUES (?, ?, ?)',
|
||||
array(0,
|
||||
self::S_GOOD,
|
||||
''));
|
||||
$this->id = $this->db->Insert_ID();
|
||||
|
||||
$this->db->Execute('UPDATE builds SET id=? WHERE id=?', array(0, $this->id));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function checkChilds()
|
||||
{
|
||||
if (is_null($this->result))
|
||||
{
|
||||
$this->result = new TestResult($this->getLastWorkingId());
|
||||
$this->errors = TestError::getErrorsForBuild($this->getLastWorkingId());
|
||||
}
|
||||
}
|
||||
|
||||
private function getErrorStatistics()
|
||||
{
|
||||
$ret = array();
|
||||
foreach($this->errors as $err)
|
||||
{
|
||||
$ret[] = $err->getStatistics();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getStatistics()
|
||||
{
|
||||
$this->checkChilds();
|
||||
|
||||
$build_result = '';
|
||||
if ($this->status == self::S_GOOD)
|
||||
{
|
||||
$build_result = $this->result->getResult();
|
||||
} else {
|
||||
$build_result = nl2br("Compilation failed:\n" . $this->error_msg);
|
||||
}
|
||||
|
||||
return array('build_result' => $build_result,
|
||||
'build_time' => $this->time,
|
||||
'build_error_msg' => $this->error_msg,
|
||||
'build_svn_rev' => $this->svn_version,
|
||||
'result_passed' => $this->result->getAssertionsPassed(),
|
||||
'result_failed' => $this->result->getAssertionsFailed(),
|
||||
'errors' => $this->getErrorStatistics());
|
||||
}
|
||||
}
|
||||
?>
|
23
utils/tests/htdocs/include/Config.php
Normal file
23
utils/tests/htdocs/include/Config.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
class Config {
|
||||
private $name;
|
||||
function __construct($name = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function insertDefaults()
|
||||
{
|
||||
}
|
||||
|
||||
public function set()
|
||||
{
|
||||
}
|
||||
|
||||
public function get()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
362
utils/tests/htdocs/include/DBCreator.php
Normal file
362
utils/tests/htdocs/include/DBCreator.php
Normal file
|
@ -0,0 +1,362 @@
|
|||
<?php
|
||||
|
||||
class DBForeignKey {
|
||||
private $name;
|
||||
private $field_name;
|
||||
private $reference;
|
||||
|
||||
function __construct($name, $field_name, $reference)
|
||||
{
|
||||
$this->field_name = $field_name;
|
||||
$this->name = $name;
|
||||
$this->reference = $reference;
|
||||
}
|
||||
public function getCreateSQL()
|
||||
{
|
||||
return "CONSTRAINT $this->name FOREIGN KEY ($this->field_name) REFERENCES $this->reference";
|
||||
}
|
||||
|
||||
public function match_and_alter($db, &$create_sql, $table_name)
|
||||
{
|
||||
$m = array();
|
||||
$needle = preg_replace("/[()]/","\\\\$0","/^.*CONSTRAINT `$this->name` FOREIGN KEY ($this->field_name) REFERENCES $this->reference.*$/im");
|
||||
if (!preg_match($needle,$create_sql))
|
||||
{
|
||||
// echo "$needle\n$create_sql\n";
|
||||
// echo "Creating foreign key $this->field_name in $table_name!\n";
|
||||
if (!$db->Execute("ALTER TABLE $table_name
|
||||
ADD CONSTRAINT $this->name
|
||||
FOREIGN KEY ($this->field_name)
|
||||
REFERENCES $this->reference"))
|
||||
{
|
||||
// echo "Failed to create foreign key!";
|
||||
}
|
||||
} else {
|
||||
$create_sql = preg_replace($needle,'',$create_sql);
|
||||
$create_sql = preg_replace("/^.*KEY (`$this->name`)? \\($this->field_name\\).*$/im",'',$create_sql);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DBIndex {
|
||||
private $field_name;
|
||||
private $type;
|
||||
private $key_name;
|
||||
|
||||
function __construct($field_name, $type, $key_name = '')
|
||||
{
|
||||
$this->field_name = $field_name;
|
||||
$this->type = $type;
|
||||
if (empty($key_name))
|
||||
$key_name = $field_name;
|
||||
$this->key_name = $key_name;
|
||||
}
|
||||
public function getCreateSQL()
|
||||
{
|
||||
return "$this->type $this->key_name ($this->field_name)";
|
||||
}
|
||||
|
||||
public function match_and_alter($db, &$create_sql, $table_name)
|
||||
{
|
||||
$m = array();
|
||||
$needle = "/^.*$this->type (`$this->key_name`)? \\(`$this->field_name`\\).*$/im";
|
||||
if (!preg_match($needle,$create_sql))
|
||||
{
|
||||
// echo "$needle\n$create_sql\n";
|
||||
// echo "Creating index $this->field_name in $table_name!\n";
|
||||
if (!$db->Execute("ALTER TABLE $table_name
|
||||
ADD $this->type $this->key_name ($this->field_name)"))
|
||||
{
|
||||
// echo "Failed to create key!\n";
|
||||
}
|
||||
} else {
|
||||
$create_sql = preg_replace($needle,'',$create_sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DBField {
|
||||
private $name;
|
||||
private $type;
|
||||
private $default;
|
||||
|
||||
function __construct($name, $type, $default = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->default = $default;
|
||||
}
|
||||
|
||||
public function getCreateSQL()
|
||||
{
|
||||
$default = '';
|
||||
if (!empty($this->default))
|
||||
{
|
||||
$default = 'DEFAULT ' . $this->default;
|
||||
}
|
||||
return "$this->name $this->type $default";
|
||||
}
|
||||
|
||||
public function match_and_alter($db, &$create_sql, $table_name)
|
||||
{
|
||||
$m = array();
|
||||
|
||||
$default = '';
|
||||
if (!empty($this->default))
|
||||
{
|
||||
$default = ' DEFAULT ' . $this->default;
|
||||
}
|
||||
$needle = "/^\\s*`$this->name`(.*),?$/im";
|
||||
if (preg_match($needle,$create_sql, $m))
|
||||
{
|
||||
// Found the field checking for correct type
|
||||
$type = preg_replace(array("/[()]/","/^([a-zA-Z1-9_]*) /"),array("\\\\$0","$1(\\(\\d*\\))? "), $this->type);
|
||||
if (!preg_match("/$type$default/i",$m[1]))
|
||||
{
|
||||
// echo $m[1] . "\n" . $type . "\n";
|
||||
// echo "Updateing column $this->name in $table_name!\n";
|
||||
if (!$db->Execute("ALTER TABLE $table_name
|
||||
MODIFY COLUMN $this->name $this->type $default"))
|
||||
{
|
||||
// echo "Failed to create column!\n";
|
||||
}
|
||||
}
|
||||
$create_sql = preg_replace($needle,'',$create_sql);
|
||||
} else {
|
||||
// Add new field
|
||||
// echo "Creating column $this->name in $table_name!\n";
|
||||
|
||||
if (!$db->Execute("ALTER TABLE $table_name
|
||||
ADD COLUMN $this->name $this->type $default"))
|
||||
{
|
||||
// echo "Failed to modify column!\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class DBTable {
|
||||
private $fields;
|
||||
|
||||
private $name;
|
||||
private $engine;
|
||||
|
||||
function __construct($name, $engine = 'MYISAM')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->engine = $engine;
|
||||
$this->fields = array();
|
||||
}
|
||||
|
||||
public function addChild($child)
|
||||
{
|
||||
$this->fields[] = $child;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function check($db)
|
||||
{
|
||||
$result = $db->Execute("SHOW CREATE TABLE $this->name");
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
echo "Error reading create info for $this->name table\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
$create_sql = $result->fields['Create Table'];
|
||||
|
||||
foreach($this->fields as $id => $field)
|
||||
{
|
||||
$field->match_and_alter($db,$create_sql, $this->name);
|
||||
}
|
||||
$m = array();
|
||||
if (preg_match_all('/^\s*`(.*)` .*(int|varchar|text|blob|char|NULL|NOT NULL|timestamp|date).*$/m',$create_sql,$m,PREG_SET_ORDER))
|
||||
{
|
||||
foreach($m as $col)
|
||||
{
|
||||
try {
|
||||
$colname = $col[1];
|
||||
$db->Execute("ALTER TABLE $this->name
|
||||
DROP COLUMN $colname");
|
||||
} catch(exception $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (preg_match_all('/^\s*(CONSTRAINT|KEY|PRIMARY KEY|UNIQUE KEY) (`(.*)`)? .*$/m',$create_sql,$m,PREG_SET_ORDER))
|
||||
{
|
||||
foreach($m as $index)
|
||||
{
|
||||
try {
|
||||
$indexname = '';
|
||||
if (isset($index[3]))
|
||||
$indexname = $index[3];
|
||||
$type = $index[1];
|
||||
switch($type)
|
||||
{
|
||||
case "CONSTRAINT":
|
||||
$db->Execute("ALTER TABLE $this->name
|
||||
DREP FOREIGN KEY $indexname");
|
||||
break;
|
||||
case "PRIMARY KEY":
|
||||
$db->Execute("ALTER TABLE $this->name
|
||||
DROP PRIMARY KEY");
|
||||
break;
|
||||
case "UNIQUE KEY":
|
||||
case "KEY":
|
||||
$db->Execute("ALTER TABLE $this->name
|
||||
DROP KEY $indexname");
|
||||
break;
|
||||
}
|
||||
} catch(exception $e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function createTable($db)
|
||||
{
|
||||
// echo "Creating table '$this->name'\n";
|
||||
$sql = "CREATE TABLE $this->name (";
|
||||
foreach($this->fields as $field)
|
||||
{
|
||||
$sql .= $field->getCreateSQL() . ',';
|
||||
}
|
||||
$sql = rtrim($sql, ',') . ") ENGINE=$this->engine";
|
||||
|
||||
if($db->Execute($sql) === false)
|
||||
{
|
||||
echo "Error creating table $this->name!\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DBFormat {
|
||||
private $tables;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->tables = array();
|
||||
}
|
||||
|
||||
public function addChild($table)
|
||||
{
|
||||
$this->tables[] = $table;
|
||||
}
|
||||
|
||||
public function checkDB($db)
|
||||
{
|
||||
$result = $db->Execute('show tables');
|
||||
$dbtables = array();
|
||||
if ($result !== false)
|
||||
{
|
||||
while(!$result->EOF())
|
||||
{
|
||||
$dbtables[$result->fields['Tables_in_wesnoth_unit_test']] = true;
|
||||
$result->MoveNext();
|
||||
}
|
||||
} else {
|
||||
echo 'show tables failed';
|
||||
exit;
|
||||
}
|
||||
|
||||
// check for missing and old tables
|
||||
foreach($this->tables as $table)
|
||||
{
|
||||
if (!isset($dbtables[$table->getName()]))
|
||||
{
|
||||
// create missing table
|
||||
$table->createTable($db);
|
||||
} else {
|
||||
// check if this table needs updateing
|
||||
$table->check($db);
|
||||
unset($dbtables[$table->getname()]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($dbtables as $name => $bool)
|
||||
{
|
||||
$db->Execute('DROP TABLE ' . $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DBCreator {
|
||||
private $db;
|
||||
private $format;
|
||||
function __construct()
|
||||
{
|
||||
global $db;
|
||||
$this->format = new DBFormat();
|
||||
|
||||
$configtable = new DBTable('configs', 'InnoDB');
|
||||
$configtable->addChild(new DBField('name', 'VARCHAR(255) NOT NULL'));
|
||||
$configtable->addChild(new DBField('value', 'VARCHAR(255) NOT NULL'));
|
||||
$configtable->addChild(new DBIndex('name', 'PRIMARY KEY'));
|
||||
$this->format->addChild($configtable);
|
||||
|
||||
$buildstable = new DBTable('builds', 'InnoDB');
|
||||
$buildstable->addChild(new DBField('id', 'INT NOT NULL AUTO_INCREMENT'));
|
||||
$buildstable->addChild(new DBField('svn_version', 'INT NOT NULL'));
|
||||
$buildstable->addChild(new DBField('time', 'TIMESTAMP NOT NULL', 'CURRENT_TIMESTAMP'));
|
||||
$buildstable->addChild(new DBField('status', 'INT NOT NULL'));
|
||||
$buildstable->addChild(new DBField('error_msg', 'BLOB NOT NULL'));
|
||||
$buildstable->addChild(new DBIndex('id', 'PRIMARY KEY'));
|
||||
$buildstable->addChild(new DBIndex('time', 'KEY'));
|
||||
$this->format->addChild($buildstable);
|
||||
|
||||
$errortable = new DBTable('test_errors', 'InnoDB');
|
||||
$errortable->addChild(new DBField('id', 'INT NOT NULL AUTO_INCREMENT'));
|
||||
$errortable->addChild(new DBField('before_id', 'INT NOT NULL'));
|
||||
$errortable->addChild(new DBField('last_id', 'INT NOT NULL'));
|
||||
$errortable->addChild(new DBField('error_type', 'VARCHAR(10) NOT NULL'));
|
||||
$errortable->addChild(new DBField('file', 'VARCHAR(255) NOT NULL'));
|
||||
$errortable->addChild(new DBField('line', 'INT NOT NULL'));
|
||||
$errortable->addChild(new DBField('error_msg', 'BLOB NOT NULL'));
|
||||
$errortable->addChild(new DBIndex('id', 'PRIMARY KEY'));
|
||||
$errortable->addChild(new DBForeignKey('test_errors_before_id_key','`before_id`', '`builds` (`id`)'));
|
||||
$errortable->addChild(new DBForeignKey('test_errors_last_id_key','`last_id`', '`builds` (`id`)'));
|
||||
$this->format->addChild($errortable);
|
||||
|
||||
$resulttable = new DBTable('test_results', 'InnoDB');
|
||||
$resulttable->addChild(new DBField('id', 'INT NOT NULL AUTO_INCREMENT'));
|
||||
$resulttable->addChild(new DBField('build_id', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('result', 'VARCHAR(10) NOT NULL'));
|
||||
$resulttable->addChild(new DBField('assertions_passed', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('assertions_failed', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('test_cases_passed', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('test_cases_failed', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('test_cases_skipped', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('test_cases_aborted', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBIndex('id', 'PRIMARY KEY'));
|
||||
$resulttable->addChild(new DBForeignKey('test_results_build_id_key', '`build_id`', '`builds` (`id`)'));
|
||||
$this->format->addChild($resulttable);
|
||||
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function checkDB()
|
||||
{
|
||||
$this->db->StartTrans();
|
||||
$this->format->checkDB($this->db);
|
||||
|
||||
$build = new Build();
|
||||
$build->insertNull();
|
||||
|
||||
$config = new Config();
|
||||
$config->insertDefaults();
|
||||
$this->db->CompleteTrans();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
19
utils/tests/htdocs/include/Footer.php
Normal file
19
utils/tests/htdocs/include/Footer.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
class Footer
|
||||
{
|
||||
private $file;
|
||||
private $smarty;
|
||||
function __construct($file)
|
||||
{
|
||||
global $smarty;
|
||||
$this->file = $file;
|
||||
$this->smarty = $smarty;
|
||||
}
|
||||
|
||||
public function show()
|
||||
{
|
||||
$this->smarty->display('footer.tpl');
|
||||
}
|
||||
}
|
||||
?>
|
19
utils/tests/htdocs/include/Header.php
Normal file
19
utils/tests/htdocs/include/Header.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
class Header
|
||||
{
|
||||
private $file;
|
||||
private $smarty;
|
||||
function __construct($file)
|
||||
{
|
||||
global $smarty;
|
||||
$this->file = $file;
|
||||
$this->smarty = $smarty;
|
||||
}
|
||||
|
||||
public function show()
|
||||
{
|
||||
$this->smarty->display('header.tpl');
|
||||
}
|
||||
}
|
||||
?>
|
34
utils/tests/htdocs/include/SVNUpdater.php
Normal file
34
utils/tests/htdocs/include/SVNUpdater.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
class SVNUpdater {
|
||||
private $revision;
|
||||
function __construct()
|
||||
{
|
||||
$this->updateSVN();
|
||||
}
|
||||
|
||||
public function getRevision()
|
||||
{
|
||||
return $this->revision;
|
||||
}
|
||||
|
||||
private function updateSVN()
|
||||
{
|
||||
$success = false;
|
||||
$m = array();
|
||||
$tries = 3;
|
||||
while(!$success && $tries--)
|
||||
{
|
||||
$svnlog = shell_exec('svn up 2>&1');
|
||||
$success = preg_match('/At revision ([0-9]*)\./', $svnlog, $m);
|
||||
if (!$success)
|
||||
sleep(15);
|
||||
}
|
||||
if ($success)
|
||||
$this->revision = (int)$m[1];
|
||||
else
|
||||
$this->revision = false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
138
utils/tests/htdocs/include/TestError.php
Normal file
138
utils/tests/htdocs/include/TestError.php
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
|
||||
class TestError {
|
||||
private $db;
|
||||
private $id;
|
||||
private $before_id;
|
||||
private $last_id;
|
||||
private $error_type;
|
||||
private $file;
|
||||
private $line;
|
||||
private $error_msg;
|
||||
|
||||
private $start_version;
|
||||
private $end_version;
|
||||
|
||||
function __construct($name = null, $data = null, Build $build = null)
|
||||
{
|
||||
global $db;
|
||||
$this->db = $db;
|
||||
$this->start_version = -1;
|
||||
$this->end_version = -1;
|
||||
if (!is_null($name))
|
||||
{
|
||||
$this->error_type = $name;
|
||||
$this->file = (string)$data->attributes()->file;
|
||||
$this->line = (string)$data->attributes()->line;
|
||||
$this->error_msg = (string)$data[0];
|
||||
$result = $this->db->Execute('SELECT id, before_id, last_id FROM test_errors
|
||||
WHERE error_type=?
|
||||
AND file=?
|
||||
AND line=?
|
||||
AND error_msg=?
|
||||
AND last_id=?
|
||||
LIMIT 1',
|
||||
array($this->error_type,
|
||||
$this->file,
|
||||
$this->line,
|
||||
$this->error_msg,
|
||||
$build->getPreviousId()
|
||||
));
|
||||
if (!$result->EOF())
|
||||
{
|
||||
$this->id = $result->fields['id'];
|
||||
$this->before_id = $result->fields['before_id'];
|
||||
$this->last_id = $result->fields['last_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fetch($where, $params =array(), $fields = '*')
|
||||
{
|
||||
$result = $this->db->Execute("SELECT $fields FROM test_errors $where LIMIT 1",$params);
|
||||
if (!$result->EOF())
|
||||
{
|
||||
$this->init($result->fields);
|
||||
}
|
||||
}
|
||||
|
||||
private function init($values)
|
||||
{
|
||||
$this->start_version = -1;
|
||||
$this->end_version = -1;
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getErrorsForBuild($id)
|
||||
{
|
||||
global $db;
|
||||
$ret = array();
|
||||
$result = $db->Execute('SELECT * FROM test_errors
|
||||
WHERE before_id<? AND last_id >=?',
|
||||
array($id,$id));
|
||||
while(!$result->EOF())
|
||||
{
|
||||
$error = new TestError();
|
||||
$error->init($result->fields);
|
||||
$ret[] = $error;
|
||||
$result->moveNext();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function updateDB(Build $build)
|
||||
{
|
||||
if (is_null($this->id))
|
||||
{
|
||||
$this->before_id = $build->getPreviousId();
|
||||
$this->last_id = $build->getId();
|
||||
$this->insert();
|
||||
} else {
|
||||
$this->db->Execute('UPDATE test_errors SET last_id=? WHERE id=?', array($build->getid(), $this->id));
|
||||
}
|
||||
}
|
||||
|
||||
private function insert()
|
||||
{
|
||||
$this->db->Execute('INSERT INTO test_errors (before_id, last_id, error_type, file, line, error_msg)
|
||||
VALUES (?, ?, ?, ?, ?, ?)',
|
||||
array($this->before_id,$this->last_id,$this->error_type,$this->file,$this->line,$this->error_msg));
|
||||
$this->id = $this->db->Insert_ID();
|
||||
}
|
||||
|
||||
public function getStatistics()
|
||||
{
|
||||
return array('error_type' => $this->error_type,
|
||||
'start_version' => $this->getStartVersion(),
|
||||
'end_version' => $this->getEndVersion(),
|
||||
'file' => $this->file,
|
||||
'line' => $this->line,
|
||||
'error_msg' => $this->error_msg);
|
||||
}
|
||||
|
||||
public function getStartVersion()
|
||||
{
|
||||
if ($this->start_version == -1)
|
||||
{
|
||||
$result = $this->db->Execute('SELECT svn_version as start_version FROM builds WHERE id=?',array($this->before_id));
|
||||
$this->start_version = $result->fields['start_version'];
|
||||
}
|
||||
return $this->start_version;
|
||||
}
|
||||
|
||||
public function getEndVersion()
|
||||
{
|
||||
if ($this->end_version == -1)
|
||||
{
|
||||
$result = $this->db->Execute('SELECT svn_version as end_version FROM builds WHERE id=?',array($this->last_id));
|
||||
$this->end_version = $result->fields['end_version'];
|
||||
}
|
||||
return $this->end_version;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
110
utils/tests/htdocs/include/TestResult.php
Normal file
110
utils/tests/htdocs/include/TestResult.php
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
class TestResult {
|
||||
private $db;
|
||||
private $id;
|
||||
private $build_id;
|
||||
private $name;
|
||||
private $result;
|
||||
private $assertions_passed;
|
||||
private $assertions_failed;
|
||||
private $test_cases_passed;
|
||||
private $test_cases_failed;
|
||||
private $test_cases_skipped;
|
||||
private $test_cases_aborted;
|
||||
|
||||
function __construct($data = null, Build $build = null)
|
||||
{
|
||||
global $db;
|
||||
$this->db = $db;
|
||||
if (!is_null($data))
|
||||
{
|
||||
if ($data instanceof SimpleXMLElement)
|
||||
{
|
||||
$this->build_id = $build->getId();
|
||||
$attr = $data->attributes();
|
||||
foreach($attr as $name => $value)
|
||||
{
|
||||
$this->$name = (string)$value;
|
||||
if (is_numeric($this->name))
|
||||
$this->$name = (int)$this->$name;
|
||||
}
|
||||
} else {
|
||||
$this->fetch('WHERE build_id = ?', array($data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fetch($where, $params = array())
|
||||
{
|
||||
$result = $this->db->Execute('SELECT * FROM test_results '
|
||||
. $where . ' LIMIT 1', $params);
|
||||
if (!$result->EOF())
|
||||
{
|
||||
$this->init($result->fields);
|
||||
} else {
|
||||
$this->reset();
|
||||
}
|
||||
}
|
||||
|
||||
private function init($values)
|
||||
{
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
private function reset()
|
||||
{
|
||||
$this->id = -1;
|
||||
$this->build_id = -1;
|
||||
$this->name = '';
|
||||
$this->result = '';
|
||||
$this->assertions_passed = -1;
|
||||
$this->assertions_failed = -1;
|
||||
$this->test_cases_passed = -1;
|
||||
$this->test_cases_failed = -1;
|
||||
$this->test_cases_skipped = -1;
|
||||
$this->test_cases_aborted = -1;
|
||||
|
||||
}
|
||||
|
||||
public function updateDB()
|
||||
{
|
||||
if (!empty($this->result))
|
||||
$this->insert();
|
||||
}
|
||||
|
||||
private function insert()
|
||||
{
|
||||
$this->db->Execute('INSERT INTO test_results
|
||||
(build_id, result, assertions_passed,
|
||||
assertions_failed, test_cases_passed,
|
||||
test_cases_failed, test_cases_skipped,
|
||||
test_cases_aborted)
|
||||
VALUES(?,?,?,
|
||||
?,?,
|
||||
?,?,
|
||||
?)',
|
||||
array($this->build_id, $this->result, $this->assertions_passed,
|
||||
$this->assertions_failed, $this->test_cases_passed,
|
||||
$this->test_cases_failed, $this->test_cases_skipped,
|
||||
$this->test_cases_aborted));
|
||||
}
|
||||
|
||||
public function getResult()
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
public function getAssertionsPassed()
|
||||
{
|
||||
return $this->assertions_passed;
|
||||
}
|
||||
|
||||
public function getAssertionsFailed()
|
||||
{
|
||||
return $this->assertions_failed;
|
||||
}
|
||||
}
|
||||
?>
|
43
utils/tests/htdocs/include/TestRunner.php
Normal file
43
utils/tests/htdocs/include/TestRunner.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
class TestRunner {
|
||||
function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function run(Build $build)
|
||||
{
|
||||
$binary_name = $build->getTestName();
|
||||
if ($binary_name === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
$test_output = '<UnitTest>'.shell_exec("./$binary_name --log_format=XML --report_format=XML 2>&1").'</UnitTest>';
|
||||
|
||||
//$test_output = '<UnitTest><TestLog><Message file="./boost/test/impl/results_collector.ipp" line="220">Test case test_user_team_name doesn't include any assertions</Message><Error file="build/debug/tests/test_config_cache.cpp" line="84">check defines_map.size() == cache.get_preproc_map().size() failed [2 != 0]</Error></TestLog>
|
||||
//<TestResult><TestSuite name="wesnoth unit tests master suite"
|
||||
//result="failed"
|
||||
//assertions_passed="112"
|
||||
//assertions_failed="1"
|
||||
//expected_failures="0"
|
||||
//test_cases_passed="17"
|
||||
//test_cases_failed="1"
|
||||
//test_cases_skipped="0"
|
||||
//test_cases_aborted="0"></TestSuite>
|
||||
//</TestResult></UnitTest>';
|
||||
$xml = simplexml_load_string($test_output);
|
||||
foreach($xml->TestLog[0] as $name => $data)
|
||||
{
|
||||
$test_error = new TestError($name, $data, $build);
|
||||
$test_error->updateDB($build);
|
||||
}
|
||||
|
||||
foreach($xml->TestResult[0] as $name => $data)
|
||||
{
|
||||
$test_report = new TestResult($data, $build);
|
||||
$test_report->updateDB();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
16
utils/tests/htdocs/include/WesnothSmarty.php
Normal file
16
utils/tests/htdocs/include/WesnothSmarty.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
global $smarty_dir;
|
||||
require(/*$smarty_dir .*/ 'smarty/libs/Smarty.class.php');
|
||||
|
||||
class WesnothSmarty extends Smarty {
|
||||
function __construct($work_dir)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->template_dir = $work_dir . '/templates';
|
||||
$this->compile_dir = $work_dir . '/templates_c';
|
||||
$this->cache_dir = $work_dir . '/cache';
|
||||
$this->config_dir = $work_dir . '/configs';
|
||||
}
|
||||
}
|
||||
?>
|
838
utils/tests/htdocs/include/adodb_lite/adodb-datadict.inc.php
Normal file
838
utils/tests/htdocs/include/adodb_lite/adodb-datadict.inc.php
Normal file
|
@ -0,0 +1,838 @@
|
|||
<?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.
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
277
utils/tests/htdocs/include/adodb_lite/adodb-error.inc.php
Normal file
277
utils/tests/htdocs/include/adodb_lite/adodb-error.inc.php
Normal file
|
@ -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;
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
/**
|
||||
* @version V4.66 28 Sept 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.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* @version V4.66 28 Sept 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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @version V4.66 28 Sept 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.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
?>
|
974
utils/tests/htdocs/include/adodb_lite/adodb-perf-module.inc.php
Normal file
974
utils/tests/htdocs/include/adodb_lite/adodb-perf-module.inc.php
Normal file
|
@ -0,0 +1,974 @@
|
|||
<?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.
|
||||
|
||||
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 (maugrimtr@hotmail.com)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
241
utils/tests/htdocs/include/adodb_lite/adodb-perf.inc.php
Normal file
241
utils/tests/htdocs/include/adodb_lite/adodb-perf.inc.php
Normal file
|
@ -0,0 +1,241 @@
|
|||
<?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.
|
||||
|
||||
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 (maugrimtr@hotmail.com)
|
||||
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
1313
utils/tests/htdocs/include/adodb_lite/adodb-time.inc.php
Normal file
1313
utils/tests/htdocs/include/adodb_lite/adodb-time.inc.php
Normal file
File diff suppressed because it is too large
Load diff
2338
utils/tests/htdocs/include/adodb_lite/adodb-xmlschema.inc.php
Normal file
2338
utils/tests/htdocs/include/adodb_lite/adodb-xmlschema.inc.php
Normal file
File diff suppressed because it is too large
Load diff
52
utils/tests/htdocs/include/adodb_lite/adodb.config.php
Normal file
52
utils/tests/htdocs/include/adodb_lite/adodb.config.php
Normal file
|
@ -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";
|
||||
?>
|
392
utils/tests/htdocs/include/adodb_lite/adodb.inc.php
Normal file
392
utils/tests/htdocs/include/adodb_lite/adodb.inc.php
Normal file
|
@ -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="";
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,65 @@
|
|||
<?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_fbsql extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'fbsql';
|
||||
var $seqField = false;
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'VARCHAR(250)';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'VARCHAR(250)';
|
||||
|
||||
case 'B': return 'VARCHAR';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATE';
|
||||
|
||||
case 'L': return 'DECIMAL(1)';
|
||||
case 'I': return 'DECIMAL(10)';
|
||||
case 'I1': return 'DECIMAL(3)';
|
||||
case 'I2': return 'DECIMAL(5)';
|
||||
case 'I4': return 'DECIMAL(10)';
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
|
||||
case 'F': return 'DECIMAL(32,8)';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for Frontbase
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
eval('class fbsql_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class fbsql_date_ADOConnection extends fbsql_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 = false; /// name of function that returns the current date
|
||||
var $sysTimeStamp = false; /// name of function that returns the current timestamp
|
||||
var $isoDates = false; /// accepts dates in ISO format
|
||||
|
||||
function Time()
|
||||
{
|
||||
$rs =& $this->_Execute("select $this->sysTimeStamp");
|
||||
if ($rs && !$rs->EOF)
|
||||
return $this->UnixTimeStamp(reset($rs->fields));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
|
||||
return '('.$date.'+'.$dayFraction.')';
|
||||
}
|
||||
|
||||
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'";
|
||||
|
||||
$timestamp = $this->UnixTimeStamp($timestamp);
|
||||
return adodb_date($this->fmtTimeStamp, $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]);
|
||||
else 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;
|
||||
else return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col)
|
||||
$col = $this->sysDate;
|
||||
return $col;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class fbsql_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class fbsql_date_ResultSet extends fbsql_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 fbsql_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return fbsql_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,626 @@
|
|||
<?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 fbsql_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
function fbsql_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'fbsql';
|
||||
$this->dataProvider = 'fbsql';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('fbsql_pconnect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->database = $database;
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
if($this->persistent == 1)
|
||||
{
|
||||
$this->connectionId = @fbsql_pconnect( $this->host, $this->username, $this->password );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connectionId = @fbsql_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 = @fbsql_select_db( $this->database, $this->connectionId );
|
||||
|
||||
if($result === false)
|
||||
{
|
||||
if($this->createdatabase == true)
|
||||
{
|
||||
$result = @fbsql_query( "CREATE DATABASE " . $this->database, $this->connectionId );
|
||||
if ($result === false) { // error handling if query fails
|
||||
return false;
|
||||
}
|
||||
$result = @fbsql_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()
|
||||
{
|
||||
return @fbsql_error($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
return @fbsql_errno($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @fbsql_affected_rows($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return @fbsql_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) {
|
||||
$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();
|
||||
foreach ($arr as $arg) {
|
||||
$list[] = "'" . $arg . "'";
|
||||
}
|
||||
|
||||
$s = implode(', ',$list);
|
||||
|
||||
if (strlen($s) > 0) return "CONCAT($s)";
|
||||
else return '';
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " CASE WHEN $field is null THEN $ifNull ELSE $field END ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@fbsql_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 != -1 || $nrows != -1)
|
||||
// {
|
||||
// $offset = ($offset>=0) ? $offset . "," : '';
|
||||
// $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 . ";";
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @fbsql_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 . ";");
|
||||
}
|
||||
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 . ";";
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @fbsql_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 . ";");
|
||||
}
|
||||
}
|
||||
|
||||
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 = FBSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$recordset->fetchMode = FBSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$recordset->fetchMode = FBSQL_ASSOC; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @fbsql_num_rows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @fbsql_num_fields( $resultId );
|
||||
$recordset->_fetch();
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class fbsql_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 fbsql_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()
|
||||
{
|
||||
fbsql_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 = fbsql_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 @fbsql_data_seek($this->resultId,$row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @fbsql_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 = @fbsql_fetch_field($this->resultId, $fieldOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$fieldObject = @fbsql_fetch_field($this->resultId);
|
||||
}
|
||||
return $fieldObject;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class fbsql_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class fbsql_extend_ADOConnection extends fbsql_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;
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function DropSequence($seqname='adodbseq')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class fbsql_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class fbsql_extend_ResultSet extends fbsql_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,499 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for Fbsql
|
||||
*
|
||||
* 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 fbsql_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class fbsql_meta_ADOConnection extends fbsql_meta_EXTENDER
|
||||
{
|
||||
var $metaDatabasesSQL = '';
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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 = fbsql_list_dbs($this->_connectionID);
|
||||
$arr = array();
|
||||
$i = 0;
|
||||
$max = fbsql_num_rows($qid);
|
||||
while ($i < $max) {
|
||||
$arr[] = fbsql_tablename($qid,$i);
|
||||
$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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if ($this->metaColumnsSQL) {
|
||||
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
|
||||
|
||||
if ($rs === false) return false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF){
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
|
||||
// split type into type(length):
|
||||
if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array)) {
|
||||
$fld->type = $query_array[1];
|
||||
$fld->max_length = $query_array[2];
|
||||
} else {
|
||||
$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($fld->type,'blob') !== false);
|
||||
|
||||
$retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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 fbsql_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class fbsql_meta_ResultSet extends fbsql_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';
|
||||
|
||||
case 'CHARACTER':
|
||||
case 'CHARACTER VARYING':
|
||||
case 'BLOB':
|
||||
case 'CLOB':
|
||||
case 'BIT':
|
||||
case 'BIT VARYING':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
// 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 'TIME WITH TIME ZONE':
|
||||
case 'TIMESTAMP':
|
||||
case 'TIMESTAMP WITH TIME ZONE': return 'T';
|
||||
|
||||
case 'PRIMARY_KEY':
|
||||
return 'R';
|
||||
|
||||
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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for Frontbase
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class fbsql_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class fbsql_transaction_ADOConnection extends fbsql_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 fbsql_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class fbsql_transaction_ResultSet extends fbsql_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
## Gladius Database Engine
|
||||
# @author legolas558
|
||||
# @version 0.3.94
|
||||
# Licensed under GNU General Public License (GPL)
|
||||
# contains parts of mysql_datadict.inc v4.65 by John Lim (jlim@natsoft.com.my)
|
||||
#
|
||||
#
|
||||
# ADODB driver
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_gladius extends ADODB_DataDict {
|
||||
var $dbtype = 'gladius';
|
||||
var $alterCol = ' MODIFY COLUMN'; // not yet supported on Gladius
|
||||
var $alterTableAddIndex = true;
|
||||
var $dropTable = 'DROP TABLE %s';
|
||||
|
||||
var $dropIndex = 'DROP INDEX %s ON %s'; // not yet supported on Gladius
|
||||
var $renameColumn = 'ALTER TABLE %s CHANGE COLUMN %s %s %s'; // needs column-definition!
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'VARCHAR(250)';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'VARCHAR(250)';
|
||||
|
||||
case 'B': return 'VARCHAR';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATE';
|
||||
|
||||
case 'L': return 'DECIMAL(1)';
|
||||
case 'I': return 'DECIMAL(10)';
|
||||
case 'I1': return 'DECIMAL(3)';
|
||||
case 'I2': return 'DECIMAL(5)';
|
||||
case 'I4': return 'DECIMAL(10)';
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
|
||||
case 'F': return 'DECIMAL(32,8)';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
// 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,329 @@
|
|||
<?php
|
||||
## Gladius Database Engine
|
||||
# @author legolas558
|
||||
# @version 0.3.94
|
||||
# Licensed under GNU General Public License (GPL)
|
||||
#
|
||||
#
|
||||
# adoDB lite date module
|
||||
# NOT FULLY WORKING
|
||||
#
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
eval('class gladius_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class gladius_date_ADOConnection extends gladius_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 = 'DATE()';
|
||||
var $sysTimeStamp = 'NOW()';
|
||||
var $isoDates = true; // accepts dates in ISO format
|
||||
|
||||
function Time()
|
||||
{
|
||||
return false;
|
||||
$rs =& $this->_Execute('select '.$this->sysTimeStamp);
|
||||
if ($rs && !$rs->EOF)
|
||||
return $this->UnixTimeStamp(reset($rs->fields));
|
||||
else return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
return 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)
|
||||
{
|
||||
return 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 gladius_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class gladius_date_ResultSet extends gladius_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 gladius_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return gladius_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,289 @@
|
|||
<?php
|
||||
## Gladius Database Engine
|
||||
# @author legolas558
|
||||
# @version 0.3.94
|
||||
# Licensed under GNU General Public License (GPL)
|
||||
#
|
||||
#
|
||||
# ADODB lite main driver
|
||||
|
||||
class gladius_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
var $nameQuote = ''; // identifier delimiters not supported!
|
||||
var $sysDate = 'DATE()'; // function not yet available! (v0.3)
|
||||
var $sysTimeStamp = 'NOW()';// function not yet available! (v0.3)
|
||||
|
||||
var $g; // instance of Gladius engine
|
||||
|
||||
function gladius_driver_ADOConnection()
|
||||
{
|
||||
$this->g = new Gladius();
|
||||
$this->g->fetch_mode =& $GLOBALS['ADODB_FETCH_MODE'];
|
||||
$this->dbtype = 'gladius';
|
||||
$this->dataProvider = 'gladius';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host_ignored, $username_ignored, $password_ignored, $database = '', $persistent_ignored, $forcenew_ignored)
|
||||
{
|
||||
if ($database!=='')
|
||||
return $this->SelectDB( $database );
|
||||
else
|
||||
$this->database = $database;
|
||||
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;
|
||||
|
||||
return $this->g->SelectDB($dbname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error message
|
||||
* Usage: $errormessage =& $db->ErrorMsg();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
return $this->g->errstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
return $this->g->errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return $this->g->affected_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return $this->g->insert_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return "'".$this->g->escape($string, $magic_quotes)."'";
|
||||
}
|
||||
|
||||
function QMagic($string)
|
||||
{
|
||||
return $this->qstr($string, get_magic_quotes_gpc());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns concatenated string
|
||||
* Usage: $db->Concat($str1,$str2);
|
||||
*
|
||||
* @return concatenated string
|
||||
* NOT IMPLEMENTED
|
||||
* software emulation?
|
||||
*/
|
||||
function Concat()
|
||||
{
|
||||
$arr = func_get_args();
|
||||
$list = implode(', ', $arr);
|
||||
|
||||
if (strlen($list) > 0) return "CONCAT($list)";
|
||||
else return '';
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
$this->g->Close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns All Records in an array
|
||||
*
|
||||
* Usage: $db->GetAll($sql);
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function &GetAll($sql, $inputarr = false)
|
||||
{
|
||||
return $this->GetArray($sql, $inputarr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns All Records in an array
|
||||
*
|
||||
* Usage: $db->GetArray($sql);
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function &GetArray($sql, $inputarr = false)
|
||||
{
|
||||
$data =& $this->Execute($sql, $inputarr);
|
||||
if (!is_bool($data))
|
||||
$data = $data->GetArray();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes SQL query and instantiates resultset methods
|
||||
*
|
||||
* @access private
|
||||
* @return mixed Resultset methods
|
||||
*/
|
||||
|
||||
function &do_query( $sql, $offset, $nrows, $inputarr=false )
|
||||
{
|
||||
$false = false;
|
||||
|
||||
$limit = '';
|
||||
if ($offset != -1 || $nrows != -1)
|
||||
{
|
||||
$offset = ($offset>=0) ? $offset. ", " : '';
|
||||
$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++;
|
||||
$recordset = $this->g->Query( $this->sql );
|
||||
$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 ($recordset === 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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$recordset = $this->g->query( $this->sql );
|
||||
$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 ($recordset === 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 ($recordset === true) { // return simplified recordset for inserts/updates/deletes with lower overhead
|
||||
$recordset = new ADORecordSet_empty();
|
||||
return $recordset;
|
||||
}
|
||||
|
||||
// $recordset->_fetch(); // unnecessary
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class gladius_driver_ResultSet extends Gladius_Resultset { }
|
||||
|
||||
?>
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
## Gladius Database Engine
|
||||
# @author legolas558
|
||||
# @version 0.3.94
|
||||
# Licensed under GNU General Public License (GPL)
|
||||
#
|
||||
#
|
||||
# adoDB lite extend module
|
||||
#
|
||||
|
||||
eval('class gladius_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class gladius_extend_ADOConnection extends gladius_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)
|
||||
{
|
||||
return false;
|
||||
$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 = gladius_insert_id($this->connectionId);
|
||||
|
||||
if ($result)
|
||||
$result->Close();
|
||||
|
||||
return $this->genID;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
return false;
|
||||
$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 false;
|
||||
return $this->Execute(sprintf($this->_dropSeqSQL, $seqname));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class gladius_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class gladius_extend_ResultSet extends gladius_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="")
|
||||
{
|
||||
return false; // COUNT not yet working
|
||||
$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->current_row;
|
||||
}
|
||||
|
||||
function AbsolutePosition()
|
||||
{
|
||||
return $this->current_row;
|
||||
}
|
||||
|
||||
function NextRecordSet()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,376 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for Gladius
|
||||
*
|
||||
* 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 gladius_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class gladius_meta_ADOConnection extends gladius_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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->metaDatabasesSQL) {
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$arr = $this->GetCol($this->metaDatabasesSQL);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
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($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,$normalize=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
|
||||
if (!empty($this->metaColumnsSQL)) {
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false || $rs->EOF) return $false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) { //print_r($rs->fields);
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
if (isset($rs->fields[3]) && $rs->fields[3]) {
|
||||
if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3];
|
||||
$fld->scale = $rs->fields[4];
|
||||
if ($fld->scale>0) $fld->max_length += 1;
|
||||
} else
|
||||
$fld->max_length = $rs->fields[2];
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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 gladius_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class gladius_meta_ResultSet extends gladius_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;
|
||||
}
|
||||
$is_serial = is_object($fieldobj) && $fieldobj->primary_key && $fieldobj->auto_increment;
|
||||
|
||||
$len = -1; // max_length is not accurate
|
||||
switch (strtolower($t))
|
||||
{
|
||||
case 'varchar':
|
||||
return 'C';
|
||||
case 'text':
|
||||
return 'X';
|
||||
|
||||
// 'B' binary not yet supported in Gladius
|
||||
|
||||
case 'date': return 'D';
|
||||
|
||||
case 'time': return 'T';
|
||||
case 'datetime':
|
||||
return 'DT';
|
||||
case 'timestamp': return 'TS';
|
||||
|
||||
case 'double':
|
||||
return 'F';
|
||||
|
||||
case 'int':
|
||||
return $is_serial ? 'R' : 'I';
|
||||
// default: return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
## Gladius Database Engine
|
||||
# @author legolas558
|
||||
# @version 0.3.94
|
||||
# Licensed under GNU General Public License (GPL)
|
||||
#
|
||||
#
|
||||
# adoDB lite transaction module
|
||||
# transactions are NOT supported
|
||||
#
|
||||
|
||||
eval('class gladius_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class gladius_transaction_ADOConnection extends gladius_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 gladius_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class gladius_transaction_ResultSet extends gladius_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,78 @@
|
|||
<?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_maxdb extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'maxdb';
|
||||
var $seqField = false;
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'VARCHAR(250)';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'VARCHAR(250)';
|
||||
|
||||
case 'B': return 'VARCHAR';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATE';
|
||||
|
||||
case 'L': return 'DECIMAL(1)';
|
||||
case 'I': return 'DECIMAL(10)';
|
||||
case 'I1': return 'DECIMAL(3)';
|
||||
case 'I2': return 'DECIMAL(5)';
|
||||
case 'I4': return 'DECIMAL(10)';
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
|
||||
case 'F': return 'DECIMAL(32,8)';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for MAXDB
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
eval('class maxdb_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class maxdb_date_ADOConnection extends maxdb_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 A'"; /// used by DBTimeStamp as the default timestamp fmt.
|
||||
var $emptyDate = ' ';
|
||||
var $emptyTimeStamp = ' ';
|
||||
var $sysDate = false; /// name of function that returns the current date
|
||||
var $sysTimeStamp = false; /// name of function that returns the current timestamp
|
||||
var $isoDates = false; /// accepts dates in ISO format
|
||||
|
||||
function Time()
|
||||
{
|
||||
$rs =& $this->_Execute("select $this->sysTimeStamp");
|
||||
if ($rs && !$rs->EOF)
|
||||
return $this->UnixTimeStamp(reset($rs->fields));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
|
||||
return '('.$date.'+'.$dayFraction.')';
|
||||
}
|
||||
|
||||
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'";
|
||||
|
||||
$timestamp = $this->UnixTimeStamp($timestamp);
|
||||
return adodb_date($this->fmtTimeStamp, $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]);
|
||||
else 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;
|
||||
else return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col)
|
||||
$col = $this->sysDate;
|
||||
return $col;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class maxdb_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class maxdb_date_ResultSet extends maxdb_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 maxdb_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return maxdb_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,606 @@
|
|||
<?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 maxdb_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
function maxdb_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'maxdb';
|
||||
$this->dataProvider = 'maxdb';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('maxdb_connect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->database = $database;
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
$this->connectionId = @maxdb_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 = @maxdb_select( $this->connectionId, $this->database );
|
||||
|
||||
if($result === false)
|
||||
{
|
||||
if($this->createdatabase == true)
|
||||
{
|
||||
$result = @maxdb_query( "CREATE DATABASE " . $this->database, $this->connectionId );
|
||||
if ($result === false) { // error handling if query fails
|
||||
return false;
|
||||
}
|
||||
$result = @maxdb_select( $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()
|
||||
{
|
||||
return @maxdb_error($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
return @maxdb_errno($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @maxdb_affected_rows($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return @maxdb_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) {
|
||||
$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();
|
||||
return implode("+", $arr);
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " CASE WHEN $field is null THEN $ifNull ELSE $field END ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@maxdb_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 != -1 || $nrows != -1)
|
||||
// {
|
||||
// $offset = ($offset>=0) ? $offset . "," : '';
|
||||
// $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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @maxdb_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);
|
||||
}
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @maxdb_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);
|
||||
}
|
||||
}
|
||||
|
||||
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 = MAXDB_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$recordset->fetchMode = MAXDB_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$recordset->fetchMode = MAXDB_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @maxdb_num_rows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @maxdb_field_count( $resultId );
|
||||
$recordset->_fetch();
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class maxdb_driver_ResultSet
|
||||
{
|
||||
var $connectionId;
|
||||
var $fields;
|
||||
var $resultId;
|
||||
var $_currentRow = 0;
|
||||
var $_numOfRows = -1;
|
||||
var $_numOfFields = -1;
|
||||
var $fetchMode;
|
||||
var $EOF;
|
||||
|
||||
/**
|
||||
* maxdbResultSet Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $record
|
||||
* @param string $resultId
|
||||
*/
|
||||
|
||||
function maxdb_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()
|
||||
{
|
||||
@maxdb_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 = maxdb_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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @maxdb_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)
|
||||
{
|
||||
// $fieldOffset not supported by MaxDB
|
||||
$fieldObject = @maxdb_fetch_field($this->resultId);
|
||||
return $fieldObject;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class maxdb_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class maxdb_extend_ADOConnection extends maxdb_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;
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function DropSequence($seqname='adodbseq')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class maxdb_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class maxdb_extend_ResultSet extends maxdb_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,500 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for MAXdb
|
||||
*
|
||||
* 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 maxdb_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class maxdb_meta_ADOConnection extends maxdb_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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->metaDatabasesSQL) {
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$arr = $this->GetCol($this->metaDatabasesSQL);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
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($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,$normalize=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
|
||||
if (!empty($this->metaColumnsSQL)) {
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false || $rs->EOF) return $false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) { //print_r($rs->fields);
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
if (isset($rs->fields[3]) && $rs->fields[3]) {
|
||||
if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3];
|
||||
$fld->scale = $rs->fields[4];
|
||||
if ($fld->scale>0) $fld->max_length += 1;
|
||||
} else
|
||||
$fld->max_length = $rs->fields[2];
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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 maxdb_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class maxdb_meta_ResultSet extends maxdb_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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for MaxDB
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class maxdb_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class maxdb_transaction_ADOConnection extends maxdb_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 maxdb_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class maxdb_transaction_ResultSet extends maxdb_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,65 @@
|
|||
<?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_msql extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'msql';
|
||||
var $seqField = false;
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'VARCHAR(250)';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'VARCHAR(250)';
|
||||
|
||||
case 'B': return 'VARCHAR';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATE';
|
||||
|
||||
case 'L': return 'DECIMAL(1)';
|
||||
case 'I': return 'DECIMAL(10)';
|
||||
case 'I1': return 'DECIMAL(3)';
|
||||
case 'I2': return 'DECIMAL(5)';
|
||||
case 'I4': return 'DECIMAL(10)';
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
|
||||
case 'F': return 'DECIMAL(32,8)';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for Mini SQL
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
eval('class msql_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class msql_date_ADOConnection extends msql_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 A'"; /// used by DBTimeStamp as the default timestamp fmt.
|
||||
var $emptyDate = ' ';
|
||||
var $emptyTimeStamp = ' ';
|
||||
var $sysDate = false; /// name of function that returns the current date
|
||||
var $sysTimeStamp = false; /// name of function that returns the current timestamp
|
||||
var $isoDates = false; /// accepts dates in ISO format
|
||||
|
||||
function Time()
|
||||
{
|
||||
$rs =& $this->_Execute("select $this->sysTimeStamp");
|
||||
if ($rs && !$rs->EOF)
|
||||
return $this->UnixTimeStamp(reset($rs->fields));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
|
||||
return '('.$date.'+'.$dayFraction.')';
|
||||
}
|
||||
|
||||
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'";
|
||||
|
||||
$timestamp = $this->UnixTimeStamp($timestamp);
|
||||
return adodb_date($this->fmtTimeStamp, $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]);
|
||||
else 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;
|
||||
else return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col)
|
||||
$col = $this->sysDate;
|
||||
return $col;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class msql_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class msql_date_ResultSet extends msql_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 msql_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return msql_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,600 @@
|
|||
<?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 msql_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
function msql_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'msql';
|
||||
$this->dataProvider = 'msql';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('msql_connect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->database = $database;
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
if($this->persistent == 1)
|
||||
{
|
||||
$this->connectionId = msql_pconnect( $this->host );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connectionId = msql_connect( $this->host );
|
||||
}
|
||||
|
||||
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 = @msql_select_db( $this->database, $this->connectionId );
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error message
|
||||
* Usage: $errormessage =& $db->ErrorMsg();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
return @msql_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
return (msql_error()) ? -1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @msql_affected_rows($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
$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();
|
||||
return implode("+", $arr);
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " CASE WHEN $field is null THEN $ifNull ELSE $field END ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@msql_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 != -1 || $nrows != -1)
|
||||
// {
|
||||
// $offset = ($offset>=0) ? $offset . "," : '';
|
||||
// $limit = ' LIMIT ' . $offset . ' ' . $nrows;
|
||||
// }
|
||||
|
||||
if ($inputarr && is_array($inputarr)) {
|
||||
$sqlarr = explode('?', $this->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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @msql_query( $this->sql );
|
||||
$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);
|
||||
}
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @msql_query( $this->sql );
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
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 = MSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$recordset->fetchMode = MSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$recordset->fetchMode = MSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @msql_num_rows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @msql_num_fields( $resultId );
|
||||
$recordset->_fetch();
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class msql_driver_ResultSet
|
||||
{
|
||||
var $connectionId;
|
||||
var $fields;
|
||||
var $resultId;
|
||||
var $_currentRow = 0;
|
||||
var $_numOfRows = -1;
|
||||
var $_numOfFields = -1;
|
||||
var $fetchMode;
|
||||
var $EOF;
|
||||
|
||||
/**
|
||||
* msqlResultSet Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $record
|
||||
* @param string $resultId
|
||||
*/
|
||||
|
||||
function msql_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()
|
||||
{
|
||||
@msql_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 = msql_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 @msql_data_seek($this->resultId,$row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @msql_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 = @msql_fetch_field($this->resultId, $fieldOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$fieldObject = @msql_fetch_field($this->resultId);
|
||||
}
|
||||
return $fieldObject;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class msql_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class msql_extend_ADOConnection extends msql_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;
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function DropSequence($seqname='adodbseq')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class msql_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class msql_extend_ResultSet extends msql_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,499 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for Msql
|
||||
*
|
||||
* 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 msql_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class msql_meta_ADOConnection extends msql_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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->metaDatabasesSQL) {
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$arr = $this->GetCol($this->metaDatabasesSQL);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
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($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,$normalize=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
|
||||
if (!empty($this->metaColumnsSQL)) {
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false || $rs->EOF) return $false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) { //print_r($rs->fields);
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
if (isset($rs->fields[3]) && $rs->fields[3]) {
|
||||
if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3];
|
||||
$fld->scale = $rs->fields[4];
|
||||
if ($fld->scale>0) $fld->max_length += 1;
|
||||
} else
|
||||
$fld->max_length = $rs->fields[2];
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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 msql_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class msql_meta_ResultSet extends msql_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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for Mini Sql
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class msql_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class msql_transaction_ADOConnection extends msql_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 msql_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class msql_transaction_ResultSet extends msql_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,134 @@
|
|||
<?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_mssql extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'mssql';
|
||||
var $dropIndex = 'DROP INDEX %2$s.%1$s';
|
||||
var $renameTable = "EXEC sp_rename '%s','%s'";
|
||||
var $renameColumn = "EXEC sp_rename '%s.%s','%s'";
|
||||
|
||||
var $typeX = 'TEXT'; ## Alternatively, set it to VARCHAR(4000)
|
||||
var $typeXL = 'TEXT';
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch(strtoupper($meta)) {
|
||||
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL': return (isset($this)) ? $this->typeXL : 'TEXT';
|
||||
case 'X': return (isset($this)) ? $this->typeX : 'TEXT'; ## could be varchar(8000), but we want compat with oracle
|
||||
case 'C2': return 'NVARCHAR';
|
||||
case 'X2': return 'NTEXT';
|
||||
|
||||
case 'B': return 'IMAGE';
|
||||
|
||||
case 'D': return 'DATETIME';
|
||||
case 'T': return 'DATETIME';
|
||||
case 'L': return 'BIT';
|
||||
|
||||
case 'R':
|
||||
case 'I': return 'INT';
|
||||
case 'I1': return 'TINYINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INT';
|
||||
case 'I8': return 'BIGINT';
|
||||
|
||||
case 'F': return 'REAL';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
if (!is_array($flds))
|
||||
$flds = explode(',',$flds);
|
||||
$f = array();
|
||||
$s = 'ALTER TABLE ' . $tabname;
|
||||
foreach($flds as $v) {
|
||||
$f[] = "\n$this->dropCol ".$this->NameQuote($v);
|
||||
}
|
||||
$s .= implode(', ',$f);
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function AddColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$f = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$s = "ALTER TABLE $tabname $this->addCol";
|
||||
foreach($lines as $v) {
|
||||
$f[] = "\n $v";
|
||||
}
|
||||
$s .= implode(', ',$f);
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fautoinc) $suffix .= ' IDENTITY(1,1)';
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
else if ($suffix == '') $suffix .= ' 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, $tabname);
|
||||
if ( isset($idxoptions['DROP']) )
|
||||
return $sql;
|
||||
}
|
||||
if ( empty ($flds) ) {
|
||||
return $sql;
|
||||
}
|
||||
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
|
||||
$clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
|
||||
if ( is_array($flds) )
|
||||
$flds = implode(', ',$flds);
|
||||
$s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _GetSize($ftype, $ty, $fsize, $fprec)
|
||||
{
|
||||
switch ($ftype) {
|
||||
case 'INT':
|
||||
case 'SMALLINT':
|
||||
case 'TINYINT':
|
||||
case 'BIGINT':
|
||||
return $ftype;
|
||||
}
|
||||
if ($ty == 'T') return $ftype;
|
||||
return parent::_GetSize($ftype, $ty, $fsize, $fprec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,367 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for Microsoft SQL
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
if (strnatcmp(PHP_VERSION, '4.3.0') >= 0) {
|
||||
ini_set('mssql.datetimeconvert',0);
|
||||
} else {
|
||||
global $ADODB_mssql_mths; // array, months must be upper-case
|
||||
|
||||
$ADODB_mssql_date_order = 'mdy';
|
||||
$ADODB_mssql_mths = array(
|
||||
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
|
||||
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
|
||||
// just after you connect to the database. Supports mdy and dmy only.
|
||||
// Not required for PHP 4.2.0 and above.
|
||||
function AutoDetect_MSSQL_Date_Order($conn)
|
||||
{
|
||||
global $ADODB_mssql_date_order;
|
||||
$adate = $conn->GetOne('select getdate()');
|
||||
if ($adate) {
|
||||
$anum = (int) $adate;
|
||||
if ($anum > 0) {
|
||||
if ($anum > 31) {
|
||||
//ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
|
||||
} else
|
||||
$ADODB_mssql_date_order = 'dmy';
|
||||
} else
|
||||
$ADODB_mssql_date_order = 'mdy';
|
||||
}
|
||||
}
|
||||
|
||||
eval('class mssql_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mssql_date_ADOConnection extends mssql_date_EXTENDER
|
||||
{
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
var $emptyDate = ' ';
|
||||
var $emptyTimeStamp = ' ';
|
||||
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
|
||||
var $sysTimeStamp = 'GetDate()';
|
||||
var $isoDates = false; /// accepts dates in ISO format
|
||||
|
||||
function Time()
|
||||
{
|
||||
$rs =& $this->_Execute("select $this->sysTimeStamp");
|
||||
if ($rs && !$rs->EOF)
|
||||
return $this->UnixTimeStamp(reset($rs->fields));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
|
||||
return '('.$date.'+'.$dayFraction.')';
|
||||
}
|
||||
|
||||
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'";
|
||||
|
||||
$timestamp = $this->UnixTimeStamp($timestamp);
|
||||
return adodb_date($this->fmtTimeStamp, $timestamp);
|
||||
}
|
||||
|
||||
function UnixDate($v)
|
||||
{
|
||||
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
|
||||
|
||||
if (is_numeric(substr($v,0,1)) && strnatcmp(PHP_VERSION, '4.2.0') >= 0)
|
||||
return $v;
|
||||
|
||||
//Dec 30 2000 12:00AM
|
||||
if ($ADODB_mssql_date_order == 'dmy') {
|
||||
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
|
||||
return $v;
|
||||
}
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
$theday = $rr[1];
|
||||
$themth = substr(strtoupper($rr[2]), 0, 3);
|
||||
} else {
|
||||
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
|
||||
return $v;
|
||||
}
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
$theday = $rr[2];
|
||||
$themth = substr(strtoupper($rr[1]), 0, 3);
|
||||
}
|
||||
$themth = $ADODB_mssql_mths[$themth];
|
||||
if ($themth <= 0)
|
||||
return false;
|
||||
|
||||
// h-m-s-MM-DD-YY
|
||||
return mktime(0, 0, 0, $themth, $theday, $rr[3]);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
|
||||
|
||||
if (is_numeric(substr($v,0,1)) && strnatcmp(PHP_VERSION, '4.2.0') >= 0)
|
||||
return $v;
|
||||
|
||||
//Dec 30 2000 12:00AM
|
||||
if ($ADODB_mssql_date_order == 'dmy') {
|
||||
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|",$v , $rr))
|
||||
return $v;
|
||||
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
$theday = $rr[1];
|
||||
$themth = substr(strtoupper($rr[2]), 0, 3);
|
||||
} else {
|
||||
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|",$v , $rr))
|
||||
return $v;
|
||||
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
$theday = $rr[2];
|
||||
$themth = substr(strtoupper($rr[1]), 0, 3);
|
||||
}
|
||||
|
||||
$themth = $ADODB_mssql_mths[$themth];
|
||||
if ($themth <= 0)
|
||||
return false;
|
||||
|
||||
switch (strtoupper($rr[6])) {
|
||||
case 'P':
|
||||
if ($rr[4]<12)
|
||||
$rr[4] += 12;
|
||||
break;
|
||||
case 'A':
|
||||
if ($rr[4]==12)
|
||||
$rr[4] = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// h-m-s-MM-DD-YY
|
||||
return mktime($rr[4], $rr[5], 0, $themth, $theday, $rr[3]);
|
||||
}
|
||||
|
||||
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;
|
||||
else return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysTimeStamp;
|
||||
$s = '';
|
||||
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
if ($s) $s .= '+';
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= "datename(yyyy,$col)";
|
||||
break;
|
||||
case 'M':
|
||||
$s .= "convert(char(3),$col,0)";
|
||||
break;
|
||||
case 'm':
|
||||
$s .= "replace(str(month($col),2),' ','0')";
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "datename(quarter,$col)";
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= "replace(str(day($col),2),' ','0')";
|
||||
break;
|
||||
case 'h':
|
||||
$s .= "substring(convert(char(14),$col,0),13,2)";
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
|
||||
break;
|
||||
case 's':
|
||||
$s .= "replace(str(datepart(ss,$col),2),' ','0')";
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= "substring(convert(char(19),$col,0),18,2)";
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
$s .= $this->qstr($ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
eval('class mssql_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mssql_date_ResultSet extends mssql_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 mssql_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return mssql_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,686 @@
|
|||
<?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 mssql_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
|
||||
var $sysTimeStamp = 'GetDate()';
|
||||
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
|
||||
|
||||
function mssql_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'mssql';
|
||||
$this->dataProvider = 'mssql';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('mssql_pconnect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->database = $database;
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
if($this->persistent == 1)
|
||||
{
|
||||
$this->connectionId = @mssql_pconnect( $this->host, $this->username, $this->password );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connectionId = @mssql_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 = @mssql_select_db( $this->database, $this->connectionId );
|
||||
|
||||
if($result === false)
|
||||
{
|
||||
if($this->createdatabase == true)
|
||||
{
|
||||
$result = @mssql_query( "CREATE DATABASE " . $this->database, $this->connectionId );
|
||||
if ($result === false) { // error handling if query fails
|
||||
return false;
|
||||
}
|
||||
$result = @mssql_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()
|
||||
{
|
||||
return @mssql_get_last_message();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
$result = @mssql_query("select @@ERROR",$this->connectionId);
|
||||
if (!$result) return false;
|
||||
$array = mssql_fetch_array($result);
|
||||
@mssql_free_result($result);
|
||||
if (is_array($array)) return $array[0];
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @mssql_rows_affected($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
$data = false;
|
||||
$result =& $this->do_query('select @@IDENTITY', -1, -1);
|
||||
if ($result) {
|
||||
if (!$result->EOF)
|
||||
$data = reset($result->fields);
|
||||
$result->Close();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
return "'".str_replace("'", "''", $string)."'";
|
||||
}
|
||||
$string = str_replace("\\'", "''", str_replace('\\\\', '\\', str_replace('\\"', '"', $string)));
|
||||
return "'" . $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()
|
||||
{
|
||||
$s = "";
|
||||
$arr = func_get_args();
|
||||
|
||||
if (sizeof($arr) == 1) {
|
||||
foreach ($arr as $arg) {
|
||||
$args = explode(',', $arg);
|
||||
}
|
||||
$arr = $args;
|
||||
}
|
||||
|
||||
array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
|
||||
$s = implode('+',$arr);
|
||||
if (sizeof($arr) > 0) return "$s";
|
||||
return '';
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " ISNULL($field, $ifNull) ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@mssql_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;
|
||||
|
||||
if ($nrows > 0 && $offset <= 0) {
|
||||
$sql = preg_replace('/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 ' . $this->hasTop . " $nrows ", $sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->hasTop && $nrows > 0) {
|
||||
$total_rows = $nrows + $offset;
|
||||
$sql = preg_replace('/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 ' . $this->hasTop . ' ' . $total_rows . ' ', $sql);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @mssql_query( $this->sql );
|
||||
$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);
|
||||
}
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @mssql_query( $this->sql );
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
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 = MSSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$recordset->fetchMode = MSSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$recordset->fetchMode = MSSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @mssql_num_rows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @mssql_num_fields( $resultId );
|
||||
|
||||
if ($offset != -1 || $nrows != -1)
|
||||
{
|
||||
if($offset == -1 || ($offset == 0 && $nrows != -1))
|
||||
{
|
||||
$recordset->_numOfRows = ($nrows < $recordset->_numOfRows) ? $nrows : $recordset->_numOfRows;
|
||||
$recordset->_fetch();
|
||||
}
|
||||
else
|
||||
{
|
||||
if($offset > $recordset->_numOfRows)
|
||||
{
|
||||
$rs =& new ADORecordSet_empty();
|
||||
return $rs;
|
||||
}
|
||||
|
||||
$recordset->_fetch();
|
||||
$recordset->Move($offset);
|
||||
|
||||
$recordset->_currentRow = 0;
|
||||
if($nrows != -1)
|
||||
{
|
||||
$recordset->_numOfRows = ($nrows < ($recordset->_numOfRows - $offset)) ? $nrows : $recordset->_numOfRows - $offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
$recordset->_numOfRows -= $offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$recordset->_fetch();
|
||||
}
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class mssql_driver_ResultSet
|
||||
{
|
||||
var $connectionId;
|
||||
var $fields;
|
||||
var $resultId;
|
||||
var $_currentRow = 0;
|
||||
var $_numOfRows = -1;
|
||||
var $_numOfFields = -1;
|
||||
var $fetchMode;
|
||||
var $EOF;
|
||||
|
||||
/**
|
||||
* mssqlResultSet Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $record
|
||||
* @param string $resultId
|
||||
*/
|
||||
|
||||
function mssql_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()
|
||||
{
|
||||
@mssql_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 = mssql_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 @mssql_data_seek($this->resultId,$row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @mssql_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 = @mssql_fetch_field($this->resultId, $fieldOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$fieldObject = @mssql_fetch_field($this->resultId);
|
||||
}
|
||||
$false = false;
|
||||
if (empty($fieldObject)) return $false;
|
||||
return $fieldObject;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mssql_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mssql_extend_ADOConnection extends mssql_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;
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
$this->Execute('BEGIN TRANSACTION adodbseq');
|
||||
$result = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
|
||||
if (!$result) {
|
||||
$this->Execute("create table $seq (id float(53))");
|
||||
$result = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
|
||||
if (!$result) {
|
||||
$this->Execute('ROLLBACK TRANSACTION adodbseq');
|
||||
return false;
|
||||
}
|
||||
$this->Execute('COMMIT TRANSACTION adodbseq');
|
||||
return $start;
|
||||
}
|
||||
$num = $this->GetOne("select id from $seq");
|
||||
$this->Execute('COMMIT TRANSACTION adodbseq');
|
||||
return $num;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function DropSequence($seqname='adodbseq')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class mssql_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mssql_extend_ResultSet extends mssql_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()
|
||||
{
|
||||
if (!mssql_next_result($this->resultId)) return false;
|
||||
$this->_inited = false;
|
||||
$this->bind = false;
|
||||
$this->_currentRow = -1;
|
||||
$this->_numOfRows = @mssql_num_rows($this->resultId);
|
||||
$this->_numOfFields = @mssql_num_fields($this->resultId);
|
||||
if ($this->_numOfRows != 0 && $this->_numOfFields) {
|
||||
$this->_currentRow = 0;
|
||||
$this->_fetch();
|
||||
} else {
|
||||
$this->EOF = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,604 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for Mssql
|
||||
*
|
||||
* 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 mssql_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mssql_meta_ADOConnection extends mssql_meta_EXTENDER
|
||||
{
|
||||
var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
|
||||
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
|
||||
var $metaColumnsSQL = # xtype==61 is datetime
|
||||
"select c.name,t.name,c.length,
|
||||
(case when c.xusertype=61 then 0 else c.xprec end),
|
||||
(case when c.xusertype=61 then 0 else c.xscale end)
|
||||
from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%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)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = '';
|
||||
$this->_findschema($table,$schema);
|
||||
if (!$schema) $schema = $this->database;
|
||||
if ($schema) $schema = "and k.table_catalog like '$schema%'";
|
||||
|
||||
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
|
||||
information_schema.table_constraints tc
|
||||
where tc.constraint_name = k.constraint_name and tc.constraint_type =
|
||||
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$a = $this->GetCol($sql);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if ($a && sizeof($a)>0) return $a;
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns assoc array where keys are tables, and values are foreign keys
|
||||
*/
|
||||
function MetaForeignKeys($table, $owner=false, $upper=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$table = $this->qstr(strtoupper($table));
|
||||
|
||||
$sql =
|
||||
"select object_name(constid) as constraint_name,
|
||||
col_name(fkeyid, fkey) as column_name,
|
||||
object_name(rkeyid) as referenced_table_name,
|
||||
col_name(rkeyid, rkey) as referenced_column_name
|
||||
from sysforeignkeys
|
||||
where upper(object_name(fkeyid)) = $table
|
||||
order by constraint_name, referenced_table_name, keyno";
|
||||
|
||||
$constraints =& $this->GetArray($sql);
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
$arr = false;
|
||||
foreach($constraints as $constr) {
|
||||
//print_r($constr);
|
||||
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
|
||||
}
|
||||
if (!$arr) return false;
|
||||
|
||||
$arr2 = false;
|
||||
|
||||
foreach($arr as $k => $v) {
|
||||
foreach($v as $a => $b) {
|
||||
if ($upper) $a = strtoupper($a);
|
||||
$arr2[$a] = $b;
|
||||
}
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
if(@mssql_select_db("master")) {
|
||||
$qry=$this->metaDatabasesSQL;
|
||||
if($rs=@mssql_query($qry,$this->_connectionID)){
|
||||
$tmpAr=$ar=array();
|
||||
while($tmpAr=@mssql_fetch_row($rs))
|
||||
$ar[]=$tmpAr[0];
|
||||
@mssql_select_db($this->database);
|
||||
if(sizeof($ar))
|
||||
return($ar);
|
||||
else
|
||||
return(false);
|
||||
} else {
|
||||
@mssql_select_db($this->database);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
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($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
if ($mask) {
|
||||
$save = $this->metaTablesSQL;
|
||||
$mask = $this->qstr(($mask));
|
||||
$this->metaTablesSQL .= " AND name like $mask";
|
||||
}
|
||||
$ret =& $this->_MetaTables($ttype,$showSchema);
|
||||
|
||||
if ($mask) {
|
||||
$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,$normalize=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
|
||||
if (!empty($this->metaColumnsSQL)) {
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false || $rs->EOF) return $false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) { //print_r($rs->fields);
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
if (isset($rs->fields[3]) && $rs->fields[3]) {
|
||||
if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3];
|
||||
$fld->scale = $rs->fields[4];
|
||||
if ($fld->scale>0) $fld->max_length += 1;
|
||||
} else
|
||||
$fld->max_length = $rs->fields[2];
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$table = $this->qstr($table);
|
||||
|
||||
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
|
||||
CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
|
||||
CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
|
||||
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
|
||||
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
|
||||
INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
|
||||
WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
|
||||
ORDER BY O.name, I.Name, K.keyno";
|
||||
|
||||
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($sql);
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!is_object($rs)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$indexes = array();
|
||||
while ($row = $rs->FetchRow()) {
|
||||
if (!$primary && $row[5]) continue;
|
||||
|
||||
$indexes[$row[0]]['unique'] = $row[6];
|
||||
$indexes[$row[0]]['columns'][] = $row[1];
|
||||
}
|
||||
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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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 mssql_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mssql_meta_ResultSet extends mssql_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 'R':
|
||||
case 'INT':
|
||||
case 'INTEGER': return 'I';
|
||||
|
||||
case 'BIT':
|
||||
case 'TINYINT': return 'I1';
|
||||
|
||||
case 'SMALLINT': return 'I2';
|
||||
|
||||
case 'BIGINT': return 'I8';
|
||||
|
||||
case 'REAL':
|
||||
case 'FLOAT': return 'F';
|
||||
|
||||
case 'MEDIUMINT':
|
||||
|
||||
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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for MS Sql
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mssql_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mssql_transaction_ADOConnection extends mssql_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()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt += 1;
|
||||
$this->Execute('BEGIN TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
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->RollbackTrans();
|
||||
if ($this->debug)
|
||||
ADOCOnnection::outp("Smart Rollback occurred");
|
||||
}
|
||||
return $this->transaction_status;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if (!$ok)
|
||||
return $this->RollbackTrans();
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->Execute('COMMIT TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->Execute('ROLLBACK TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
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($tables,$where)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function CommitLock($table)
|
||||
{
|
||||
return $this->CommitTrans();
|
||||
}
|
||||
|
||||
function RollbackLock($table)
|
||||
{
|
||||
return $this->RollbackTrans();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class mssql_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mssql_transaction_ResultSet extends mssql_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,134 @@
|
|||
<?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_mssqlpo extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'mssqlpo';
|
||||
var $dropIndex = 'DROP INDEX %2$s.%1$s';
|
||||
var $renameTable = "EXEC sp_rename '%s','%s'";
|
||||
var $renameColumn = "EXEC sp_rename '%s.%s','%s'";
|
||||
|
||||
var $typeX = 'TEXT'; ## Alternatively, set it to VARCHAR(4000)
|
||||
var $typeXL = 'TEXT';
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch(strtoupper($meta)) {
|
||||
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL': return (isset($this)) ? $this->typeXL : 'TEXT';
|
||||
case 'X': return (isset($this)) ? $this->typeX : 'TEXT'; ## could be varchar(8000), but we want compat with oracle
|
||||
case 'C2': return 'NVARCHAR';
|
||||
case 'X2': return 'NTEXT';
|
||||
|
||||
case 'B': return 'IMAGE';
|
||||
|
||||
case 'D': return 'DATETIME';
|
||||
case 'T': return 'DATETIME';
|
||||
case 'L': return 'BIT';
|
||||
|
||||
case 'R':
|
||||
case 'I': return 'INT';
|
||||
case 'I1': return 'TINYINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INT';
|
||||
case 'I8': return 'BIGINT';
|
||||
|
||||
case 'F': return 'REAL';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
if (!is_array($flds))
|
||||
$flds = explode(',',$flds);
|
||||
$f = array();
|
||||
$s = 'ALTER TABLE ' . $tabname;
|
||||
foreach($flds as $v) {
|
||||
$f[] = "\n$this->dropCol ".$this->NameQuote($v);
|
||||
}
|
||||
$s .= implode(', ',$f);
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function AddColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$f = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$s = "ALTER TABLE $tabname $this->addCol";
|
||||
foreach($lines as $v) {
|
||||
$f[] = "\n $v";
|
||||
}
|
||||
$s .= implode(', ',$f);
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fautoinc) $suffix .= ' IDENTITY(1,1)';
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
else if ($suffix == '') $suffix .= ' 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, $tabname);
|
||||
if ( isset($idxoptions['DROP']) )
|
||||
return $sql;
|
||||
}
|
||||
if ( empty ($flds) ) {
|
||||
return $sql;
|
||||
}
|
||||
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
|
||||
$clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
|
||||
if ( is_array($flds) )
|
||||
$flds = implode(', ',$flds);
|
||||
$s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _GetSize($ftype, $ty, $fsize, $fprec)
|
||||
{
|
||||
switch ($ftype) {
|
||||
case 'INT':
|
||||
case 'SMALLINT':
|
||||
case 'TINYINT':
|
||||
case 'BIGINT':
|
||||
return $ftype;
|
||||
}
|
||||
if ($ty == 'T') return $ftype;
|
||||
return parent::_GetSize($ftype, $ty, $fsize, $fprec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,367 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for Microsoft SQL Pro
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
if (strnatcmp(PHP_VERSION, '4.3.0') >= 0) {
|
||||
ini_set('mssql.datetimeconvert',0);
|
||||
} else {
|
||||
global $ADODB_mssql_mths; // array, months must be upper-case
|
||||
|
||||
$ADODB_mssql_date_order = 'mdy';
|
||||
$ADODB_mssql_mths = array(
|
||||
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
|
||||
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
|
||||
// just after you connect to the database. Supports mdy and dmy only.
|
||||
// Not required for PHP 4.2.0 and above.
|
||||
function AutoDetect_MSSQL_Date_Order($conn)
|
||||
{
|
||||
global $ADODB_mssql_date_order;
|
||||
$adate = $conn->GetOne('select getdate()');
|
||||
if ($adate) {
|
||||
$anum = (int) $adate;
|
||||
if ($anum > 0) {
|
||||
if ($anum > 31) {
|
||||
//ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
|
||||
} else
|
||||
$ADODB_mssql_date_order = 'dmy';
|
||||
} else
|
||||
$ADODB_mssql_date_order = 'mdy';
|
||||
}
|
||||
}
|
||||
|
||||
eval('class mssqlpo_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mssqlpo_date_ADOConnection extends mssqlpo_date_EXTENDER
|
||||
{
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
var $emptyDate = ' ';
|
||||
var $emptyTimeStamp = ' ';
|
||||
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
|
||||
var $sysTimeStamp = 'GetDate()';
|
||||
var $isoDates = false; /// accepts dates in ISO format
|
||||
|
||||
function Time()
|
||||
{
|
||||
$rs =& $this->_Execute("select $this->sysTimeStamp");
|
||||
if ($rs && !$rs->EOF)
|
||||
return $this->UnixTimeStamp(reset($rs->fields));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
|
||||
return '('.$date.'+'.$dayFraction.')';
|
||||
}
|
||||
|
||||
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'";
|
||||
|
||||
$timestamp = $this->UnixTimeStamp($timestamp);
|
||||
return adodb_date($this->fmtTimeStamp, $timestamp);
|
||||
}
|
||||
|
||||
function UnixDate($v)
|
||||
{
|
||||
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
|
||||
|
||||
if (is_numeric(substr($v,0,1)) && strnatcmp(PHP_VERSION, '4.2.0') >= 0)
|
||||
return $v;
|
||||
|
||||
//Dec 30 2000 12:00AM
|
||||
if ($ADODB_mssql_date_order == 'dmy') {
|
||||
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
|
||||
return $v;
|
||||
}
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
$theday = $rr[1];
|
||||
$themth = substr(strtoupper($rr[2]), 0, 3);
|
||||
} else {
|
||||
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
|
||||
return $v;
|
||||
}
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
$theday = $rr[2];
|
||||
$themth = substr(strtoupper($rr[1]), 0, 3);
|
||||
}
|
||||
$themth = $ADODB_mssql_mths[$themth];
|
||||
if ($themth <= 0)
|
||||
return false;
|
||||
|
||||
// h-m-s-MM-DD-YY
|
||||
return mktime(0, 0, 0, $themth, $theday, $rr[3]);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
|
||||
|
||||
if (is_numeric(substr($v,0,1)) && strnatcmp(PHP_VERSION, '4.2.0') >= 0)
|
||||
return $v;
|
||||
|
||||
//Dec 30 2000 12:00AM
|
||||
if ($ADODB_mssql_date_order == 'dmy') {
|
||||
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|",$v , $rr))
|
||||
return $v;
|
||||
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
$theday = $rr[1];
|
||||
$themth = substr(strtoupper($rr[2]), 0, 3);
|
||||
} else {
|
||||
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|",$v , $rr))
|
||||
return $v;
|
||||
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR)
|
||||
return 0;
|
||||
|
||||
$theday = $rr[2];
|
||||
$themth = substr(strtoupper($rr[1]), 0, 3);
|
||||
}
|
||||
|
||||
$themth = $ADODB_mssql_mths[$themth];
|
||||
if ($themth <= 0)
|
||||
return false;
|
||||
|
||||
switch (strtoupper($rr[6])) {
|
||||
case 'P':
|
||||
if ($rr[4]<12)
|
||||
$rr[4] += 12;
|
||||
break;
|
||||
case 'A':
|
||||
if ($rr[4]==12)
|
||||
$rr[4] = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// h-m-s-MM-DD-YY
|
||||
return mktime($rr[4], $rr[5], 0, $themth, $theday, $rr[3]);
|
||||
}
|
||||
|
||||
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;
|
||||
else return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysTimeStamp;
|
||||
$s = '';
|
||||
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
if ($s) $s .= '+';
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= "datename(yyyy,$col)";
|
||||
break;
|
||||
case 'M':
|
||||
$s .= "convert(char(3),$col,0)";
|
||||
break;
|
||||
case 'm':
|
||||
$s .= "replace(str(month($col),2),' ','0')";
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "datename(quarter,$col)";
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= "replace(str(day($col),2),' ','0')";
|
||||
break;
|
||||
case 'h':
|
||||
$s .= "substring(convert(char(14),$col,0),13,2)";
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
|
||||
break;
|
||||
case 's':
|
||||
$s .= "replace(str(datepart(ss,$col),2),' ','0')";
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= "substring(convert(char(19),$col,0),18,2)";
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
$s .= $this->qstr($ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
eval('class mssqlpo_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mssqlpo_date_ResultSet extends mssqlpo_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 mssqlpo_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return mssqlpo_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,685 @@
|
|||
<?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 mssqlpo_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
|
||||
var $sysTimeStamp = 'GetDate()';
|
||||
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
|
||||
|
||||
function mssqlpo_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'mssqlpo';
|
||||
$this->dataProvider = 'mssql';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('mssql_pconnect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->database = $database;
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
if($this->persistent == 1)
|
||||
{
|
||||
$this->connectionId = @mssql_pconnect( $this->host, $this->username, $this->password );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connectionId = @mssql_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 = @mssql_select_db( $this->database, $this->connectionId );
|
||||
|
||||
if($result === false)
|
||||
{
|
||||
if($this->createdatabase == true)
|
||||
{
|
||||
$result = @mssql_query( "CREATE DATABASE " . $this->database, $this->connectionId );
|
||||
if ($result === false) { // error handling if query fails
|
||||
return false;
|
||||
}
|
||||
$result = @mssql_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()
|
||||
{
|
||||
return @mssql_get_last_message();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
$result = @mssql_query("select @@ERROR",$this->connectionId);
|
||||
if (!$result) return false;
|
||||
$array = mssql_fetch_array($result);
|
||||
@mssql_free_result($result);
|
||||
if (is_array($array)) return $array[0];
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @mssql_rows_affected($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
$data = false;
|
||||
$result =& $this->do_query('select @@IDENTITY', -1, -1);
|
||||
if ($result) {
|
||||
if (!$result->EOF)
|
||||
$data = reset($result->fields);
|
||||
$result->Close();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
return "'".str_replace("'", "''", $string)."'";
|
||||
}
|
||||
$string = str_replace("\\'", "''", str_replace('\\\\', '\\', str_replace('\\"', '"', $string)));
|
||||
return "'" . $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()
|
||||
{
|
||||
$s = "";
|
||||
$arr = func_get_args();
|
||||
|
||||
if (sizeof($arr) == 1) {
|
||||
foreach ($arr as $arg) {
|
||||
$args = explode(',', $arg);
|
||||
}
|
||||
$arr = $args;
|
||||
}
|
||||
|
||||
array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
|
||||
$s = implode('+',$arr);
|
||||
if (sizeof($arr) > 0) return "$s";
|
||||
return '';
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " ISNULL($field, $ifNull) ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@mssql_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;
|
||||
|
||||
if ($nrows > 0 && $offset <= 0) {
|
||||
$sql = preg_replace('/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 ' . $this->hasTop . " $nrows ", $sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->hasTop && $nrows > 0) {
|
||||
$total_rows = $nrows + $offset;
|
||||
$sql = preg_replace('/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 ' . $this->hasTop . ' ' . $total_rows . ' ', $sql);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @mssql_query( $this->sql );
|
||||
$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);
|
||||
}
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @mssql_query( $this->sql );
|
||||
$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($this->sql);
|
||||
}
|
||||
}
|
||||
|
||||
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 = MSSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$recordset->fetchMode = MSSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$recordset->fetchMode = MSSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @mssql_num_rows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @mssql_num_fields( $resultId );
|
||||
|
||||
if ($offset != -1 || $nrows != -1)
|
||||
{
|
||||
if($offset == -1 || ($offset == 0 && $nrows != -1))
|
||||
{
|
||||
$recordset->_numOfRows = ($nrows < $recordset->_numOfRows) ? $nrows : $recordset->_numOfRows;
|
||||
$recordset->_fetch();
|
||||
}
|
||||
else
|
||||
{
|
||||
if($offset > $recordset->_numOfRows)
|
||||
{
|
||||
$rs =& new ADORecordSet_empty();
|
||||
return $rs;
|
||||
}
|
||||
|
||||
$recordset->_fetch();
|
||||
$recordset->Move($offset);
|
||||
|
||||
$recordset->_currentRow = 0;
|
||||
if($nrows != -1)
|
||||
{
|
||||
$recordset->_numOfRows = ($nrows < ($recordset->_numOfRows - $offset)) ? $nrows : $recordset->_numOfRows - $offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
$recordset->_numOfRows -= $offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$recordset->_fetch();
|
||||
}
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class mssqlpo_driver_ResultSet
|
||||
{
|
||||
var $connectionId;
|
||||
var $fields;
|
||||
var $resultId;
|
||||
var $_currentRow = 0;
|
||||
var $_numOfRows = -1;
|
||||
var $_numOfFields = -1;
|
||||
var $fetchMode;
|
||||
var $EOF;
|
||||
|
||||
/**
|
||||
* mssqlResultSet Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $record
|
||||
* @param string $resultId
|
||||
*/
|
||||
|
||||
function mssqlpo_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()
|
||||
{
|
||||
@mssql_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 = mssql_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 @mssql_data_seek($this->resultId,$row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @mssql_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 = @mssql_fetch_field($this->resultId, $fieldOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$fieldObject = @mssql_fetch_field($this->resultId);
|
||||
}
|
||||
$false = false;
|
||||
if (empty($fieldObject)) return $false;
|
||||
return $fieldObject;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mssqlpo_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mssqlpo_extend_ADOConnection extends mssqlpo_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;
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
$this->Execute('BEGIN TRANSACTION adodbseq');
|
||||
$result = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
|
||||
if (!$result) {
|
||||
$this->Execute("create table $seq (id float(53))");
|
||||
$result = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
|
||||
if (!$result) {
|
||||
$this->Execute('ROLLBACK TRANSACTION adodbseq');
|
||||
return false;
|
||||
}
|
||||
$this->Execute('COMMIT TRANSACTION adodbseq');
|
||||
return $start;
|
||||
}
|
||||
$num = $this->GetOne("select id from $seq");
|
||||
$this->Execute('COMMIT TRANSACTION adodbseq');
|
||||
return $num;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function DropSequence($seqname='adodbseq')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class mssqlpo_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mssqlpo_extend_ResultSet extends mssqlpo_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()
|
||||
{
|
||||
if (!mssql_next_result($this->resultId)) return false;
|
||||
$this->_inited = false;
|
||||
$this->bind = false;
|
||||
$this->_currentRow = -1;
|
||||
$this->_numOfRows = @mssql_num_rows($this->resultId);
|
||||
$this->_numOfFields = @mssql_num_fields($this->resultId);
|
||||
if ($this->_numOfRows != 0 && $this->_numOfFields) {
|
||||
$this->_currentRow = 0;
|
||||
$this->_fetch();
|
||||
} else {
|
||||
$this->EOF = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,604 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for Mssqlpo
|
||||
*
|
||||
* 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 mssqlpo_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mssqlpo_meta_ADOConnection extends mssqlpo_meta_EXTENDER
|
||||
{
|
||||
var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
|
||||
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
|
||||
var $metaColumnsSQL = # xtype==61 is datetime
|
||||
"select c.name,t.name,c.length,
|
||||
(case when c.xusertype=61 then 0 else c.xprec end),
|
||||
(case when c.xusertype=61 then 0 else c.xscale end)
|
||||
from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%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)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = '';
|
||||
$this->_findschema($table,$schema);
|
||||
if (!$schema) $schema = $this->database;
|
||||
if ($schema) $schema = "and k.table_catalog like '$schema%'";
|
||||
|
||||
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
|
||||
information_schema.table_constraints tc
|
||||
where tc.constraint_name = k.constraint_name and tc.constraint_type =
|
||||
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$a = $this->GetCol($sql);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if ($a && sizeof($a)>0) return $a;
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns assoc array where keys are tables, and values are foreign keys
|
||||
*/
|
||||
function MetaForeignKeys($table, $owner=false, $upper=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$table = $this->qstr(strtoupper($table));
|
||||
|
||||
$sql =
|
||||
"select object_name(constid) as constraint_name,
|
||||
col_name(fkeyid, fkey) as column_name,
|
||||
object_name(rkeyid) as referenced_table_name,
|
||||
col_name(rkeyid, rkey) as referenced_column_name
|
||||
from sysforeignkeys
|
||||
where upper(object_name(fkeyid)) = $table
|
||||
order by constraint_name, referenced_table_name, keyno";
|
||||
|
||||
$constraints =& $this->GetArray($sql);
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
$arr = false;
|
||||
foreach($constraints as $constr) {
|
||||
//print_r($constr);
|
||||
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
|
||||
}
|
||||
if (!$arr) return false;
|
||||
|
||||
$arr2 = false;
|
||||
|
||||
foreach($arr as $k => $v) {
|
||||
foreach($v as $a => $b) {
|
||||
if ($upper) $a = strtoupper($a);
|
||||
$arr2[$a] = $b;
|
||||
}
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
if(@mssql_select_db("master")) {
|
||||
$qry=$this->metaDatabasesSQL;
|
||||
if($rs=@mssql_query($qry,$this->_connectionID)){
|
||||
$tmpAr=$ar=array();
|
||||
while($tmpAr=@mssql_fetch_row($rs))
|
||||
$ar[]=$tmpAr[0];
|
||||
@mssql_select_db($this->database);
|
||||
if(sizeof($ar))
|
||||
return($ar);
|
||||
else
|
||||
return(false);
|
||||
} else {
|
||||
@mssql_select_db($this->database);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
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($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
if ($mask) {
|
||||
$save = $this->metaTablesSQL;
|
||||
$mask = $this->qstr(($mask));
|
||||
$this->metaTablesSQL .= " AND name like $mask";
|
||||
}
|
||||
$ret =& $this->_MetaTables($ttype,$showSchema);
|
||||
|
||||
if ($mask) {
|
||||
$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,$normalize=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
|
||||
if (!empty($this->metaColumnsSQL)) {
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false || $rs->EOF) return $false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) { //print_r($rs->fields);
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
if (isset($rs->fields[3]) && $rs->fields[3]) {
|
||||
if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3];
|
||||
$fld->scale = $rs->fields[4];
|
||||
if ($fld->scale>0) $fld->max_length += 1;
|
||||
} else
|
||||
$fld->max_length = $rs->fields[2];
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$table = $this->qstr($table);
|
||||
|
||||
$sql = "SELECT i.name AS ind_name, C.name AS col_name, USER_NAME(O.uid) AS Owner, c.colid, k.Keyno,
|
||||
CASE WHEN I.indid BETWEEN 1 AND 254 AND (I.status & 2048 = 2048 OR I.Status = 16402 AND O.XType = 'V') THEN 1 ELSE 0 END AS IsPK,
|
||||
CASE WHEN I.status & 2 = 2 THEN 1 ELSE 0 END AS IsUnique
|
||||
FROM dbo.sysobjects o INNER JOIN dbo.sysindexes I ON o.id = i.id
|
||||
INNER JOIN dbo.sysindexkeys K ON I.id = K.id AND I.Indid = K.Indid
|
||||
INNER JOIN dbo.syscolumns c ON K.id = C.id AND K.colid = C.Colid
|
||||
WHERE LEFT(i.name, 8) <> '_WA_Sys_' AND o.status >= 0 AND O.Name LIKE $table
|
||||
ORDER BY O.name, I.Name, K.keyno";
|
||||
|
||||
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($sql);
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!is_object($rs)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$indexes = array();
|
||||
while ($row = $rs->FetchRow()) {
|
||||
if (!$primary && $row[5]) continue;
|
||||
|
||||
$indexes[$row[0]]['unique'] = $row[6];
|
||||
$indexes[$row[0]]['columns'][] = $row[1];
|
||||
}
|
||||
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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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 mssqlpo_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mssqlpo_meta_ResultSet extends mssqlpo_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 'R':
|
||||
case 'INT':
|
||||
case 'INTEGER': return 'I';
|
||||
|
||||
case 'BIT':
|
||||
case 'TINYINT': return 'I1';
|
||||
|
||||
case 'SMALLINT': return 'I2';
|
||||
|
||||
case 'BIGINT': return 'I8';
|
||||
|
||||
case 'REAL':
|
||||
case 'FLOAT': return 'F';
|
||||
|
||||
case 'MEDIUMINT':
|
||||
|
||||
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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for MS Sql
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mssqlpo_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mssqlpo_transaction_ADOConnection extends mssqlpo_transaction_EXTENDER
|
||||
{
|
||||
var $autoCommit = true;
|
||||
var $transOff = 0;
|
||||
var $transCnt = 0;
|
||||
var $transaction_status = true;
|
||||
|
||||
function transaction_ADOConnection( $dbtype )
|
||||
{
|
||||
$this->dbtype = strtolower( $dbtype );
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt += 1;
|
||||
$this->Execute('BEGIN TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
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->RollbackTrans();
|
||||
if ($this->debug)
|
||||
ADOCOnnection::outp("Smart Rollback occurred");
|
||||
}
|
||||
return $this->transaction_status;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if (!$ok)
|
||||
return $this->RollbackTrans();
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->Execute('COMMIT TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->Execute('ROLLBACK TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
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($tables,$where)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function CommitLock($table)
|
||||
{
|
||||
return $this->CommitTrans();
|
||||
}
|
||||
|
||||
function RollbackLock($table)
|
||||
{
|
||||
return $this->RollbackTrans();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class mssqlpo_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mssqlpo_transaction_ResultSet extends mssqlpo_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -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,657 @@
|
|||
<?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')) 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><b>Explain</b>: '.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
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -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_mysqli extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'mysqli';
|
||||
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 mysqli_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysqli_date_ADOConnection extends mysqli_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 mysqli_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqli_date_ResultSet extends mysqli_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 mysqli_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return mysqli_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,638 @@
|
|||
<?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 mysqli_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
var $nameQuote = '`';
|
||||
var $sysDate = 'CURDATE()';
|
||||
var $sysTimeStamp = 'NOW()';
|
||||
|
||||
function mysqli_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'mysqli';
|
||||
$this->dataProvider = 'mysql';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('mysqli_real_connect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->database = $database;
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
$this->connectionId = @mysqli_init();
|
||||
@mysqli_real_connect( $this->connectionId, $this->host, $this->username, $this->password, $this->database, $this->port, $this->socket, $this->clientFlags );
|
||||
|
||||
if (mysqli_connect_errno() != 0)
|
||||
{
|
||||
$this->connectionId = false;
|
||||
}
|
||||
|
||||
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 = @mysqli_select_db( $this->connectionId, $this->database );
|
||||
|
||||
if($result === false)
|
||||
{
|
||||
if($this->createdatabase == true)
|
||||
{
|
||||
$result = @mysqli_query( $this->connectionId, "CREATE DATABASE IF NOT EXISTS " . $this->database );
|
||||
if ($result === false) { // error handling if query fails
|
||||
return false;
|
||||
}
|
||||
$result = @mysqli_select_db( $this->connectionId, $this->database );
|
||||
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 @mysqli_connect_error();
|
||||
}
|
||||
else
|
||||
{
|
||||
return @mysqli_error($this->connectionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
if ($this->connectionId === false)
|
||||
{
|
||||
return @mysqli_connect_errno();
|
||||
}
|
||||
else
|
||||
{
|
||||
return @mysqli_errno($this->connectionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @mysqli_affected_rows($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return @mysqli_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 && function_exists('mysqli_real_escape_string')) {
|
||||
return "'" . mysqli_real_escape_string($this->connectionId, $string) . "'";
|
||||
}
|
||||
$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()
|
||||
{
|
||||
@mysqli_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 = @mysqli_query($this->connectionId, $this->sql );
|
||||
$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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @mysqli_query($this->connectionId, $this->sql );
|
||||
$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 = MYSQLI_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$recordset->fetchMode = MYSQLI_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$recordset->fetchMode = MYSQLI_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @mysqli_num_rows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @mysqli_num_fields( $resultId );
|
||||
$recordset->_fetch();
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class mysqli_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 mysqli_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()
|
||||
{
|
||||
@mysqli_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 = mysqli_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 @mysqli_data_seek($this->resultId,$row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @mysqli_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)
|
||||
{
|
||||
// $fieldOffset not supported by mysqli
|
||||
$fieldObject = @mysqli_fetch_field($this->resultId);
|
||||
return $fieldObject;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mysqli_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysqli_extend_ADOConnection extends mysqli_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 $_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";
|
||||
var $genID = 0;
|
||||
|
||||
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 = mysqli_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 mysqli_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqli_extend_ResultSet extends mysqli_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,624 @@
|
|||
<?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 mysqli_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysqli_meta_ADOConnection extends mysqli_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 mysqli_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqli_meta_ResultSet extends mysqli_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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,468 @@
|
|||
<?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 = 'mysqli';
|
||||
|
||||
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 mysqli_perfmon_EXTENDER extends perfmon_parent_ADOConnection { }');
|
||||
|
||||
class mysqli_perfmon_ADOConnection extends mysqli_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><b>Explain</b>: '.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 mysqli_perfmon_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqli_perfmon_ResultSet extends mysqli_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':
|
||||
|
||||
case MYSQLI_TYPE_TINY_BLOB :
|
||||
case MYSQLI_TYPE_CHAR :
|
||||
case MYSQLI_TYPE_STRING :
|
||||
case MYSQLI_TYPE_ENUM :
|
||||
case MYSQLI_TYPE_SET :
|
||||
case 253 :
|
||||
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':
|
||||
|
||||
case MYSQLI_TYPE_BLOB :
|
||||
case MYSQLI_TYPE_LONG_BLOB :
|
||||
case MYSQLI_TYPE_MEDIUM_BLOB :
|
||||
|
||||
return !empty($fieldobj->binary) ? 'B' : 'X';
|
||||
case 'YEAR':
|
||||
case 'DATE':
|
||||
case MYSQLI_TYPE_DATE :
|
||||
case MYSQLI_TYPE_YEAR :
|
||||
|
||||
return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP':
|
||||
|
||||
case MYSQLI_TYPE_DATETIME :
|
||||
case MYSQLI_TYPE_NEWDATE :
|
||||
case MYSQLI_TYPE_TIME :
|
||||
case MYSQLI_TYPE_TIMESTAMP :
|
||||
|
||||
return 'T';
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER':
|
||||
case 'BIGINT':
|
||||
case 'TINYINT':
|
||||
case 'MEDIUMINT':
|
||||
case 'SMALLINT':
|
||||
|
||||
case MYSQLI_TYPE_INT24 :
|
||||
case MYSQLI_TYPE_LONG :
|
||||
case MYSQLI_TYPE_LONGLONG :
|
||||
case MYSQLI_TYPE_SHORT :
|
||||
case MYSQLI_TYPE_TINY :
|
||||
|
||||
if (!empty($fieldobj->primary_key)) return 'R';
|
||||
|
||||
return 'I';
|
||||
|
||||
|
||||
// Added floating-point types
|
||||
// Maybe not necessery.
|
||||
case 'FLOAT':
|
||||
case 'DOUBLE':
|
||||
// case 'DOUBLE PRECISION':
|
||||
case 'DECIMAL':
|
||||
case 'DEC':
|
||||
case 'FIXED':
|
||||
default:
|
||||
//if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>";
|
||||
return 'N';
|
||||
}
|
||||
} // function
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for Mysqli
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mysqli_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysqli_transaction_ADOConnection extends mysqli_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()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt += 1;
|
||||
$this->Execute('SET AUTOCOMMIT=0');
|
||||
$this->Execute('BEGIN');
|
||||
return true;
|
||||
}
|
||||
|
||||
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->RollbackTrans();
|
||||
if ($this->debug)
|
||||
ADOCOnnection::outp("Smart Rollback occurred");
|
||||
}
|
||||
return $this->transaction_status;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if (!$ok) return
|
||||
$this->RollbackTrans();
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->Execute('COMMIT');
|
||||
$this->Execute('SET AUTOCOMMIT=1');
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->Execute('ROLLBACK');
|
||||
$this->Execute('SET AUTOCOMMIT=1');
|
||||
return true;
|
||||
}
|
||||
|
||||
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($tables,$where,$flds='1 as ignore')
|
||||
{
|
||||
if ($this->transCnt==0)
|
||||
$this->BeginTrans();
|
||||
|
||||
return $this->GetOne("select $flds from $tables where $where for update");
|
||||
}
|
||||
|
||||
function CommitLock($table)
|
||||
{
|
||||
return $this->CommitTrans();
|
||||
}
|
||||
|
||||
function RollbackLock($table)
|
||||
{
|
||||
return $this->RollbackTrans();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class mysqli_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqli_transaction_ResultSet extends mysqli_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,111 @@
|
|||
<?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_mysqlt extends ADODB_DataDict {
|
||||
var $dbtype = 'mysqlt';
|
||||
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,320 @@
|
|||
<?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 mysqlt_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysqlt_date_ADOConnection extends mysqlt_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()';
|
||||
|
||||
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 mysqlt_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqlt_date_ResultSet extends mysqlt_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 mysqlt_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return mysqlt_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,775 @@
|
|||
<?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 mysqlt_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
var $autoCommit = true;
|
||||
var $transOff = 0;
|
||||
var $transCnt = 0;
|
||||
var $transaction_status = true;
|
||||
var $nameQuote = '`';
|
||||
var $sysDate = 'CURDATE()';
|
||||
var $sysTimeStamp = 'NOW()';
|
||||
var $isoDates = true; // accepts dates in ISO format
|
||||
|
||||
function mysqlt_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'mysqlt';
|
||||
$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')) 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;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt += 1;
|
||||
$this->Execute('SET AUTOCOMMIT=0');
|
||||
$this->Execute('BEGIN');
|
||||
return true;
|
||||
}
|
||||
|
||||
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->RollbackTrans();
|
||||
if ($this->debug)
|
||||
ADOCOnnection::outp("Smart Rollback occurred");
|
||||
}
|
||||
return $this->transaction_status;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if (!$ok) return
|
||||
$this->RollbackTrans();
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->Execute('COMMIT');
|
||||
$this->Execute('SET AUTOCOMMIT=1');
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->Execute('ROLLBACK');
|
||||
$this->Execute('SET AUTOCOMMIT=1');
|
||||
return true;
|
||||
}
|
||||
|
||||
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($tables,$where,$flds='1 as ignore')
|
||||
{
|
||||
if ($this->transCnt==0)
|
||||
$this->BeginTrans();
|
||||
|
||||
return $this->GetOne("select $flds from $tables where $where for update");
|
||||
}
|
||||
|
||||
function CommitLock($table)
|
||||
{
|
||||
return $this->CommitTrans();
|
||||
}
|
||||
|
||||
function RollbackLock($table)
|
||||
{
|
||||
return $this->RollbackTrans();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
$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 mysqlt_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 mysqlt_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 mysqlt_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysqlt_extend_ADOConnection extends mysqlt_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 $_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";
|
||||
var $genID = 0;
|
||||
|
||||
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 mysqlt_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqlt_extend_ResultSet extends mysqlt_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,624 @@
|
|||
<?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 mysqlt_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysqlt_meta_ADOConnection extends mysqlt_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 mysqlt_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqlt_meta_ResultSet extends mysqlt_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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
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 = 'mysqlt';
|
||||
|
||||
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 mysqlt_perfmon_EXTENDER extends perfmon_parent_ADOConnection { }');
|
||||
|
||||
class mysqlt_perfmon_ADOConnection extends mysqlt_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><b>Explain</b>: '.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 mysqlt_perfmon_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqlt_perfmon_ResultSet extends mysqlt_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,18 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class mysqlt_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class mysqlt_transaction_ADOConnection extends mysqlt_transaction_EXTENDER
|
||||
{
|
||||
}
|
||||
|
||||
eval('class mysqlt_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class mysqlt_transaction_ResultSet extends mysqlt_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,65 @@
|
|||
<?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_odbc extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'odbc';
|
||||
var $seqField = false;
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'VARCHAR(250)';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'VARCHAR(250)';
|
||||
|
||||
case 'B': return 'VARCHAR';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATE';
|
||||
|
||||
case 'L': return 'DECIMAL(1)';
|
||||
case 'I': return 'DECIMAL(10)';
|
||||
case 'I1': return 'DECIMAL(3)';
|
||||
case 'I2': return 'DECIMAL(5)';
|
||||
case 'I4': return 'DECIMAL(10)';
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
|
||||
case 'F': return 'DECIMAL(32,8)';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) $this->outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for ODBC
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
eval('class odbc_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class odbc_date_ADOConnection extends odbc_date_EXTENDER
|
||||
{
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
|
||||
var $emptyDate = ' ';
|
||||
var $emptyTimeStamp = ' ';
|
||||
var $sysDate = false; /// name of function that returns the current date
|
||||
var $sysTimeStamp = false; /// name of function that returns the current timestamp
|
||||
var $isoDates = false; /// accepts dates in ISO format
|
||||
|
||||
function Time()
|
||||
{
|
||||
$rs =& $this->_Execute("select $this->sysTimeStamp");
|
||||
if ($rs && !$rs->EOF)
|
||||
return $this->UnixTimeStamp(reset($rs->fields));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
|
||||
return '('.$date.'+'.$dayFraction.')';
|
||||
}
|
||||
|
||||
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'";
|
||||
|
||||
$timestamp = $this->UnixTimeStamp($timestamp);
|
||||
return adodb_date($this->fmtTimeStamp, $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]);
|
||||
else 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;
|
||||
else return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col)
|
||||
$col = $this->sysDate;
|
||||
return $col;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class odbc_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class odbc_date_ResultSet extends odbc_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 odbc_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return odbc_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,645 @@
|
|||
<?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 odbc_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
function odbc_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'odbc';
|
||||
$this->dataProvider = 'odbc';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('odbc_connect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->database = $database;
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
if($this->persistent == 1)
|
||||
{
|
||||
$this->connectionId = @odbc_pconnect( $this->host, $this->username, $this->password );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connectionId = @odbc_connect( $this->host, $this->username, $this->password, $this->forcenewconnection );
|
||||
}
|
||||
|
||||
if ($this->connectionId === false)
|
||||
{
|
||||
if ($fn = $this->raiseErrorFn)
|
||||
$fn($this->dbtype, 'CONNECT', $this->ErrorNo(), $this->ErrorMsg(), $this->host, $this->database, $this);
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error message
|
||||
* Usage: $errormessage =& $db->ErrorMsg();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if (strnatcmp(PHP_VERSION, '4.0.5') >= 0)
|
||||
{
|
||||
if ($this->connectionId)
|
||||
{
|
||||
return @odbc_errormsg();
|
||||
}
|
||||
else
|
||||
{
|
||||
return @odbc_errormsg($this->connectionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
if (strnatcmp(PHP_VERSION, '4.0.5') >= 0)
|
||||
{
|
||||
if ($this->connectionId)
|
||||
{
|
||||
return @odbc_error();
|
||||
}
|
||||
else
|
||||
{
|
||||
return @odbc_error($this->connectionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
$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();
|
||||
return implode("+", $arr);
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " CASE WHEN $field is null THEN $ifNull ELSE $field END ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@odbc_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 != -1 || $nrows != -1)
|
||||
{
|
||||
$offset = ($offset>=0) ? $offset . "," : '';
|
||||
$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 = @odbc_exec( $this->connectionId, $this->sql );
|
||||
$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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @odbc_exec( $this->connectionId, $this->sql );
|
||||
$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 = ADODB_FETCH_NUM; break;
|
||||
case ADODB_FETCH_ASSOC: $recordset->fetchMode = ADODB_FETCH_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH: $recordset->fetchMode = ADODB_FETCH_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @odbc_num_rows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @odbc_num_fields( $resultId );
|
||||
$recordset->_fetch();
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class odbc_driver_ResultSet
|
||||
{
|
||||
var $connectionId;
|
||||
var $fields;
|
||||
var $resultId;
|
||||
var $_currentRow = 0;
|
||||
var $_numOfRows = -1;
|
||||
var $_numOfFields = -1;
|
||||
var $fetchMode;
|
||||
var $EOF;
|
||||
var $odbcchange;
|
||||
var $temp;
|
||||
|
||||
/**
|
||||
* odbcResultSet Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $record
|
||||
* @param string $resultId
|
||||
*/
|
||||
|
||||
function odbc_driver_ResultSet( $resultId, $connectionId )
|
||||
{
|
||||
$this->fields = array();
|
||||
$this->connectionId = $connectionId;
|
||||
$this->record = array();
|
||||
$this->resultId = $resultId;
|
||||
$this->EOF = false;
|
||||
$this->odbcchange = strnatcmp(PHP_VERSION, '4.2.0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees resultset
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@odbc_close( $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->odbcchange >= 0){
|
||||
$result = @odbc_fetch_into($this->resultId, $this->fields);
|
||||
}
|
||||
else
|
||||
{
|
||||
$row = 0;
|
||||
$result = @odbc_fetch_into($this->resultId, $row, $this->fields);
|
||||
}
|
||||
if ($result) {
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
|
||||
$this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
|
||||
}
|
||||
$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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
if ($this->odbcchange >= 0){
|
||||
$result = @odbc_fetch_into($this->resultId, $this->fields);
|
||||
}
|
||||
else
|
||||
{
|
||||
$row = 0;
|
||||
$result = @odbc_fetch_into($this->resultId, $row, $this->fields);
|
||||
}
|
||||
if ($result) {
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
|
||||
$this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->fields = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$fieldOffset += 1; // offsets begin at 1
|
||||
|
||||
$fieldObject= new ADOFieldObject();
|
||||
$fieldObject->name = @odbc_field_name($this->resultId, $fieldOffset);
|
||||
$fieldObject->type = @odbc_field_type($this->resultId, $fieldOffset);
|
||||
$fieldObject->max_length = @odbc_field_len($this->resultId, $fieldOffset);
|
||||
return $fieldObject;
|
||||
}
|
||||
|
||||
function GetRowAssoc($upper=1)
|
||||
{
|
||||
$record = array();
|
||||
if (!$this->temp) {
|
||||
$this->temp = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$object = $this->FetchField($i);
|
||||
if ($upper === 2) $this->temp[$object->name] = $i;
|
||||
else $this->temp[($upper) ? strtoupper($object->name) : strtolower($object->name)] = $i;
|
||||
}
|
||||
}
|
||||
foreach($this->temp as $k => $v) {
|
||||
$record[$k] = $this->fields[$v];
|
||||
}
|
||||
return $record;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class odbc_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class odbc_extend_ADOConnection extends odbc_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 $_genSeqSQL = "create table %s (id integer)";
|
||||
var $_dropSeqSQL = 'drop table %s';
|
||||
var $genID = 0;
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
$MAXLOOPS = 100;
|
||||
|
||||
while (--$MAXLOOPS>=0) {
|
||||
$num = $this->GetOne("select id from $seq");
|
||||
if ($num === false) {
|
||||
$this->Execute(sprintf($this->_genSeqSQL, $seq));
|
||||
$start -= 1;
|
||||
$num = '0';
|
||||
$result = $this->Execute("insert into $seq values($start)");
|
||||
if (!$result)
|
||||
return false;
|
||||
}
|
||||
$this->Execute("update $seq set id=id+1 where id=$num");
|
||||
|
||||
if ($this->affected_rows() > 0) {
|
||||
$num += 1;
|
||||
$this->genID = $num;
|
||||
return $num;
|
||||
}
|
||||
}
|
||||
if ($fn = $this->raiseErrorFn) {
|
||||
$fn($this->databaseType, 'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts", $seq, $num);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq', $start=1)
|
||||
{
|
||||
$ok = $this->Execute(sprintf($this->_genSeqSQL, $seqname));
|
||||
if (!$ok)
|
||||
return false;
|
||||
$start -= 1;
|
||||
return $this->Execute("insert into $seqname values($start)");
|
||||
}
|
||||
|
||||
function DropSequence($seqname)
|
||||
{
|
||||
return $this->Execute(sprintf($this->_dropSeqSQL, $seqname));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class odbc_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class odbc_extend_ResultSet extends odbc_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,616 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for ODBC
|
||||
*
|
||||
* 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 odbc_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class odbc_meta_ADOConnection extends odbc_meta_EXTENDER
|
||||
{
|
||||
var $metaTablesSQL = "SHOW TABLES";
|
||||
var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
|
||||
var $uCaseTables = true; // for meta* functions, uppercase table names
|
||||
|
||||
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)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->uCaseTables) $table = strtoupper($table);
|
||||
$schema = '';
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$qid = @odbc_primarykeys($this->_connectionID,'',$schema,$table);
|
||||
|
||||
if (!$qid) {
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
return false;
|
||||
}
|
||||
$rs = new ADORecordSet_odbc($qid);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if (!$rs) return false;
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
|
||||
$arr =& $rs->GetArray();
|
||||
$rs->Close();
|
||||
//print_r($arr);
|
||||
$arr2 = array();
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
if ($arr[$i][3]) $arr2[] = $arr[$i][3];
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns assoc array where keys are tables, and values are foreign keys
|
||||
*/
|
||||
function MetaForeignKeys($table, $owner=false, $upper=false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->metaDatabasesSQL) {
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$arr = $this->GetCol($this->metaDatabasesSQL);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
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($ttype=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$qid = odbc_tables($this->_connectionID);
|
||||
|
||||
$rs = new ADORecordSet_odbc($qid);
|
||||
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
if (!$rs) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
|
||||
$arr =& $rs->GetArray();
|
||||
//print_r($arr);
|
||||
|
||||
$rs->Close();
|
||||
$arr2 = array();
|
||||
|
||||
if ($ttype) {
|
||||
$isview = strncmp($ttype,'V',1) === 0;
|
||||
}
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
if (!$arr[$i][2]) continue;
|
||||
$type = $arr[$i][3];
|
||||
if ($ttype) {
|
||||
if ($isview) {
|
||||
if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
|
||||
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
|
||||
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$false = false;
|
||||
if ($this->uCaseTables) $table = strtoupper($table);
|
||||
$schema = '';
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
/*if (false) { // after testing, confirmed that the following does not work becoz of a bug
|
||||
$qid2 = odbc_tables($this->_connectionID);
|
||||
$rs = new ADORecordSet_odbc($qid2);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
if (!$rs) return false;
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
$rs->_fetch();
|
||||
|
||||
while (!$rs->EOF) {
|
||||
if ($table == strtoupper($rs->fields[2])) {
|
||||
$q = $rs->fields[0];
|
||||
$o = $rs->fields[1];
|
||||
break;
|
||||
}
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
|
||||
$qid = odbc_columns($this->_connectionID,$q,$o,strtoupper($table),'%');
|
||||
} */
|
||||
|
||||
switch ($this->databaseType) {
|
||||
case 'access':
|
||||
case 'vfp':
|
||||
$qid = odbc_columns($this->_connectionID);#,'%','',strtoupper($table),'%');
|
||||
break;
|
||||
|
||||
|
||||
case 'db2':
|
||||
$colname = "%";
|
||||
$qid = odbc_columns($this->_connectionID, "", $schema, $table, $colname);
|
||||
break;
|
||||
|
||||
default:
|
||||
$qid = @odbc_columns($this->_connectionID,'%','%',strtoupper($table),'%');
|
||||
if (empty($qid)) $qid = odbc_columns($this->_connectionID);
|
||||
break;
|
||||
}
|
||||
if (empty($qid)) return $false;
|
||||
|
||||
$rs =& new ADORecordSet_odbc($qid);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if (!$rs) return $false;
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
$rs->_fetch();
|
||||
|
||||
$retarr = array();
|
||||
|
||||
/*
|
||||
$rs->fields indices
|
||||
0 TABLE_QUALIFIER
|
||||
1 TABLE_SCHEM
|
||||
2 TABLE_NAME
|
||||
3 COLUMN_NAME
|
||||
4 DATA_TYPE
|
||||
5 TYPE_NAME
|
||||
6 PRECISION
|
||||
7 LENGTH
|
||||
8 SCALE
|
||||
9 RADIX
|
||||
10 NULLABLE
|
||||
11 REMARKS
|
||||
*/
|
||||
while (!$rs->EOF) {
|
||||
// adodb_pr($rs->fields);
|
||||
if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[3];
|
||||
$fld->type = $this->ODBCTypes($rs->fields[4]);
|
||||
|
||||
// ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
|
||||
// access uses precision to store length for char/varchar
|
||||
if ($fld->type == 'C' or $fld->type == 'X') {
|
||||
if ($this->databaseType == 'access')
|
||||
$fld->max_length = $rs->fields[6];
|
||||
else if ($rs->fields[4] <= -95) // UNICODE
|
||||
$fld->max_length = $rs->fields[7]/2;
|
||||
else
|
||||
$fld->max_length = $rs->fields[7];
|
||||
} else
|
||||
$fld->max_length = $rs->fields[7];
|
||||
$fld->not_null = !empty($rs->fields[10]);
|
||||
$fld->scale = $rs->fields[8];
|
||||
$retarr[strtoupper($fld->name)] = $fld;
|
||||
} else if (sizeof($retarr)>0)
|
||||
break;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close(); //-- crashes 4.03pl1 -- why?
|
||||
|
||||
if (empty($retarr)) $retarr = false;
|
||||
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)
|
||||
{
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
function ODBCTypes($t)
|
||||
{
|
||||
switch ((integer)$t) {
|
||||
case 1:
|
||||
case 12:
|
||||
case 0:
|
||||
case -95:
|
||||
case -96:
|
||||
return 'C';
|
||||
case -97:
|
||||
case -1: //text
|
||||
return 'X';
|
||||
case -4: //image
|
||||
return 'B';
|
||||
|
||||
case 9:
|
||||
case 91:
|
||||
return 'D';
|
||||
|
||||
case 10:
|
||||
case 11:
|
||||
case 92:
|
||||
case 93:
|
||||
return 'T';
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
case -6:
|
||||
return 'I';
|
||||
|
||||
case -11: // uniqidentifier
|
||||
return 'R';
|
||||
case -7: //bit
|
||||
return 'L';
|
||||
|
||||
default:
|
||||
return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class odbc_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class odbc_meta_ResultSet extends odbc_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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for ODBC
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class odbc_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class odbc_transaction_ADOConnection extends odbc_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()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt += 1;
|
||||
$this->autocommit = false;
|
||||
return odbc_autocommit($this->connectionId,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->RollbackTrans();
|
||||
if ($this->debug)
|
||||
ADOCOnnection::outp("Smart Rollback occurred");
|
||||
}
|
||||
return $this->transaction_status;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if (!$ok)
|
||||
return $this->RollbackTrans();
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->autocommit = true;
|
||||
$ret = odbc_commit($this->connectionId);
|
||||
odbc_autocommit($this->connectionId,true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if ($this->transCnt)
|
||||
$this->transCnt -= 1;
|
||||
|
||||
$this->autocommit = true;
|
||||
$ret = odbc_rollback($this->connectionId);
|
||||
odbc_autocommit($this->connectionId,true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
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($tables,$where,$flds='1 as ignore')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function CommitLock($table)
|
||||
{
|
||||
return $this->CommitTrans();
|
||||
}
|
||||
|
||||
function RollbackLock($table)
|
||||
{
|
||||
return $this->RollbackTrans();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class odbc_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class odbc_transaction_ResultSet extends odbc_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,211 @@
|
|||
<?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_postgres extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'postgres';
|
||||
var $seqField = false;
|
||||
var $seqPrefix = 'SEQ_';
|
||||
var $addCol = ' ADD COLUMN';
|
||||
var $quote = '"';
|
||||
var $renameTable = 'ALTER TABLE %s RENAME TO %s'; // at least since 7.1
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'TEXT';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'TEXT';
|
||||
|
||||
case 'B': return 'BYTEA';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'TIMESTAMP';
|
||||
|
||||
case 'L': return 'BOOLEAN';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'INT2';
|
||||
case 'I4': return 'INT4';
|
||||
case 'I8': return 'INT8';
|
||||
|
||||
case 'F': return 'FLOAT8';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (($not_null = preg_match('/NOT NULL/i',$v))) {
|
||||
$v = preg_replace('/NOT NULL/i','',$v);
|
||||
}
|
||||
if (preg_match('/^([^ ]+) .*(DEFAULT [^ ]+)/',$v,$matches)) {
|
||||
list(,$colname,$default) = $matches;
|
||||
$sql[] = $alter . str_replace($default,'',$v);
|
||||
$sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET ' . $default;
|
||||
} else {
|
||||
$sql[] = $alter . $v;
|
||||
}
|
||||
if ($not_null) {
|
||||
list($colname) = explode(' ',$v);
|
||||
$sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL';
|
||||
}
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
|
||||
{
|
||||
if (!$tableflds) {
|
||||
if ($this->debug) $this->outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
|
||||
return array();
|
||||
}
|
||||
return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions);
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
|
||||
{
|
||||
$has_drop_column = 7.3 <= (float) @$this->serverInfo['version'];
|
||||
if (!$has_drop_column && !$tableflds) {
|
||||
if ($this->debug) $this->outp("DropColumnSQL needs complete table-definiton for PostgreSQL < 7.3");
|
||||
return array();
|
||||
}
|
||||
if ($has_drop_column) {
|
||||
return ADODB_DataDict::DropColumnSQL($tabname, $flds);
|
||||
}
|
||||
return $this->_recreate_copy_table($tabname,$flds,$tableflds,$tableoptions);
|
||||
}
|
||||
|
||||
function DropTableSQL($tabname)
|
||||
{
|
||||
$sql = ADODB_DataDict::DropTableSQL($tabname);
|
||||
$drop_seq = $this->_DropAutoIncrement($tabname);
|
||||
if ($drop_seq) $sql[] = $drop_seq;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
if ($fautoinc) {
|
||||
$ftype = 'SERIAL';
|
||||
return '';
|
||||
}
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
function _DropAutoIncrement($tabname)
|
||||
{
|
||||
$tabname = $this->connection->qstr('%'.$tabname.'%');
|
||||
|
||||
$seq = $this->connection->GetOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'");
|
||||
|
||||
// check if a tables depends on the sequenz and it therefor cant and dont need to be droped separatly
|
||||
if (!$seq || $this->connection->GetOne("SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) {
|
||||
return False;
|
||||
}
|
||||
return "DROP SEQUENCE ".$seq;
|
||||
}
|
||||
|
||||
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
|
||||
{
|
||||
$sql = array();
|
||||
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
|
||||
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
|
||||
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['HASH']))
|
||||
$s .= 'USING HASH ';
|
||||
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
|
||||
if ( is_array($flds) )
|
||||
$flds = implode(', ',$flds);
|
||||
$s .= '(' . $flds . ')';
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
||||
function _recreate_copy_table($tabname,$dropflds,$tableflds,$tableoptions='')
|
||||
{
|
||||
if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds);
|
||||
$copyflds = array();
|
||||
foreach($this->MetaColumns($tabname) as $fld) {
|
||||
if (!$dropflds || !in_array($fld->name,$dropflds)) {
|
||||
// we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one
|
||||
if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) &&
|
||||
in_array($fld->type,array('varchar','char','text','bytea'))) {
|
||||
$copyflds[] = "to_number($fld->name,'S99D99')";
|
||||
} else {
|
||||
$copyflds[] = $fld->name;
|
||||
}
|
||||
// identify the sequence name and the fld its on
|
||||
if ($fld->primary_key && $fld->has_default &&
|
||||
preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) {
|
||||
$seq_name = $matches[1];
|
||||
$seq_fld = $fld->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
$copyflds = implode(', ',$copyflds);
|
||||
|
||||
$tempname = $tabname.'_tmp';
|
||||
$aSql[] = 'BEGIN'; // we use a transaction, to make sure not to loose the content of the table
|
||||
$aSql[] = "SELECT * INTO TEMPORARY TABLE $tempname FROM $tabname";
|
||||
$aSql = array_merge($aSql,$this->DropTableSQL($tabname));
|
||||
$aSql = array_merge($aSql,$this->CreateTableSQL($tabname,$tableflds,$tableoptions));
|
||||
$aSql[] = "INSERT INTO $tabname SELECT $copyflds FROM $tempname";
|
||||
if ($seq_name && $seq_fld) { // if we have a sequence we need to set it again
|
||||
$seq_name = $tabname.'_'.$seq_fld.'_seq'; // has to be the name of the new implicit sequence
|
||||
$aSql[] = "SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname";
|
||||
}
|
||||
$aSql[] = "DROP TABLE $tempname";
|
||||
// recreate the indexes, if they not contain one of the droped columns
|
||||
foreach($this->MetaIndexes($tabname) as $idx_name => $idx_data)
|
||||
{
|
||||
if (substr($idx_name,-5) != '_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data['columns'])))) {
|
||||
$aSql = array_merge($aSql,$this->CreateIndexSQL($idx_name,$tabname,$idx_data['columns'],
|
||||
$idx_data['unique'] ? array('UNIQUE') : False));
|
||||
}
|
||||
}
|
||||
$aSql[] = 'COMMIT';
|
||||
return $aSql;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,316 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for Postgres
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
eval('class postgres_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class postgres_date_ADOConnection extends postgres_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'"; // used by DBTimeStamp as the default timestamp fmt.
|
||||
var $emptyDate = ' ';
|
||||
var $emptyTimeStamp = ' ';
|
||||
var $sysDate = "CURRENT_DATE";
|
||||
var $sysTimeStamp = "CURRENT_TIMESTAMP";
|
||||
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));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
else if (strncmp($date,"'",1) == 0) {
|
||||
$len = strlen($date);
|
||||
if (10 <= $len && $len <= 12)
|
||||
$date = 'date ' . $date;
|
||||
else $date = 'timestamp ' . $date;
|
||||
}
|
||||
return "($date+interval'$dayFraction days')";
|
||||
}
|
||||
|
||||
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'";
|
||||
|
||||
$timestamp = $this->UnixTimeStamp($timestamp);
|
||||
return adodb_date($this->fmtTimeStamp, $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]);
|
||||
else 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;
|
||||
else return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col)
|
||||
$col = $this->sysTimeStamp;
|
||||
|
||||
$s = 'TO_CHAR('.$col.",'";
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= 'YYYY';
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= 'Q';
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
$s .= 'Mon';
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
$s .= 'MM';
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= 'DD';
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s.= 'HH24';
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
$s .= 'HH';
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= 'MI';
|
||||
break;
|
||||
|
||||
case 's':
|
||||
$s .= 'SS';
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= 'AM';
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
$s .= 'D';
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
$s .= 'DAY';
|
||||
break;
|
||||
|
||||
default:
|
||||
// handle escape characters...
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
if (strpos('-/.:;, ',$ch) !== false)
|
||||
$s .= $ch;
|
||||
else $s .= '"'.$ch.'"';
|
||||
}
|
||||
}
|
||||
return $s. "')";
|
||||
}
|
||||
}
|
||||
|
||||
eval('class postgres_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class postgres_date_ResultSet extends postgres_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 postgres_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return postgres_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,657 @@
|
|||
<?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 postgres_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
var $connect_string;
|
||||
var $sysDate = "CURRENT_DATE";
|
||||
var $sysTimeStamp = "CURRENT_TIMESTAMP";
|
||||
|
||||
function postgres_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'postgres';
|
||||
$this->dataProvider = 'postgres';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('pg_connect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $this->query_addslashes($username);
|
||||
$this->password = $this->query_addslashes($password);
|
||||
if (strlen($database) == 0) $database = 'template1';
|
||||
$this->database = $this->query_addslashes($database);
|
||||
|
||||
if ($this->username || $this->password || $this->database) {
|
||||
$this->connect_string = $this->host;
|
||||
if ($this->connect_string) {
|
||||
$host = split(":", $this->connect_string);
|
||||
if ($host[0]) $this->connect_string = "host=" . $this->query_addslashes($host[0]);
|
||||
else $this->connect_string = 'host=localhost';
|
||||
if (isset($host[1])) $this->connect_string .= " port=$host[1]";
|
||||
else if (!empty($this->port)) $this->connect_string .= " port=" . $this->port;
|
||||
}
|
||||
if ($this->username) $this->connect_string .= " user=" . $this->username;
|
||||
if ($this->password) $this->connect_string .= " password=" . $this->password;
|
||||
if ($this->database) $this->connect_string .= " dbname=" . $this->database;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connect_string = $this->host;
|
||||
}
|
||||
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
$this->_makeconnection();
|
||||
|
||||
if ($this->connectionId === false)
|
||||
{
|
||||
if ($fn = $this->raiseErrorFn)
|
||||
$fn($this->dbtype, 'CONNECT', $this->ErrorNo(), $this->ErrorMsg(), $this->host, $this->database, $this);
|
||||
return $this->SelectDB( $this->database );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function _makeconnection()
|
||||
{
|
||||
if($this->persistent == 1)
|
||||
{
|
||||
$this->connectionId = @pg_pconnect( $this->connect_string );
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!$this->forcenewconnection)
|
||||
{
|
||||
$this->connectionId = @pg_connect( $this->connect_string );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connectionId = @pg_connect( $this->connect_string, PGSQL_CONNECT_FORCE_NEW );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function query_addslashes($query)
|
||||
{
|
||||
$len = strlen($query);
|
||||
if ($len == 0)
|
||||
return "''";
|
||||
if (strncmp($query,"'",1) === 0 && substr($query,$len-1) == "'")
|
||||
return $s;
|
||||
return "'".addslashes($query)."'";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if($this->createdatabase == true)
|
||||
{
|
||||
$this->connectionId = @pg_pconnect( $this->connect_string );
|
||||
$result = @pg_query($this->connectionId, "CREATE DATABASE " . $this->database );
|
||||
if ($result === false) { // error handling if query fails
|
||||
$this->connectionId = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_makeconnection();
|
||||
if($this->connectionId === false)
|
||||
{
|
||||
$this->connectionId = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$this->connectionId = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error message
|
||||
* Usage: $errormessage =& $db->ErrorMsg();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
return @pg_last_error($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
$error = @pg_last_error( $this->connectionId );
|
||||
return strlen($error) ? $error : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @pg_affected_rows($this->record_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return @pg_getlastoid($this->record_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.2.0') >= 0) {
|
||||
return "'" . pg_escape_string($string) . "'";
|
||||
}
|
||||
$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();
|
||||
return implode("||", $arr);
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " coalesce($field, $ifNull) ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@pg_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 != -1 || $nrows != -1)
|
||||
// {
|
||||
// $offset = ($offset>=0) ? $offset . "," : '';
|
||||
// $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 ? "'t'" : "'f'";
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @pg_query($this->connectionId, $this->sql );
|
||||
$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);
|
||||
}
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @pg_query($this->connectionId, $this->sql );
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
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 (@pg_numfields( $resultId ) <= 0) { // return simplified recordset for inserts/updates/deletes with lower overhead
|
||||
$recordset = new ADORecordSet_empty();
|
||||
$this->record_set = $recordset;
|
||||
return $recordset;
|
||||
}
|
||||
|
||||
$resultset_name = $this->last_module_name . "_ResultSet";
|
||||
$recordset = new $resultset_name( $resultId, $this->connectionId );
|
||||
$this->record_set = $recordset;
|
||||
|
||||
$recordset->_currentRow = 0;
|
||||
|
||||
switch ($ADODB_FETCH_MODE)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $recordset->fetchMode = PGSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$recordset->fetchMode = PGSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$recordset->fetchMode = PGSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @pg_numrows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @pg_numfields( $resultId );
|
||||
$recordset->_fetch();
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class postgres_driver_ResultSet
|
||||
{
|
||||
var $connectionId;
|
||||
var $fields;
|
||||
var $resultId;
|
||||
var $_currentRow = 0;
|
||||
var $_numOfRows = -1;
|
||||
var $_numOfFields = -1;
|
||||
var $fetchMode;
|
||||
var $EOF;
|
||||
|
||||
/**
|
||||
* pgsqlResultSet Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $record
|
||||
* @param string $resultId
|
||||
*/
|
||||
|
||||
function postgres_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()
|
||||
{
|
||||
pg_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 = pg_fetch_array($this->resultId, NULL, $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 @pg_result_seek($this->resultId,$row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @pg_fetch_array($this->resultId, NULL, $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)
|
||||
{
|
||||
$fieldObject= new ADOFieldObject();
|
||||
$fieldObject->name = @pg_fieldname($this->resultId, $fieldOffset);
|
||||
$fieldObject->type = @pg_fieldtype($this->resultId, $fieldOffset);
|
||||
$fieldObject->max_length = @pg_fieldsize($this->resultId, $fieldOffset);
|
||||
return $fieldObject;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class postgres_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class postgres_extend_ADOConnection extends postgres_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 $_genIDSQL = "SELECT NEXTVAL('%s')";
|
||||
var $_genSeqSQL = "CREATE SEQUENCE %s START %s";
|
||||
var $_dropSeqSQL = "DROP SEQUENCE %s";
|
||||
var $genID = 0;
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
$getnext = sprintf($this->_genIDSQL, $seqname);
|
||||
$holdtransOK = $this->transaction_status;
|
||||
$save_handler = $this->raiseErrorFn;
|
||||
$this->raiseErrorFn = '';
|
||||
@($result = $this->Execute($getnext));
|
||||
$this->raiseErrorFn = $save_handler;
|
||||
|
||||
if (!$result) {
|
||||
$this->transaction_status = $holdtransOK;
|
||||
$createseq = $this->Execute(sprintf($this->_genSeqSQL, $seqname, $startID));
|
||||
$result = $this->Execute($getnext);
|
||||
}
|
||||
if ($result && !$result->EOF)
|
||||
$this->genID = reset($result->fields);
|
||||
else $this->genID = 0;
|
||||
|
||||
if ($result)
|
||||
$result->Close();
|
||||
|
||||
return $this->genID;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
return $this->Execute(sprintf($this->_genSeqSQL, $seqname, $startID));
|
||||
}
|
||||
|
||||
function DropSequence($seqname='adodbseq')
|
||||
{
|
||||
return $this->Execute(sprintf($this->_dropSeqSQL, $seqname));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class postgres_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class postgres_extend_ResultSet extends postgres_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,684 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for Postgres
|
||||
*
|
||||
* 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 postgres_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class postgres_meta_ADOConnection extends postgres_meta_EXTENDER
|
||||
{
|
||||
var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
|
||||
var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
|
||||
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
|
||||
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname not like 'pg\_%'";
|
||||
var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
|
||||
FROM pg_class c, pg_attribute a,pg_type t
|
||||
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
|
||||
AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
|
||||
|
||||
// used when schema defined
|
||||
var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
|
||||
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
|
||||
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
|
||||
and c.relnamespace=n.oid and n.nspname='%s'
|
||||
and a.attname not like '....%%' AND a.attnum > 0
|
||||
AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
|
||||
|
||||
// get primary key etc -- from Freek Dijkstra
|
||||
var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
|
||||
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
|
||||
var $metaDefaultsSQL = "SELECT d.adnum as num, d.adsrc as def from pg_attrdef d, pg_class c where d.adrelid=c.oid and c.relname='%s' order by d.adnum";
|
||||
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->metaDatabasesSQL) {
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$arr = $this->GetCol($this->metaDatabasesSQL);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
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($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
$info = $this->ServerInfo();
|
||||
if ($info['version'] >= 7.3) {
|
||||
$this->metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
|
||||
and schemaname not in ( 'pg_catalog','information_schema')
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema') ";
|
||||
}
|
||||
if ($mask) {
|
||||
$save = $this->metaTablesSQL;
|
||||
$mask = $this->qstr(strtolower($mask));
|
||||
if ($info['version']>=7.3)
|
||||
$this->metaTablesSQL = "
|
||||
select tablename,'T' from pg_tables where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema')
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname like $mask and schemaname not in ( 'pg_catalog','information_schema') ";
|
||||
else
|
||||
$this->metaTablesSQL = "
|
||||
select tablename,'T' from pg_tables where tablename like $mask
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname like $mask";
|
||||
}
|
||||
$ret =& $this->_MetaTables($ttype,$showSchema);
|
||||
|
||||
if ($mask) {
|
||||
$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,$normalize=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = false;
|
||||
$false = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
if ($normalize) $table = strtolower($table);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
|
||||
else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rs === false) {
|
||||
return $false;
|
||||
}
|
||||
if (!empty($this->metaKeySQL)) {
|
||||
// If we want the primary keys, we have to issue a separate query
|
||||
// Of course, a modified version of the metaColumnsSQL query using a
|
||||
// LEFT JOIN would have been much more elegant, but postgres does
|
||||
// not support OUTER JOINS. So here is the clumsy way.
|
||||
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
|
||||
$rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
|
||||
// fetch all result in once for performance.
|
||||
$keys =& $rskey->GetArray();
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
$rskey->Close();
|
||||
unset($rskey);
|
||||
}
|
||||
|
||||
$rsdefa = array();
|
||||
if (!empty($this->metaDefaultsSQL)) {
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
$sql = sprintf($this->metaDefaultsSQL, ($table));
|
||||
$rsdef = $this->Execute($sql);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rsdef) {
|
||||
while (!$rsdef->EOF) {
|
||||
$num = $rsdef->fields['num'];
|
||||
$s = $rsdef->fields['def'];
|
||||
if (strpos($s,'::')===false && substr($s, 0, 1) == "'") { /* quoted strings hack... for now... fixme */
|
||||
$s = substr($s, 1);
|
||||
$s = substr($s, 0, strlen($s) - 1);
|
||||
}
|
||||
|
||||
$rsdefa[$num] = $s;
|
||||
$rsdef->MoveNext();
|
||||
}
|
||||
} else {
|
||||
ADOConnection::outp( "==> SQL => " . $sql);
|
||||
}
|
||||
unset($rsdef);
|
||||
}
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) {
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
$fld->max_length = $rs->fields[2];
|
||||
$fld->attnum = $rs->fields[6];
|
||||
|
||||
if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4;
|
||||
if ($fld->max_length <= 0) $fld->max_length = -1;
|
||||
if ($fld->type == 'numeric') {
|
||||
$fld->scale = $fld->max_length & 0xFFFF;
|
||||
$fld->max_length >>= 16;
|
||||
}
|
||||
// dannym
|
||||
// 5 hasdefault; 6 num-of-column
|
||||
$fld->has_default = ($rs->fields[5] == 't');
|
||||
if ($fld->has_default) {
|
||||
$fld->default_value = $rsdefa[$rs->fields[6]];
|
||||
}
|
||||
|
||||
//Freek
|
||||
$fld->not_null = $rs->fields[4] == 't';
|
||||
|
||||
|
||||
// Freek
|
||||
if (is_array($keys)) {
|
||||
foreach($keys as $key) {
|
||||
if ($fld->name == $key['column_name'] AND $key['primary_key'] == 't')
|
||||
$fld->primary_key = true;
|
||||
if ($fld->name == $key['column_name'] AND $key['unique_key'] == 't')
|
||||
$fld->unique = true; // What name is more compatible?
|
||||
}
|
||||
}
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[($normalize) ? strtoupper($fld->name) : $fld->name] = $fld;
|
||||
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
if (empty($retarr))
|
||||
return $false;
|
||||
else
|
||||
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)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
|
||||
$sql = '
|
||||
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
|
||||
FROM pg_catalog.pg_class c
|
||||
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
|
||||
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
|
||||
,pg_namespace n
|
||||
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\')) and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\'';
|
||||
} else {
|
||||
$sql = '
|
||||
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
|
||||
FROM pg_catalog.pg_class c
|
||||
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
|
||||
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
|
||||
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
|
||||
}
|
||||
|
||||
if ($primary == FALSE) {
|
||||
$sql .= ' AND i.indisprimary=false;';
|
||||
}
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== FALSE) {
|
||||
$savem = $this->SetFetchMode(FALSE);
|
||||
}
|
||||
|
||||
$rs = $this->Execute(sprintf($sql,$table,$table,$schema));
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!is_object($rs)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
$col_names = $this->MetaColumnNames($table,true,true);
|
||||
//3rd param is use attnum,
|
||||
// see http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976
|
||||
$indexes = array();
|
||||
while ($row = $rs->FetchRow()) {
|
||||
$columns = array();
|
||||
foreach (explode(' ', $row[2]) as $col) {
|
||||
$columns[] = $col_names[$col];
|
||||
}
|
||||
|
||||
$indexes[$row[0]] = array(
|
||||
'unique' => ($row[1] == 't'),
|
||||
'columns' => $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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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 postgres_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class postgres_meta_ResultSet extends postgres_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;
|
||||
}
|
||||
$is_serial = is_object($fieldobj) && $fieldobj->primary_key && $fieldobj->unique && $fieldobj->has_default && substr($fieldobj->default_value,0,8) == 'nextval(';
|
||||
switch (strtoupper($t)) {
|
||||
case 'MONEY': // stupid, postgres expects money to be a string
|
||||
case 'INTERVAL':
|
||||
case 'CHAR':
|
||||
case 'CHARACTER':
|
||||
case 'VARCHAR':
|
||||
case 'NAME':
|
||||
case 'BPCHAR':
|
||||
case '_VARCHAR':
|
||||
case 'INET':
|
||||
case 'MACADDR':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
case 'TEXT':
|
||||
return 'X';
|
||||
case 'IMAGE': // user defined type
|
||||
case 'BLOB': // user defined type
|
||||
case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
|
||||
case 'VARBIT':
|
||||
case 'BYTEA':
|
||||
return 'B';
|
||||
case 'BOOL':
|
||||
case 'BOOLEAN':
|
||||
return 'L';
|
||||
case 'DATE':
|
||||
return 'D';
|
||||
case 'TIMESTAMP WITHOUT TIME ZONE':
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP':
|
||||
case 'TIMESTAMPTZ':
|
||||
return 'T';
|
||||
case 'INTEGER': return !$is_serial ? 'I' : 'R';
|
||||
case 'SMALLINT':
|
||||
case 'INT2': return !$is_serial ? 'I2' : 'R';
|
||||
case 'INT4': return !$is_serial ? 'I4' : 'R';
|
||||
case 'BIGINT':
|
||||
case 'INT8': return !$is_serial ? 'I8' : 'R';
|
||||
case 'OID':
|
||||
case 'SERIAL':
|
||||
return 'R';
|
||||
case 'FLOAT4':
|
||||
case 'FLOAT8':
|
||||
case 'DOUBLE PRECISION':
|
||||
case 'REAL':
|
||||
return 'F';
|
||||
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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for Postgres
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class postgres_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class postgres_transaction_ADOConnection extends postgres_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()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt += 1;
|
||||
return @pg_Exec($this->connectionId, "begin");
|
||||
}
|
||||
|
||||
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->RollbackTrans();
|
||||
if ($this->debug)
|
||||
ADOCOnnection::outp("Smart Rollback occurred");
|
||||
}
|
||||
return $this->transaction_status;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if (!$ok)
|
||||
return $this->RollbackTrans();
|
||||
|
||||
$this->transCnt -= 1;
|
||||
return @pg_Exec($this->connectionId, "commit");
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt -= 1;
|
||||
return @pg_Exec($this->connectionId, "rollback");
|
||||
}
|
||||
|
||||
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($tables,$where,$flds='1 as ignore')
|
||||
{
|
||||
if (!$this->transCnt)
|
||||
$this->BeginTrans();
|
||||
|
||||
return $this->GetOne("select $flds from $tables where $where for update");
|
||||
}
|
||||
|
||||
function CommitLock($table)
|
||||
{
|
||||
return $this->CommitTrans();
|
||||
}
|
||||
|
||||
function RollbackLock($table)
|
||||
{
|
||||
return $this->RollbackTrans();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class postgres_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class postgres_transaction_ResultSet extends postgres_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,211 @@
|
|||
<?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_postgres64 extends ADODB_DataDict {
|
||||
|
||||
var $dbtype = 'postgres';
|
||||
var $seqField = false;
|
||||
var $seqPrefix = 'SEQ_';
|
||||
var $addCol = ' ADD COLUMN';
|
||||
var $quote = '"';
|
||||
var $renameTable = 'ALTER TABLE %s RENAME TO %s'; // at least since 7.1
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'TEXT';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'TEXT';
|
||||
|
||||
case 'B': return 'BYTEA';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'TIMESTAMP';
|
||||
|
||||
case 'L': return 'BOOLEAN';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'INT2';
|
||||
case 'I4': return 'INT4';
|
||||
case 'I8': return 'INT8';
|
||||
|
||||
case 'F': return 'FLOAT8';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (($not_null = preg_match('/NOT NULL/i',$v))) {
|
||||
$v = preg_replace('/NOT NULL/i','',$v);
|
||||
}
|
||||
if (preg_match('/^([^ ]+) .*(DEFAULT [^ ]+)/',$v,$matches)) {
|
||||
list(,$colname,$default) = $matches;
|
||||
$sql[] = $alter . str_replace($default,'',$v);
|
||||
$sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET ' . $default;
|
||||
} else {
|
||||
$sql[] = $alter . $v;
|
||||
}
|
||||
if ($not_null) {
|
||||
list($colname) = explode(' ',$v);
|
||||
$sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL';
|
||||
}
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
|
||||
{
|
||||
if (!$tableflds) {
|
||||
if ($this->debug) $this->outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
|
||||
return array();
|
||||
}
|
||||
return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions);
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
|
||||
{
|
||||
$has_drop_column = 7.3 <= (float) @$this->serverInfo['version'];
|
||||
if (!$has_drop_column && !$tableflds) {
|
||||
if ($this->debug) $this->outp("DropColumnSQL needs complete table-definiton for PostgreSQL < 7.3");
|
||||
return array();
|
||||
}
|
||||
if ($has_drop_column) {
|
||||
return ADODB_DataDict::DropColumnSQL($tabname, $flds);
|
||||
}
|
||||
return $this->_recreate_copy_table($tabname,$flds,$tableflds,$tableoptions);
|
||||
}
|
||||
|
||||
function DropTableSQL($tabname)
|
||||
{
|
||||
$sql = ADODB_DataDict::DropTableSQL($tabname);
|
||||
$drop_seq = $this->_DropAutoIncrement($tabname);
|
||||
if ($drop_seq) $sql[] = $drop_seq;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
if ($fautoinc) {
|
||||
$ftype = 'SERIAL';
|
||||
return '';
|
||||
}
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
function _DropAutoIncrement($tabname)
|
||||
{
|
||||
$tabname = $this->connection->qstr('%'.$tabname.'%');
|
||||
|
||||
$seq = $this->connection->GetOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'");
|
||||
|
||||
// check if a tables depends on the sequenz and it therefor cant and dont need to be droped separatly
|
||||
if (!$seq || $this->connection->GetOne("SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) {
|
||||
return False;
|
||||
}
|
||||
return "DROP SEQUENCE ".$seq;
|
||||
}
|
||||
|
||||
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
|
||||
{
|
||||
$sql = array();
|
||||
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
|
||||
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
|
||||
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['HASH']))
|
||||
$s .= 'USING HASH ';
|
||||
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
|
||||
if ( is_array($flds) )
|
||||
$flds = implode(', ',$flds);
|
||||
$s .= '(' . $flds . ')';
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
||||
function _recreate_copy_table($tabname,$dropflds,$tableflds,$tableoptions='')
|
||||
{
|
||||
if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds);
|
||||
$copyflds = array();
|
||||
foreach($this->MetaColumns($tabname) as $fld) {
|
||||
if (!$dropflds || !in_array($fld->name,$dropflds)) {
|
||||
// we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one
|
||||
if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) &&
|
||||
in_array($fld->type,array('varchar','char','text','bytea'))) {
|
||||
$copyflds[] = "to_number($fld->name,'S99D99')";
|
||||
} else {
|
||||
$copyflds[] = $fld->name;
|
||||
}
|
||||
// identify the sequence name and the fld its on
|
||||
if ($fld->primary_key && $fld->has_default &&
|
||||
preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) {
|
||||
$seq_name = $matches[1];
|
||||
$seq_fld = $fld->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
$copyflds = implode(', ',$copyflds);
|
||||
|
||||
$tempname = $tabname.'_tmp';
|
||||
$aSql[] = 'BEGIN'; // we use a transaction, to make sure not to loose the content of the table
|
||||
$aSql[] = "SELECT * INTO TEMPORARY TABLE $tempname FROM $tabname";
|
||||
$aSql = array_merge($aSql,$this->DropTableSQL($tabname));
|
||||
$aSql = array_merge($aSql,$this->CreateTableSQL($tabname,$tableflds,$tableoptions));
|
||||
$aSql[] = "INSERT INTO $tabname SELECT $copyflds FROM $tempname";
|
||||
if ($seq_name && $seq_fld) { // if we have a sequence we need to set it again
|
||||
$seq_name = $tabname.'_'.$seq_fld.'_seq'; // has to be the name of the new implicit sequence
|
||||
$aSql[] = "SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname";
|
||||
}
|
||||
$aSql[] = "DROP TABLE $tempname";
|
||||
// recreate the indexes, if they not contain one of the droped columns
|
||||
foreach($this->MetaIndexes($tabname) as $idx_name => $idx_data)
|
||||
{
|
||||
if (substr($idx_name,-5) != '_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data['columns'])))) {
|
||||
$aSql = array_merge($aSql,$this->CreateIndexSQL($idx_name,$tabname,$idx_data['columns'],
|
||||
$idx_data['unique'] ? array('UNIQUE') : False));
|
||||
}
|
||||
}
|
||||
$aSql[] = 'COMMIT';
|
||||
return $aSql;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,316 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Date Module for Postgres 64
|
||||
*
|
||||
*/
|
||||
|
||||
if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
|
||||
|
||||
@include(ADODB_DIR . '/adodb-time.inc.php');
|
||||
|
||||
eval('class postgres64_date_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class postgres64_date_ADOConnection extends postgres64_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'"; // used by DBTimeStamp as the default timestamp fmt.
|
||||
var $emptyDate = ' ';
|
||||
var $emptyTimeStamp = ' ';
|
||||
var $sysDate = "CURRENT_DATE";
|
||||
var $sysTimeStamp = "CURRENT_TIMESTAMP";
|
||||
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));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction, $date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
else if (strncmp($date,"'",1) == 0) {
|
||||
$len = strlen($date);
|
||||
if (10 <= $len && $len <= 12)
|
||||
$date = 'date ' . $date;
|
||||
else $date = 'timestamp ' . $date;
|
||||
}
|
||||
return "($date+interval'$dayFraction days')";
|
||||
}
|
||||
|
||||
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'";
|
||||
|
||||
$timestamp = $this->UnixTimeStamp($timestamp);
|
||||
return adodb_date($this->fmtTimeStamp, $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]);
|
||||
else 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;
|
||||
else return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col)
|
||||
$col = $this->sysTimeStamp;
|
||||
|
||||
$s = 'TO_CHAR('.$col.",'";
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= 'YYYY';
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= 'Q';
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
$s .= 'Mon';
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
$s .= 'MM';
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= 'DD';
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s.= 'HH24';
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
$s .= 'HH';
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= 'MI';
|
||||
break;
|
||||
|
||||
case 's':
|
||||
$s .= 'SS';
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= 'AM';
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
$s .= 'D';
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
$s .= 'DAY';
|
||||
break;
|
||||
|
||||
default:
|
||||
// handle escape characters...
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
if (strpos('-/.:;, ',$ch) !== false)
|
||||
$s .= $ch;
|
||||
else $s .= '"'.$ch.'"';
|
||||
}
|
||||
}
|
||||
return $s. "')";
|
||||
}
|
||||
}
|
||||
|
||||
eval('class postgres64_date_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class postgres64_date_ResultSet extends postgres64_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 postgres64_date_ADOConnection::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return postgres64_date_ADOConnection::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,654 @@
|
|||
<?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 postgres64_driver_ADOConnection extends ADOConnection
|
||||
{
|
||||
var $connect_string;
|
||||
var $sysDate = "CURRENT_DATE";
|
||||
var $sysTimeStamp = "CURRENT_TIMESTAMP";
|
||||
|
||||
function postgres64_driver_ADOConnection()
|
||||
{
|
||||
$this->dbtype = 'postgres64';
|
||||
$this->dataProvider = 'postgres';
|
||||
}
|
||||
|
||||
/**
|
||||
* Connection to database server and selected database
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _connect($host = "", $username = "", $password = "", $database = "", $persistent, $forcenew)
|
||||
{
|
||||
if (!function_exists('pg_connect')) return false;
|
||||
|
||||
$this->host = $host;
|
||||
$this->username = $this->query_addslashes($username);
|
||||
$this->password = $this->query_addslashes($password);
|
||||
if (strlen($database) == 0) $database = 'template1';
|
||||
$this->database = $this->query_addslashes($database);
|
||||
|
||||
if ($this->username || $this->password || $this->database) {
|
||||
$this->connect_string = $this->host;
|
||||
if ($this->connect_string) {
|
||||
$host = split(":", $this->connect_string);
|
||||
if ($host[0]) $this->connect_string = "host=" . $this->query_addslashes($host[0]);
|
||||
else $this->connect_string = 'host=localhost';
|
||||
if (isset($host[1])) $this->connect_string .= " port=$host[1]";
|
||||
else if (!empty($this->port)) $this->connect_string .= " port=" . $this->port;
|
||||
}
|
||||
if ($this->username) $this->connect_string .= " user=" . $this->username;
|
||||
if ($this->password) $this->connect_string .= " password=" . $this->password;
|
||||
if ($this->database) $this->connect_string .= " dbname=" . $this->database;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connect_string = $this->host;
|
||||
}
|
||||
|
||||
$this->persistent = $persistent;
|
||||
$this->forcenewconnection = $forcenew;
|
||||
|
||||
$this->_makeconnection();
|
||||
|
||||
if ($this->connectionId === false)
|
||||
{
|
||||
if ($fn = $this->raiseErrorFn)
|
||||
$fn($this->dbtype, 'CONNECT', $this->ErrorNo(), $this->ErrorMsg(), $this->host, $this->database, $this);
|
||||
return $this->SelectDB( $this->database );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function _makeconnection()
|
||||
{
|
||||
if($this->persistent == 1)
|
||||
{
|
||||
$this->connectionId = @pg_pconnect( $this->connect_string );
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!$this->forcenewconnection)
|
||||
{
|
||||
$this->connectionId = @pg_connect( $this->connect_string );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->connectionId = @pg_connect( $this->connect_string, PGSQL_CONNECT_FORCE_NEW );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function query_addslashes($query)
|
||||
{
|
||||
$len = strlen($query);
|
||||
if ($len == 0)
|
||||
return "''";
|
||||
if (strncmp($query,"'",1) === 0 && substr($query,$len-1) == "'")
|
||||
return $s;
|
||||
return "'".addslashes($query)."'";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if($this->createdatabase == true)
|
||||
{
|
||||
$this->connectionId = @pg_pconnect( "host=$this->host user=$this->username password=$this->password" );
|
||||
$result = @pg_query($this->connectionId, "CREATE DATABASE " . $this->database );
|
||||
if ($result === false) { // error handling if query fails
|
||||
$this->connectionId = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_makeconnection();
|
||||
if($this->connectionId === false)
|
||||
{
|
||||
$this->connectionId = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$this->connectionId = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error message
|
||||
* Usage: $errormessage =& $db->ErrorMsg();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
return @pg_last_error($this->connectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return database error number
|
||||
* Usage: $errorbo =& $db->ErrorNo();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
$error = @pg_last_error( $this->connectionId );
|
||||
return strlen($error) ? $error : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns # of affected rows from insert/delete/update query
|
||||
*
|
||||
* @access public
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return @pg_affected_rows($this->record_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last record id of an inserted item
|
||||
* Usage: $db->Insert_ID();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Insert_ID()
|
||||
{
|
||||
return @pg_getlastoid($this->record_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
$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();
|
||||
return implode("||", $arr);
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " coalesce($field, $ifNull) ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
* Usage: $db->close();
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
|
||||
function Close()
|
||||
{
|
||||
@pg_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 != -1 || $nrows != -1)
|
||||
// {
|
||||
// $offset = ($offset>=0) ? $offset . "," : '';
|
||||
// $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 ? "'t'" : "'f'";
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @pg_query( $this->sql );
|
||||
$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);
|
||||
}
|
||||
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;
|
||||
$time_start = array_sum(explode(' ', microtime()));
|
||||
$this->query_count++;
|
||||
$resultId = @pg_query( $this->sql);
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
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 (@pg_numfields( $resultId ) <= 0) { // return simplified recordset for inserts/updates/deletes with lower overhead
|
||||
$recordset = new ADORecordSet_empty();
|
||||
$this->record_set = $recordset;
|
||||
return $recordset;
|
||||
}
|
||||
|
||||
$resultset_name = $this->last_module_name . "_ResultSet";
|
||||
$recordset = new $resultset_name( $resultId, $this->connectionId );
|
||||
$this->record_set = $recordset;
|
||||
|
||||
$recordset->_currentRow = 0;
|
||||
|
||||
switch ($ADODB_FETCH_MODE)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $recordset->fetchMode = PGSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$recordset->fetchMode = PGSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$recordset->fetchMode = PGSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$recordset->_numOfRows = @pg_numrows( $resultId );
|
||||
if( $recordset->_numOfRows == 0)
|
||||
{
|
||||
$recordset->EOF = true;
|
||||
}
|
||||
$recordset->_numOfFields = @pg_numfields( $resultId );
|
||||
$recordset->_fetch();
|
||||
|
||||
return $recordset;
|
||||
}
|
||||
}
|
||||
|
||||
class postgres64_driver_ResultSet
|
||||
{
|
||||
var $connectionId;
|
||||
var $fields;
|
||||
var $resultId;
|
||||
var $_currentRow = 0;
|
||||
var $_numOfRows = -1;
|
||||
var $_numOfFields = -1;
|
||||
var $fetchMode;
|
||||
var $EOF;
|
||||
|
||||
/**
|
||||
* pgsqlResultSet Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $record
|
||||
* @param string $resultId
|
||||
*/
|
||||
|
||||
function postgres64_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()
|
||||
{
|
||||
pg_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 = pg_fetch_array($this->resultId, NULL, $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 @pg_result_seek($this->resultId,$row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills field array with first database element when query initially executed
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @pg_fetch_array($this->resultId, NULL, $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)
|
||||
{
|
||||
$fieldObject= new ADOFieldObject();
|
||||
$fieldObject->name = @pg_fieldname($this->resultId, $fieldOffset);
|
||||
$fieldObject->type = @pg_fieldtype($this->resultId, $fieldOffset);
|
||||
$fieldObject->max_length = @pg_fieldsize($this->resultId, $fieldOffset);
|
||||
return $fieldObject;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Extend Module for Mysqlt
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class postgres64_extend_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class postgres64_extend_ADOConnection extends postgres64_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 $_genIDSQL = "SELECT NEXTVAL('%s')";
|
||||
var $_genSeqSQL = "CREATE SEQUENCE %s START %s";
|
||||
var $_dropSeqSQL = "DROP SEQUENCE %s";
|
||||
var $genID = 0;
|
||||
|
||||
function GenID($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
$getnext = sprintf($this->_genIDSQL, $seqname);
|
||||
$holdtransOK = $this->transaction_status;
|
||||
$save_handler = $this->raiseErrorFn;
|
||||
$this->raiseErrorFn = '';
|
||||
@($result = $this->Execute($getnext));
|
||||
$this->raiseErrorFn = $save_handler;
|
||||
|
||||
if (!$result) {
|
||||
$this->transaction_status = $holdtransOK;
|
||||
$createseq = $this->Execute(sprintf($this->_genSeqSQL, $seqname, $startID));
|
||||
$result = $this->Execute($getnext);
|
||||
}
|
||||
if ($result && !$result->EOF)
|
||||
$this->genID = reset($result->fields);
|
||||
else $this->genID = 0;
|
||||
|
||||
if ($result)
|
||||
$result->Close();
|
||||
|
||||
return $this->genID;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq', $startID=1)
|
||||
{
|
||||
return $this->Execute(sprintf($this->_genSeqSQL, $seqname, $startID));
|
||||
}
|
||||
|
||||
function DropSequence($seqname='adodbseq')
|
||||
{
|
||||
return $this->Execute(sprintf($this->_dropSeqSQL, $seqname));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class postgres64_extend_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class postgres64_extend_ResultSet extends postgres64_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,684 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Meta Module for Postgres64
|
||||
*
|
||||
* 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 postgres64_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class postgres64_meta_ADOConnection extends postgres64_meta_EXTENDER
|
||||
{
|
||||
var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
|
||||
var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
|
||||
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
|
||||
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname not like 'pg\_%'";
|
||||
var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
|
||||
FROM pg_class c, pg_attribute a,pg_type t
|
||||
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
|
||||
AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
|
||||
|
||||
// used when schema defined
|
||||
var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
|
||||
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
|
||||
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
|
||||
and c.relnamespace=n.oid and n.nspname='%s'
|
||||
and a.attname not like '....%%' AND a.attnum > 0
|
||||
AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
|
||||
|
||||
// get primary key etc -- from Freek Dijkstra
|
||||
var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
|
||||
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
|
||||
var $metaDefaultsSQL = "SELECT d.adnum as num, d.adsrc as def from pg_attrdef d, pg_class c where d.adrelid=c.oid and c.relname='%s' order by d.adnum";
|
||||
|
||||
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)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->metaDatabasesSQL) {
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$arr = $this->GetCol($this->metaDatabasesSQL);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
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($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
$info = $this->ServerInfo();
|
||||
if ($info['version'] >= 7.3) {
|
||||
$this->metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
|
||||
and schemaname not in ( 'pg_catalog','information_schema')
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema') ";
|
||||
}
|
||||
if ($mask) {
|
||||
$save = $this->metaTablesSQL;
|
||||
$mask = $this->qstr(strtolower($mask));
|
||||
if ($info['version']>=7.3)
|
||||
$this->metaTablesSQL = "
|
||||
select tablename,'T' from pg_tables where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema')
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname like $mask and schemaname not in ( 'pg_catalog','information_schema') ";
|
||||
else
|
||||
$this->metaTablesSQL = "
|
||||
select tablename,'T' from pg_tables where tablename like $mask
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname like $mask";
|
||||
}
|
||||
$ret =& $this->_MetaTables($ttype,$showSchema);
|
||||
|
||||
if ($mask) {
|
||||
$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,$normalize=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = false;
|
||||
$false = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
if ($normalize) $table = strtolower($table);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
|
||||
else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rs === false) {
|
||||
return $false;
|
||||
}
|
||||
if (!empty($this->metaKeySQL)) {
|
||||
// If we want the primary keys, we have to issue a separate query
|
||||
// Of course, a modified version of the metaColumnsSQL query using a
|
||||
// LEFT JOIN would have been much more elegant, but postgres does
|
||||
// not support OUTER JOINS. So here is the clumsy way.
|
||||
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
|
||||
$rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
|
||||
// fetch all result in once for performance.
|
||||
$keys =& $rskey->GetArray();
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
$rskey->Close();
|
||||
unset($rskey);
|
||||
}
|
||||
|
||||
$rsdefa = array();
|
||||
if (!empty($this->metaDefaultsSQL)) {
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
$sql = sprintf($this->metaDefaultsSQL, ($table));
|
||||
$rsdef = $this->Execute($sql);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rsdef) {
|
||||
while (!$rsdef->EOF) {
|
||||
$num = $rsdef->fields['num'];
|
||||
$s = $rsdef->fields['def'];
|
||||
if (strpos($s,'::')===false && substr($s, 0, 1) == "'") { /* quoted strings hack... for now... fixme */
|
||||
$s = substr($s, 1);
|
||||
$s = substr($s, 0, strlen($s) - 1);
|
||||
}
|
||||
|
||||
$rsdefa[$num] = $s;
|
||||
$rsdef->MoveNext();
|
||||
}
|
||||
} else {
|
||||
ADOConnection::outp( "==> SQL => " . $sql);
|
||||
}
|
||||
unset($rsdef);
|
||||
}
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) {
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
$fld->max_length = $rs->fields[2];
|
||||
$fld->attnum = $rs->fields[6];
|
||||
|
||||
if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4;
|
||||
if ($fld->max_length <= 0) $fld->max_length = -1;
|
||||
if ($fld->type == 'numeric') {
|
||||
$fld->scale = $fld->max_length & 0xFFFF;
|
||||
$fld->max_length >>= 16;
|
||||
}
|
||||
// dannym
|
||||
// 5 hasdefault; 6 num-of-column
|
||||
$fld->has_default = ($rs->fields[5] == 't');
|
||||
if ($fld->has_default) {
|
||||
$fld->default_value = $rsdefa[$rs->fields[6]];
|
||||
}
|
||||
|
||||
//Freek
|
||||
$fld->not_null = $rs->fields[4] == 't';
|
||||
|
||||
|
||||
// Freek
|
||||
if (is_array($keys)) {
|
||||
foreach($keys as $key) {
|
||||
if ($fld->name == $key['column_name'] AND $key['primary_key'] == 't')
|
||||
$fld->primary_key = true;
|
||||
if ($fld->name == $key['column_name'] AND $key['unique_key'] == 't')
|
||||
$fld->unique = true; // What name is more compatible?
|
||||
}
|
||||
}
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[($normalize) ? strtoupper($fld->name) : $fld->name] = $fld;
|
||||
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
if (empty($retarr))
|
||||
return $false;
|
||||
else
|
||||
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)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
|
||||
$sql = '
|
||||
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
|
||||
FROM pg_catalog.pg_class c
|
||||
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
|
||||
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
|
||||
,pg_namespace n
|
||||
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\')) and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\'';
|
||||
} else {
|
||||
$sql = '
|
||||
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
|
||||
FROM pg_catalog.pg_class c
|
||||
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
|
||||
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
|
||||
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
|
||||
}
|
||||
|
||||
if ($primary == FALSE) {
|
||||
$sql .= ' AND i.indisprimary=false;';
|
||||
}
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== FALSE) {
|
||||
$savem = $this->SetFetchMode(FALSE);
|
||||
}
|
||||
|
||||
$rs = $this->Execute(sprintf($sql,$table,$table,$schema));
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!is_object($rs)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
|
||||
$col_names = $this->MetaColumnNames($table,true,true);
|
||||
//3rd param is use attnum,
|
||||
// see http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976
|
||||
$indexes = array();
|
||||
while ($row = $rs->FetchRow()) {
|
||||
$columns = array();
|
||||
foreach (explode(' ', $row[2]) as $col) {
|
||||
$columns[] = $col_names[$col];
|
||||
}
|
||||
|
||||
$indexes[$row[0]] = array(
|
||||
'unique' => ($row[1] == 't'),
|
||||
'columns' => $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,$useattnum=false /* only for postgres */)
|
||||
{
|
||||
$objarr =& $this->MetaColumns($table);
|
||||
if (!is_array($objarr)) {
|
||||
$false = false;
|
||||
return $false;
|
||||
}
|
||||
$arr = array();
|
||||
if ($numIndexes) {
|
||||
$i = 0;
|
||||
if ($useattnum) {
|
||||
foreach($objarr as $v)
|
||||
$arr[$v->attnum] = $v->name;
|
||||
|
||||
} else
|
||||
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 postgres64_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class postgres64_meta_ResultSet extends postgres64_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;
|
||||
}
|
||||
$is_serial = is_object($fieldobj) && $fieldobj->primary_key && $fieldobj->unique && $fieldobj->has_default && substr($fieldobj->default_value,0,8) == 'nextval(';
|
||||
switch (strtoupper($t)) {
|
||||
case 'MONEY': // stupid, postgres expects money to be a string
|
||||
case 'INTERVAL':
|
||||
case 'CHAR':
|
||||
case 'CHARACTER':
|
||||
case 'VARCHAR':
|
||||
case 'NAME':
|
||||
case 'BPCHAR':
|
||||
case '_VARCHAR':
|
||||
case 'INET':
|
||||
case 'MACADDR':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
case 'TEXT':
|
||||
return 'X';
|
||||
case 'IMAGE': // user defined type
|
||||
case 'BLOB': // user defined type
|
||||
case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
|
||||
case 'VARBIT':
|
||||
case 'BYTEA':
|
||||
return 'B';
|
||||
case 'BOOL':
|
||||
case 'BOOLEAN':
|
||||
return 'L';
|
||||
case 'DATE':
|
||||
return 'D';
|
||||
case 'TIMESTAMP WITHOUT TIME ZONE':
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP':
|
||||
case 'TIMESTAMPTZ':
|
||||
return 'T';
|
||||
case 'INTEGER': return !$is_serial ? 'I' : 'R';
|
||||
case 'SMALLINT':
|
||||
case 'INT2': return !$is_serial ? 'I2' : 'R';
|
||||
case 'INT4': return !$is_serial ? 'I4' : 'R';
|
||||
case 'BIGINT':
|
||||
case 'INT8': return !$is_serial ? 'I8' : 'R';
|
||||
case 'OID':
|
||||
case 'SERIAL':
|
||||
return 'R';
|
||||
case 'FLOAT4':
|
||||
case 'FLOAT8':
|
||||
case 'DOUBLE PRECISION':
|
||||
case 'REAL':
|
||||
return 'F';
|
||||
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';
|
||||
if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
|
||||
return $tmap;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
/**
|
||||
* ADOdb Lite Transaction Module for Postgres
|
||||
*
|
||||
*/
|
||||
|
||||
eval('class postgres64_transaction_EXTENDER extends '. $last_module . '_ADOConnection { }');
|
||||
|
||||
class postgres64_transaction_ADOConnection extends postgres64_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()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt += 1;
|
||||
return @pg_Exec($this->connectionId, "begin");
|
||||
}
|
||||
|
||||
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->RollbackTrans();
|
||||
if ($this->debug)
|
||||
ADOCOnnection::outp("Smart Rollback occurred");
|
||||
}
|
||||
return $this->transaction_status;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
if (!$ok)
|
||||
return $this->RollbackTrans();
|
||||
|
||||
$this->transCnt -= 1;
|
||||
return @pg_Exec($this->connectionId, "commit");
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff)
|
||||
return true;
|
||||
|
||||
$this->transCnt -= 1;
|
||||
return @pg_Exec($this->connectionId, "rollback");
|
||||
}
|
||||
|
||||
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($tables,$where,$flds='1 as ignore')
|
||||
{
|
||||
if (!$this->transCnt)
|
||||
$this->BeginTrans();
|
||||
|
||||
return $this->GetOne("select $flds from $tables where $where for update");
|
||||
}
|
||||
|
||||
function CommitLock($table)
|
||||
{
|
||||
return $this->CommitTrans();
|
||||
}
|
||||
|
||||
function RollbackLock($table)
|
||||
{
|
||||
return $this->RollbackTrans();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
eval('class postgres64_transaction_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
|
||||
|
||||
class postgres64_transaction_ResultSet extends postgres64_transaction_resultset_EXTENDER
|
||||
{
|
||||
}
|
||||
?>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue