Added code for test website. Including:

* Smarty 2.6.19

* ASOdb Lite 1.42
This commit is contained in:
Pauli Nieminen 2008-08-08 17:21:38 +00:00
parent bb78154265
commit 36d7c8e39e
312 changed files with 73558 additions and 0 deletions

1
utils/tests/autotester/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
run_unit_tests.sh

View 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());
?>

View 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
View file

@ -0,0 +1 @@
config.php

View 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());
}
}
?>

View 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()
{
}
}
?>

View 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();
}
}
?>

View 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');
}
}
?>

View 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');
}
}
?>

View 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;
}
}
?>

View 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;
}
}
?>

View 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;
}
}
?>

View 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&apos;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();
}
}
}
?>

View 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';
}
}
?>

View 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;
}
}
?>

View 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;
}
?>

View file

@ -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);
}
?>

View file

@ -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;
}
?>

View file

@ -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);
}
?>

View 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]).' &nbsp; '.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&amp;exps=1&amp;sql=".$raw."&amp;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&amp;expe=1&amp;sql=" . $raw . "&amp;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 = "&nbsp;";
}
$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> &nbsp; <a href=\"?do=viewsql\"><strong>View SQL</strong></a>&nbsp; <a href=\"?do=tables\"><strong>View Tables</strong></a> &nbsp; <a href=\"?do=poll\"><strong>Poll Stats</strong></a>",
$allowsql ? ' &nbsp; <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 "&nbsp; <a href=\"?do=viewsql&amp;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> &nbsp;</td></tr>";
continue;
}
if (!is_array($arr)) break;
$category = $arr[0];
$how = $arr[1];
if (sizeof($arr)>2) $desc = $arr[2];
else $desc = ' &nbsp; ';
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 = '&nbsp;';
if (strlen($val)==0) $val = '&nbsp;';
if ($cli)
{
$html .= str_replace('&nbsp;','',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=" &lt; " name="SMALLER" /><input type="submit" value=" &gt; &gt; " 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>&nbsp;</td></tr></table>";
rs2html($rs);
}
}
else
{
$e1 = (integer) $this->ErrorNo();
$e2 = $this->ErrorMsg();
if (($e1) || ($e2))
{
if (empty($e1)) $e1 = '-1'; // postgresql fix
print ' &nbsp; '.$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;
}
}
?>

View 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;
}
}
?>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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";
?>

View 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="";
}
?>

View file

@ -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();
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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;
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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 { }
?>

View file

@ -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;
}
}
?>

View file

@ -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';
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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();
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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();
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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);
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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);
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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;
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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';
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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;
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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
}
?>

View file

@ -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
{
}
?>

View file

@ -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;
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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';
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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();
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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;
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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
{
}
?>

View file

@ -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;
}
}
?>

View file

@ -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 = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
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 = '&nbsp;'; /// what to display when $time==0
var $emptyDate = '&nbsp;'; /// 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);
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
?>

View file

@ -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;
}
}
}
?>

View file

@ -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