MDL-71011 adodb: Bump to v5.21.0

Following the instructions @ readme_moodle.txt
This commit is contained in:
Eloy Lafuente (stronk7) 2021-03-27 17:56:57 +01:00
parent 18aafd0ed4
commit 91969d1e04
111 changed files with 9763 additions and 4252 deletions

View file

@ -10,7 +10,7 @@ In plain English, you do not need to distribute your application in source code
nor do you need to distribute ADOdb source code, provided you follow the rest of
terms of the BSD license.
For more information about ADOdb, visit http://adodb.org/
For more information about ADOdb, visit https://adodb.org/
BSD 3-Clause License
--------------------

View file

@ -1,4 +1,4 @@
ADOdb Library for PHP5
ADOdb Library for PHP
======================
[![Join chat on Gitter](https://img.shields.io/gitter/room/form-data/form-data.svg)](https://gitter.im/adodb/adodb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@ -16,7 +16,7 @@ or, at your option, any later version.
This means you can use it in proprietary products;
see [License](https://github.com/ADOdb/ADOdb/blob/master/LICENSE.md) for details.
Home page: http://adodb.org/
Home page: https://adodb.org/
Introduction
@ -27,8 +27,8 @@ need for a database class library to hide the differences between the
different databases (encapsulate the differences) so we can easily
switch databases.
The library currently supports MySQL, Interbase, Sybase, PostgreSQL, Oracle,
Microsoft SQL server, Foxpro ODBC, Access ODBC, Informix, DB2,
The library currently supports MySQL, Firebird & Interbase, PostgreSQL, SQLite3, Oracle,
Microsoft SQL Server, Foxpro ODBC, Access ODBC, Informix, DB2, Sybase,
Sybase SQL Anywhere, generic ODBC and Microsoft's ADO.
We hope more people will contribute drivers to support other databases.
@ -48,12 +48,12 @@ You can debug using:
<?php
include('adodb/adodb.inc.php');
$db = ADONewConnection($driver); # eg. 'mysql' or 'oci8'
$db = adoNewConnection($driver); # eg. 'mysqli' or 'oci8'
$db->debug = true;
$db->Connect($server, $user, $password, $database);
$rs = $db->Execute('select * from some_small_table');
$db->connect($server, $user, $password, $database);
$rs = $db->execute('select * from some_small_table');
print "<pre>";
print_r($rs->GetRows());
print_r($rs->getRows());
print "</pre>";
```
@ -61,14 +61,14 @@ print "</pre>";
Documentation and Examples
==========================
Refer to the [ADOdb website](http://adodb.org/) for library documentation and examples. The documentation can also be [downloaded for offline viewing](https://sourceforge.net/projects/adodb/files/Documentation/).
Refer to the [ADOdb website](https://adodb.org/) for library documentation and examples. The documentation can also be [downloaded for offline viewing](https://sourceforge.net/projects/adodb/files/Documentation/).
- [Main documentation](http://adodb.org/dokuwiki/doku.php?id=v5:userguide:userguide_index): Query, update and insert records using a portable API.
- [Data dictionary](http://adodb.org/dokuwiki/doku.php?id=v5:dictionary:dictionary_index) describes how to create database tables and indexes in a portable manner.
- [Database performance monitoring](http://adodb.org/dokuwiki/doku.php?id=v5:performance:performance_index) allows you to perform health checks, tune and monitor your database.
- [Database-backed sessions](http://adodb.org/dokuwiki/doku.php?id=v5:session:session_index).
- [Main documentation](https://adodb.org/dokuwiki/doku.php?id=v5:userguide:userguide_index): Query, update and insert records using a portable API.
- [Data dictionary](https://adodb.org/dokuwiki/doku.php?id=v5:dictionary:dictionary_index) describes how to create database tables and indexes in a portable manner.
- [Database performance monitoring](https://adodb.org/dokuwiki/doku.php?id=v5:performance:performance_index) allows you to perform health checks, tune and monitor your database.
- [Database-backed sessions](https://adodb.org/dokuwiki/doku.php?id=v5:session:session_index).
There is also a [tutorial](http://adodb.org/dokuwiki/doku.php?id=v5:userguide:mysql_tutorial) that contrasts ADOdb code with PHP native MySQL code.
There is also a [tutorial](https://adodb.org/dokuwiki/doku.php?id=v5:userguide:mysql_tutorial) that contrasts ADOdb code with PHP native MySQL code.
Files
@ -96,7 +96,6 @@ https://github.com/ADOdb/ADOdb/issues
You may also find legacy issues in
- the old [ADOdb forums](http://phplens.com/lens/lensforum/topics.php?id=4) on phplens.com
- the [SourceForge tickets section](http://sourceforge.net/p/adodb/_list/tickets)
However, please note that they are not actively monitored and should

View file

@ -1,10 +1,10 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@ -46,22 +46,16 @@ class ADODB_Active_Table {
// $db = database connection
// $index = name of index - can be associative, for an example see
// http://phplens.com/lens/lensforum/msgs.php?id=17790
// PHPLens Issue No: 17790
// returns index into $_ADODB_ACTIVE_DBS
function ADODB_SetDatabaseAdapter(&$db, $index=false)
{
global $_ADODB_ACTIVE_DBS;
foreach($_ADODB_ACTIVE_DBS as $k => $d) {
if (PHP_VERSION >= 5) {
if($d->db === $db) {
return $k;
}
} else {
if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database) {
return $k;
}
}
}
$obj = new ADODB_Active_DB();
@ -80,6 +74,9 @@ function ADODB_SetDatabaseAdapter(&$db, $index=false)
class ADODB_Active_Record {
static $_changeNames = true; // dynamically pluralize table names
/*
* Optional parameter that duplicates the ADODB_QUOTE_FIELDNAMES
*/
static $_quoteNames = false;
static $_foreignSuffix = '_id'; //
@ -499,7 +496,6 @@ class ADODB_Active_Record {
break;
default:
foreach($cols as $name => $fldobj) {
$name = ($fldobj->name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value)) {
$this->$name = $fldobj->default_value;
@ -510,7 +506,7 @@ class ADODB_Active_Record {
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[$name] = $cols[$name]->name;
$keys[$name] = $cols[strtoupper($name)]->name;
}
break;
}
@ -522,7 +518,7 @@ class ADODB_Active_Record {
$activetab->_created = time();
$s = serialize($activetab);
if (!function_exists('adodb_write_file')) {
include(ADODB_DIR.'/adodb-csvlib.inc.php');
include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
}
adodb_write_file($fname,$s);
}
@ -700,9 +696,14 @@ class ADODB_Active_Record {
$val = false;
}
if (is_null($val) || $val === false) {
if (is_null($val) || $val === false)
{
$SQL = sprintf("SELECT MAX(%s) FROM %s",
$this->nameQuoter($db,$fieldname),
$this->nameQuoter($db,$this->_table)
);
// this might not work reliably in multi-user environment
return $db->GetOne("select max(".$fieldname.") from ".$this->_table);
return $db->GetOne($SQL);
}
return $val;
}
@ -749,10 +750,11 @@ class ADODB_Active_Record {
foreach($keys as $k) {
$f = $table->flds[$k];
if ($f) {
$parr[] = $k.' = '.$this->doquote($db,$this->$k,$db->MetaType($f->type));
$columnName = $this->nameQuoter($db,$k);
$parr[] = $columnName.' = '.$this->doquote($db,$this->$k,$db->MetaType($f->type));
}
}
return implode(' and ', $parr);
return implode(' AND ', $parr);
}
@ -788,7 +790,9 @@ class ADODB_Active_Record {
$savem = $db->SetFetchMode(false);
}
$qry = "select * from ".$this->_table;
$qry = sprintf("SELECT * FROM %s",
$this->nameQuoter($db,$this->_table)
);
if($where) {
$qry .= ' WHERE '.$where;
@ -813,7 +817,7 @@ class ADODB_Active_Record {
}
# useful for multiple record inserts
# see http://phplens.com/lens/lensforum/msgs.php?id=17795
# see PHPLens Issue No: 17795
function Reset()
{
$this->_where=null;
@ -862,7 +866,7 @@ class ADODB_Active_Record {
$val = $this->$name;
if(!is_array($val) || !is_null($val) || !array_key_exists($name, $table->keys)) {
$valarr[] = $val;
$names[] = $this->_QName($name,$db);
$names[] = $this->nameQuoter($db,$name);
$valstr[] = $db->Param($cnt);
$cnt += 1;
}
@ -871,12 +875,18 @@ class ADODB_Active_Record {
if (empty($names)){
foreach($table->flds as $name=>$fld) {
$valarr[] = null;
$names[] = $name;
$names[] = $this->nameQuoter($db,$name);
$valstr[] = $db->Param($cnt);
$cnt += 1;
}
}
$sql = 'INSERT INTO '.$this->_table."(".implode(',',$names).') VALUES ('.implode(',',$valstr).')';
$tableName = $this->nameQuoter($db,$this->_table);
$sql = sprintf('INSERT INTO %s (%s) VALUES (%s)',
$tableName,
implode(',',$names),
implode(',',$valstr)
);
$ok = $db->Execute($sql,$valarr);
if ($ok) {
@ -907,7 +917,14 @@ class ADODB_Active_Record {
$table = $this->TableInfo();
$where = $this->GenWhere($db,$table);
$sql = 'DELETE FROM '.$this->_table.' WHERE '.$where;
$tableName = $this->nameQuoter($db,$this->_table);
$sql = sprintf('DELETE FROM %s WHERE %s',
$tableName,
$where
);
$ok = $db->Execute($sql);
return $ok ? true : false;
@ -979,7 +996,19 @@ class ADODB_Active_Record {
break;
}
$ok = $db->Replace($this->_table,$arr,$pkey);
$newArr = array();
foreach($arr as $k=>$v)
$newArr[$this->nameQuoter($db,$k)] = $v;
$arr = $newArr;
$newPkey = array();
foreach($pkey as $k=>$v)
$newPkey[$k] = $this->nameQuoter($db,$v);
$pkey = $newPkey;
$tableName = $this->nameQuoter($db,$this->_table);
$ok = $db->Replace($tableName,$arr,$pkey);
if ($ok) {
$this->_saved = true; // 1= update 2=insert
if ($ok == 2) {
@ -1051,7 +1080,7 @@ class ADODB_Active_Record {
}
$valarr[] = $val;
$pairs[] = $this->_QName($name,$db).'='.$db->Param($cnt);
$pairs[] = $this->nameQuoter($db,$name).'='.$db->Param($cnt);
$cnt += 1;
}
@ -1060,7 +1089,13 @@ class ADODB_Active_Record {
return -1;
}
$sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where;
$tableName = $this->nameQuoter($db,$this->_table);
$sql = sprintf('UPDATE %s SET %s WHERE %s',
$tableName,
implode(',',$pairs),
$where);
$ok = $db->Execute($sql,$valarr);
if ($ok) {
$this->_original = $neworig;
@ -1078,6 +1113,66 @@ class ADODB_Active_Record {
return array_keys($table->flds);
}
/**
* Quotes the table and column and field names
*
* this honours the ADODB_QUOTE_FIELDNAMES directive. The routines that
* use it should really just call _adodb_getinsertsql and _adodb_getupdatesql
* which is a nice easy project if you are interested
*
* @param obj $db The database connection
* @param string $name The table or column name to quote
*
* @return string The quoted name
*/
final private function nameQuoter($db,$string)
{
global $ADODB_QUOTE_FIELDNAMES;
if (!$ADODB_QUOTE_FIELDNAMES && !$this->_quoteNames)
/*
* Nothing to be done
*/
return $string;
if ($this->_quoteNames == 'NONE')
/*
* Force no quoting when ADODB_QUOTE_FIELDNAMES is set
*/
return $string;
if ($this->_quoteNames)
/*
* Internal setting takes precedence
*/
$quoteMethod = $this->_quoteNames;
else
$quoteMethod = $ADODB_QUOTE_FIELDNAMES;
switch ($quoteMethod)
{
case 'LOWER':
$string = strtolower($string);
break;
case 'NATIVE':
/*
* Nothing to be done
*/
break;
case 'UPPER':
default:
$string = strtoupper($string);
}
$string = sprintf( '%s%s%s',
$db->nameQuote,
$string,
$db->nameQuote
);
return $string;
}
};
function adodb_GetActiveRecordsClass(&$db, $class, $table,$whereOrderBy,$bindarr, $primkeyArr,
@ -1087,6 +1182,7 @@ global $_ADODB_ACTIVE_DBS;
$save = $db->SetFetchMode(ADODB_FETCH_NUM);
$qry = "select * from ".$table;
if (!empty($whereOrderBy)) {
@ -1125,7 +1221,7 @@ global $_ADODB_ACTIVE_DBS;
// arrRef will be the structure that knows about our objects.
// It is an associative array.
// We will, however, return arr, preserving regular 0.. order so that
// obj[0] can be used by app developpers.
// obj[0] can be used by app developers.
$arrRef = array();
$bTos = array(); // Will store belongTo's indices if any
foreach($rows as $row) {

View file

@ -1,10 +1,10 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@ -67,15 +67,9 @@ function ADODB_SetDatabaseAdapter(&$db)
global $_ADODB_ACTIVE_DBS;
foreach($_ADODB_ACTIVE_DBS as $k => $d) {
if (PHP_VERSION >= 5) {
if ($d->db === $db) {
return $k;
}
} else {
if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database) {
return $k;
}
}
}
$obj = new ADODB_Active_DB();
@ -551,7 +545,7 @@ class ADODB_Active_Record {
$activetab->_created = time();
$s = serialize($activetab);
if (!function_exists('adodb_write_file')) {
include(ADODB_DIR.'/adodb-csvlib.inc.php');
include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
}
adodb_write_file($fname,$s);
}
@ -1298,7 +1292,7 @@ function adodb_GetActiveRecordsClass(&$db, $class, $tableObj,$whereOrderBy,$bind
if (!isset($_ADODB_ACTIVE_DBS)) {
include(ADODB_DIR.'/adodb-active-record.inc.php');
include_once(ADODB_DIR.'/adodb-active-record.inc.php');
}
if (!class_exists($class)) {
$db->outp_throw("Unknown class $class in GetActiveRecordsClass()",'GetActiveRecordsClass');
@ -1309,7 +1303,7 @@ function adodb_GetActiveRecordsClass(&$db, $class, $tableObj,$whereOrderBy,$bind
// arrRef will be the structure that knows about our objects.
// It is an associative array.
// We will, however, return arr, preserving regular 0.. order so that
// obj[0] can be used by app developpers.
// obj[0] can be used by app developers.
$arrRef = array();
$bTos = array(); // Will store belongTo's indices if any
foreach($rows as $row) {

View file

@ -8,7 +8,7 @@ $ADODB_INCLUDED_CSV = 1;
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -16,7 +16,7 @@ $ADODB_INCLUDED_CSV = 1;
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Library for CSV serialization. This is used by the csv/proxy driver and is the
CacheExecute() serialization format.
@ -27,7 +27,7 @@ $ADODB_INCLUDED_CSV = 1;
*
* @param rs the recordset
*
* @return the CSV formated data
* @return the CSV formatted data
*/
function _rs2serialize(&$rs,$conn=false,$sql='')
{
@ -85,7 +85,7 @@ $ADODB_INCLUDED_CSV = 1;
* @param err returns the error message
* @param timeout dispose if recordset has been alive for $timeout secs
*
* @return recordset, or false if error occured. If no
* @return recordset, or false if error occurred. If no
* error occurred in sql INSERT/UPDATE/DELETE,
* empty recordset is returned
*/
@ -245,10 +245,8 @@ $ADODB_INCLUDED_CSV = 1;
fclose($fp);
@$arr = unserialize($text);
//var_dump($arr);
if (!is_array($arr)) {
$err = "Recordset had unexpected EOF (in serialized recordset)";
if (get_magic_quotes_runtime()) $err .= ". Magic Quotes Runtime should be disabled!";
return $false;
}
$rs = new $rsclass();

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -22,11 +22,11 @@
// security - hide paths
if (!defined('ADODB_DIR')) die();
function Lens_ParseTest()
function lens_ParseTest()
{
$str = "`zcol ACOL` NUMBER(32,2) DEFAULT 'The \"cow\" (and Jim''s dog) jumps over the moon' PRIMARY, INTI INT AUTO DEFAULT 0, zcol2\"afs ds";
print "<p>$str</p>";
$a= Lens_ParseArgs($str);
$a= lens_ParseArgs($str);
print "<pre>";
print_r($a);
print "</pre>";
@ -53,7 +53,7 @@ if (!function_exists('ctype_alnum')) {
@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='_.-')
function lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
{
$pos = 0;
$intoken = false;
@ -179,45 +179,58 @@ class ADODB_DataDict {
var $serverInfo = array();
var $autoIncrement = false;
var $dataProvider;
var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql
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.
/// in other words, we use a text area for editing.
function GetCommentSQL($table,$col)
/*
* Indicates whether a BLOB/CLOB field will allow a NOT NULL setting
* The type is whatever is matched to an X or X2 or B type. We must
* explicitly set the value in the driver to switch the behaviour on
*/
public $blobAllowsNotNull;
/*
* Indicates whether a BLOB/CLOB field will allow a DEFAULT set
* The type is whatever is matched to an X or X2 or B type. We must
* explicitly set the value in the driver to switch the behaviour on
*/
public $blobAllowsDefaultValue;
function getCommentSQL($table,$col)
{
return false;
}
function SetCommentSQL($table,$col,$cmt)
function setCommentSQL($table,$col,$cmt)
{
return false;
}
function MetaTables()
function metaTables()
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaTables();
if (!$this->connection->isConnected()) return array();
return $this->connection->metaTables();
}
function MetaColumns($tab, $upper=true, $schema=false)
function metaColumns($tab, $upper=true, $schema=false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema);
if (!$this->connection->isConnected()) return array();
return $this->connection->metaColumns($this->tableName($tab), $upper, $schema);
}
function MetaPrimaryKeys($tab,$owner=false,$intkey=false)
function metaPrimaryKeys($tab,$owner=false,$intkey=false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey);
if (!$this->connection->isConnected()) return array();
return $this->connection->metaPrimaryKeys($this->tableName($tab), $owner, $intkey);
}
function MetaIndexes($table, $primary = false, $owner = false)
function metaIndexes($table, $primary = false, $owner = false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner);
if (!$this->connection->isConnected()) return array();
return $this->connection->metaIndexes($this->tableName($table), $primary, $owner);
}
function MetaType($t,$len=-1,$fieldobj=false)
function metaType($t,$len=-1,$fieldobj=false)
{
static $typeMap = array(
'VARCHAR' => 'C',
@ -323,15 +336,15 @@ class ADODB_DataDict {
"SQLBOOL" => 'L'
);
if (!$this->connection->IsConnected()) {
if (!$this->connection->isConnected()) {
$t = strtoupper($t);
if (isset($typeMap[$t])) return $typeMap[$t];
return 'N';
return ADODB_DEFAULT_METATYPE;
}
return $this->connection->MetaType($t,$len,$fieldobj);
return $this->connection->metaType($t,$len,$fieldobj);
}
function NameQuote($name = NULL,$allowBrackets=false)
function nameQuote($name = NULL,$allowBrackets=false)
{
if (!is_string($name)) {
return FALSE;
@ -360,16 +373,16 @@ class ADODB_DataDict {
return $name;
}
function TableName($name)
function tableName($name)
{
if ( $this->schema ) {
return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name);
return $this->nameQuote($this->schema) .'.'. $this->nameQuote($name);
}
return $this->NameQuote($name);
return $this->nameQuote($name);
}
// Executes the sql array returned by GetTableSQL and GetIndexSQL
function ExecuteSQLArray($sql, $continueOnError = true)
// Executes the sql array returned by getTableSQL and getIndexSQL
function executeSQLArray($sql, $continueOnError = true)
{
$rez = 2;
$conn = $this->connection;
@ -377,10 +390,10 @@ class ADODB_DataDict {
foreach($sql as $line) {
if ($this->debug) $conn->debug = true;
$ok = $conn->Execute($line);
$ok = $conn->execute($line);
$conn->debug = $saved;
if (!$ok) {
if ($this->debug) ADOConnection::outp($conn->ErrorMsg());
if ($this->debug) ADOConnection::outp($conn->errorMsg());
if (!$continueOnError) return 0;
$rez = 1;
}
@ -406,17 +419,17 @@ class ADODB_DataDict {
N: Numeric or decimal number
*/
function ActualType($meta)
function actualType($meta)
{
return $meta;
}
function CreateDatabase($dbname,$options=false)
function createDatabase($dbname,$options=false)
{
$options = $this->_Options($options);
$options = $this->_options($options);
$sql = array();
$s = 'CREATE DATABASE ' . $this->NameQuote($dbname);
$s = 'CREATE DATABASE ' . $this->nameQuote($dbname);
if (isset($options[$this->upperName]))
$s .= ' '.$options[$this->upperName];
@ -427,7 +440,7 @@ class ADODB_DataDict {
/*
Generates the SQL to create index. Returns an array of sql strings.
*/
function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false)
function createIndexSQL($idxname, $tabname, $flds, $idxoptions = false)
{
if (!is_array($flds)) {
$flds = explode(',',$flds);
@ -435,27 +448,27 @@ class ADODB_DataDict {
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);
$flds[$key] = $this->nameQuote($fld,$allowBrackets=true);
}
return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions));
return $this->_indexSQL($this->nameQuote($idxname), $this->tableName($tabname), $flds, $this->_options($idxoptions));
}
function DropIndexSQL ($idxname, $tabname = NULL)
function dropIndexSQL ($idxname, $tabname = NULL)
{
return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname)));
return array(sprintf($this->dropIndex, $this->nameQuote($idxname), $this->tableName($tabname)));
}
function SetSchema($schema)
function setSchema($schema)
{
$this->schema = $schema;
}
function AddColumnSQL($tabname, $flds)
function addColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$tabname = $this->tableName($tabname);
$sql = array();
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
list($lines,$pkey,$idxs) = $this->_genFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
@ -464,7 +477,7 @@ class ADODB_DataDict {
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql_idxs = $this->createIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
@ -474,19 +487,19 @@ class ADODB_DataDict {
/**
* 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
* As some DBMs can't do that on their own, you need to supply the complete definition 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 ''
* @param string $tableflds='' complete definition 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='')
function alterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
$tabname = $this->tableName($tabname);
$sql = array();
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
list($lines,$pkey,$idxs) = $this->_genFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
@ -495,7 +508,7 @@ class ADODB_DataDict {
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql_idxs = $this->createIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
@ -506,71 +519,71 @@ class ADODB_DataDict {
/**
* 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)
* Some DBMs 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=''
* @param string $flds='' complete column-definition-string like for addColumnSQL, only used by mysql atm., default=''
* @return array with SQL strings
*/
function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='')
function renameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='')
{
$tabname = $this->TableName ($tabname);
$tabname = $this->tableName($tabname);
if ($flds) {
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
list($lines,$pkey,$idxs) = $this->_genFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$first = current($lines);
list(,$column_def) = preg_split("/[\t ]+/",$first,2);
}
return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def));
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,
* Some DBM's can't do that on their own, you need to supply the complete definition 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 ''
* @param string $tableflds='' complete definition 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='')
function dropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
$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);
$sql[] = $alter . $this->nameQuote($v);
}
return $sql;
}
function DropTableSQL($tabname)
function dropTableSQL($tabname)
{
return array (sprintf($this->dropTable, $this->TableName($tabname)));
return array (sprintf($this->dropTable, $this->tableName($tabname)));
}
function RenameTableSQL($tabname,$newname)
function renameTableSQL($tabname,$newname)
{
return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($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=array())
function createTableSQL($tabname, $flds, $tableoptions=array())
{
list($lines,$pkey,$idxs) = $this->_GenFields($flds, true);
list($lines,$pkey,$idxs) = $this->_genFields($flds, true);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$taboptions = $this->_Options($tableoptions);
$tabname = $this->TableName ($tabname);
$sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
$taboptions = $this->_options($tableoptions);
$tabname = $this->tableName($tabname);
$sql = $this->_tableSQL($tabname,$lines,$pkey,$taboptions);
// ggiunta - 2006/10/12 - KLUDGE:
// if we are on autoincrement, and table options includes REPLACE, the
@ -579,12 +592,12 @@ class ADODB_DataDict {
// creating sql that double-drops the sequence
if ($this->autoIncrement && isset($taboptions['REPLACE']))
unset($taboptions['REPLACE']);
$tsql = $this->_Triggers($tabname,$taboptions);
$tsql = $this->_triggers($tabname,$taboptions);
foreach($tsql as $s) $sql[] = $s;
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql_idxs = $this->createIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
@ -594,13 +607,13 @@ class ADODB_DataDict {
function _GenFields($flds,$widespacing=false)
function _genFields($flds,$widespacing=false)
{
if (is_string($flds)) {
$padding = ' ';
$txt = $flds.$padding;
$flds = array();
$flds0 = Lens_ParseArgs($txt,',');
$flds0 = lens_ParseArgs($txt,',');
$hasparam = false;
foreach($flds0 as $f0) {
$f1 = array();
@ -643,8 +656,8 @@ class ADODB_DataDict {
$pkey = array();
$idxs = array();
foreach($flds as $fld) {
$fld = _array_change_key_case($fld);
if (is_array($fld))
$fld = array_change_key_case($fld,CASE_UPPER);
$fname = false;
$fdefault = false;
$fautoinc = false;
@ -660,18 +673,23 @@ class ADODB_DataDict {
$funsigned = false;
$findex = '';
$funiqueindex = false;
$fOptions = array();
//-----------------
// 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);
if ($attr == 2 && is_numeric($v))
$attr = 'SIZE';
elseif ($attr == 2 && strtoupper($ftype) == 'ENUM')
$attr = 'ENUM';
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 'TYPE': $ty = $v; $ftype = $this->actualType(strtoupper($v)); break;
case 'SIZE':
$dotat = strpos($v,'.'); if ($dotat === false) $dotat = strpos($v,',');
@ -697,6 +715,8 @@ class ADODB_DataDict {
// let INDEX keyword create a 'very standard' index on column
case 'INDEX': $findex = $v; break;
case 'UNIQUE': $funiqueindex = true; break;
case 'ENUM':
$fOptions['ENUM'] = $v; break;
} //switch
} // foreach $fld
@ -708,7 +728,7 @@ class ADODB_DataDict {
}
$fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname));
$fname = $this->NameQuote($fname);
$fname = $this->nameQuote($fname);
if (!strlen($ftype)) {
if ($this->debug) ADOConnection::outp("Undefined TYPE for field '$fname'");
@ -717,14 +737,24 @@ class ADODB_DataDict {
$ftype = strtoupper($ftype);
}
$ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec);
$ftype = $this->_getSize($ftype, $ty, $fsize, $fprec, $fOptions);
if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls
if (($ty == 'X' || $ty == 'X2' || $ty == 'XL' || $ty == 'B') && !$this->blobAllowsNotNull)
/*
* some blob types do not accept nulls, so we override the
* previously defined value
*/
$fnotnull = false;
if ($fprimary) $pkey[] = $fname;
if ($fprimary)
$pkey[] = $fname;
// some databases do not allow blobs to have defaults
if ($ty == 'X') $fdefault = false;
if (($ty == 'X' || $ty == 'X2' || $ty == 'XL' || $ty == 'B') && !$this->blobAllowsDefaultValue)
/*
* some databases do not allow blobs to have defaults, so we
* override the previously defined value
*/
$fdefault = false;
// build list of indexes
if ($findex != '') {
@ -769,11 +799,11 @@ class ADODB_DataDict {
// convert default date into database-aware code
if ($ty == 'T')
{
$fdefault = $this->connection->DBTimeStamp($fdefault);
$fdefault = $this->connection->dbTimeStamp($fdefault);
}
else
{
$fdefault = $this->connection->DBDate($fdefault);
$fdefault = $this->connection->dbDate($fdefault);
}
}
else
@ -783,7 +813,7 @@ class ADODB_DataDict {
$fdefault = $this->connection->qstr($fdefault);
}
}
$suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
$suffix = $this->_createSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
// add index creation
if ($widespacing) $fname = str_pad($fname,24);
@ -806,19 +836,38 @@ class ADODB_DataDict {
$ftype is the actual type
$ty is the type defined originally in the DDL
*/
function _GetSize($ftype, $ty, $fsize, $fprec)
function _getSize($ftype, $ty, $fsize, $fprec, $options=false)
{
if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) {
$ftype .= "(".$fsize;
if (strlen($fprec)) $ftype .= ",".$fprec;
$ftype .= ')';
}
/*
* Handle additional options
*/
if (is_array($options))
{
foreach($options as $type=>$value)
{
switch ($type)
{
case 'ENUM':
$ftype .= '(' . $value . ')';
break;
default:
}
}
}
return $ftype;
}
// return string must begin with space
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
function _createSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
@ -827,7 +876,7 @@ class ADODB_DataDict {
return $suffix;
}
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
function _indexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
@ -856,25 +905,26 @@ class ADODB_DataDict {
return $sql;
}
function _DropAutoIncrement($tabname)
function _dropAutoIncrement($tabname)
{
return false;
}
function _TableSQL($tabname,$lines,$pkey,$tableoptions)
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);
$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) {
@ -898,7 +948,7 @@ class ADODB_DataDict {
GENERATE TRIGGERS IF NEEDED
used when table has auto-incrementing field that is emulated using triggers
*/
function _Triggers($tabname,$taboptions)
function _triggers($tabname,$taboptions)
{
return array();
}
@ -906,7 +956,7 @@ class ADODB_DataDict {
/**
Sanitize options, so that array elements with no keys are promoted to keys
*/
function _Options($opts)
function _options($opts)
{
if (!is_array($opts)) return array();
$newopts = array();
@ -938,25 +988,25 @@ class ADODB_DataDict {
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, $dropOldFlds=false)
function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($this->connection->fetchMode !== false) $savem = $this->connection->SetFetchMode(false);
if ($this->connection->fetchMode !== false) $savem = $this->connection->setFetchMode(false);
// check table exists
$save_handler = $this->connection->raiseErrorFn;
$this->connection->raiseErrorFn = '';
$cols = $this->MetaColumns($tablename);
$cols = $this->metaColumns($tablename);
$this->connection->raiseErrorFn = $save_handler;
if (isset($savem)) $this->connection->SetFetchMode($savem);
if (isset($savem)) $this->connection->setFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ( empty($cols)) {
return $this->CreateTableSQL($tablename, $flds, $tableoptions);
return $this->createTableSQL($tablename, $flds, $tableoptions);
}
if (is_array($flds)) {
@ -976,7 +1026,7 @@ class ADODB_DataDict {
$c = $cols[$k];
$ml = $c->max_length;
$mt = $this->MetaType($c->type,$ml);
$mt = $this->metaType($c->type,$ml);
if (isset($c->scale)) $sc = $c->scale;
else $sc = 99; // always force change if scale not known.
@ -998,16 +1048,16 @@ class ADODB_DataDict {
// already exists, alter table instead
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
list($lines,$pkey,$idxs) = $this->_genFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $this->TableName($tablename);
$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,',');
$flds = lens_ParseArgs($v,',');
// We are trying to change the size of the field, if not allowed, simply ignore the request.
// $flds[1] holds the type, $flds[2] holds the size -postnuke addition

View file

@ -1,6 +1,6 @@
<?php
/**
* @version v5.20.16 12-Jan-2020
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
@ -70,6 +70,10 @@ function adodb_error($provider,$dbType,$errno)
case 'oracle':
case 'oci8': $map = adodb_error_oci8(); break;
// As discussed in https://github.com/ADOdb/ADOdb/issues/201#issuecomment-188154980
// firebird uses the ibase error handler for now. This may change if and
// when the PHP driver is updated to use the new SQLSTATE error codes
case 'firebird':
case 'ibase': $map = adodb_error_ibase(); break;
case 'odbc': $map = adodb_error_odbc(); break;

View file

@ -1,6 +1,6 @@
<?php
/**
* @version v5.20.16 12-Jan-2020
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
@ -9,7 +9,7 @@
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://adodb.org/
* Latest version is available at https://adodb.org/
*
*/

View file

@ -1,6 +1,6 @@
<?php
/**
* @version v5.20.16 12-Jan-2020
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
@ -9,7 +9,7 @@
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://adodb.org/
* Latest version is available at https://adodb.org/
*
*/
include_once('PEAR.php');
@ -78,7 +78,7 @@ global $ADODB_Last_PEAR_Error;
/**
* Returns last PEAR_Error object. This error might be for an error that
* occured several sql statements ago.
* occurred several sql statements ago.
*/
function ADODB_PEAR_Error()
{

View file

@ -1,7 +1,7 @@
<?php
/**
* @version v5.20.16 12-Jan-2020
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
@ -10,7 +10,7 @@
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://adodb.org/
* Latest version is available at https://adodb.org/
*
* Exception-handling code using PHP5 exceptions (try-catch-throw).
*/
@ -60,14 +60,14 @@ var $database = '';
}
/**
* Default Error Handler. This will be called with the following params
* Default Error Handler.
*
* @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 string $dbms the RDBMS you are connecting to
* @param string $fn the name of the calling function (in uppercase)
* @param int $errno the native error number from the database
* @param string $errmsg the native error msg from the database
* @param mixed $p1 $fn specific parameter - see below
* @param mixed $p2 $fn specific parameter - see below
*/
function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)

View file

@ -1,7 +1,7 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -6,7 +6,7 @@ global $ADODB_INCLUDED_LIB;
$ADODB_INCLUDED_LIB = 1;
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -19,7 +19,12 @@ $ADODB_INCLUDED_LIB = 1;
function adodb_strip_order_by($sql)
{
$rez = preg_match('/(\sORDER\s+BY\s(?:[^)](?!LIMIT))*)/is', $sql, $arr);
$rez = preg_match_all('/(\sORDER\s+BY\s(?:[^)](?!LIMIT))*)/is', $sql, $arr);
if ($arr)
{
$tmp = array_pop($arr);
$arr = [1=>array_pop($tmp)];
}
if ($arr)
if (strpos($arr[1], '(') !== false) {
$at = strpos($sql, $arr[1]);
@ -39,6 +44,7 @@ function adodb_strip_order_by($sql)
} else {
$sql = str_replace($arr[1], '', $sql);
}
return $sql;
}
@ -118,30 +124,18 @@ function adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs)
}
}
// Force key to upper.
// See also http://www.php.net/manual/en/function.array-change-key-case.php
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;
}
function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
{
// Add Quote around table name to support use of spaces / reserved keywords
$table=sprintf('%s%s%s', $zthis->nameQuote,$table,$zthis->nameQuote);
if (count($fieldArray) == 0) return 0;
$first = true;
$uSet = '';
if (!is_array($keyCol)) {
$keyCol = array($keyCol);
}
$uSet = '';
foreach($fieldArray as $k => $v) {
if ($v === null) {
$v = 'NULL';
@ -152,38 +146,34 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
}
if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
if ($first) {
$first = false;
$uSet = "$k=$v";
} else
$uSet .= ",$k=$v";
// Add Quote around column name to support use of spaces / reserved keywords
$uSet .= sprintf(',%s%s%s=%s',$zthis->nameQuote,$k,$zthis->nameQuote,$v);
}
$uSet = ltrim($uSet, ',');
$where = false;
// Add Quote around column name in where clause
$where = '';
foreach ($keyCol as $v) {
if (isset($fieldArray[$v])) {
if ($where) $where .= ' and '.$v.'='.$fieldArray[$v];
else $where = $v.'='.$fieldArray[$v];
$where .= sprintf(' and %s%s%s=%s ', $zthis->nameQuote,$v,$zthis->nameQuote,$fieldArray[$v]);
}
}
if ($where) {
$where = substr($where, 5);
}
if ($uSet && $where) {
$update = "UPDATE $table SET $uSet WHERE $where";
$rs = $zthis->Execute($update);
if ($rs) {
if ($zthis->poorAffectedRows) {
/*
The Select count(*) wipes out any errors that the update would have returned.
http://phplens.com/lens/lensforum/msgs.php?id=5696
*/
// The Select count(*) wipes out any errors that the update would have returned.
// PHPLens Issue No: 5696
if ($zthis->ErrorNo()<>0) return 0;
# affected_rows == 0 if update field values identical to old values
# for mysql - which is silly.
// affected_rows == 0 if update field values identical to old values
// for mysql - which is silly.
$cnt = $zthis->GetOne("select count(*) from $table where $where");
if ($cnt > 0) return 1; // record already exists
} else {
@ -193,20 +183,17 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
return 0;
}
// print "<p>Error=".$this->ErrorNo().'<p>';
$first = true;
$iCols = $iVals = '';
foreach($fieldArray as $k => $v) {
if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
if ($first) {
$first = false;
$iCols = "$k";
$iVals = "$v";
} else {
$iCols .= ",$k";
// Add Quote around Column Name
$iCols .= sprintf(',%s%s%s',$zthis->nameQuote,$k,$zthis->nameQuote);
$iVals .= ",$v";
}
}
$iCols = ltrim($iCols, ',');
$iVals = ltrim($iVals, ',');
$insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
$rs = $zthis->Execute($insert);
return ($rs) ? 2 : 0;
@ -441,7 +428,7 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
}
// fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
// with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
// also see http://phplens.com/lens/lensforum/msgs.php?id=12752
// also see PHPLens Issue No: 12752
$rewritesql = adodb_strip_order_by($rewritesql);
}
@ -478,17 +465,10 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
if ($rstest) {
$qryRecs = $rstest->RecordCount();
if ($qryRecs == -1) {
global $ADODB_EXTENSION;
// some databases will return -1 on MoveLast() - change to MoveNext()
if ($ADODB_EXTENSION) {
while(!$rstest->EOF) {
adodb_movenext($rstest);
}
} else {
while(!$rstest->EOF) {
$rstest->MoveNext();
}
}
$qryRecs = $rstest->_currentRow;
}
$rstest->Close();
@ -650,7 +630,7 @@ function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr
return $rsreturn;
}
function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
function _adodb_getupdatesql(&$zthis, &$rs, $arrFields, $forceUpdate=false, $force=2)
{
global $ADODB_QUOTE_FIELDNAMES;
@ -660,15 +640,16 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
}
$fieldUpdatedCount = 0;
$arrFields = _array_change_key_case($arrFields);
if (is_array($arrFields))
$arrFields = array_change_key_case($arrFields,CASE_UPPER);
$hasnumeric = isset($rs->fields[0]);
$setFields = '';
// Loop through all of the fields in the recordset
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
for ($i=0, $max=$rs->fieldCount(); $i < $max; $i++) {
// Get the field from the recordset
$field = $rs->FetchField($i);
$field = $rs->fetchField($i);
// If the recordset field is one
// of the fields passed in then process.
@ -686,15 +667,13 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)];
else $val = '';
if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
// Set the counter for the number of fields that will be updated.
$fieldUpdatedCount++;
// Based on the datatype of the field
// Format the value properly for the database
$type = $rs->MetaType($field->type);
$type = $rs->metaType($field->type);
if ($type == 'null') {
$type = 'C';
@ -702,6 +681,8 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
switch ($ADODB_QUOTE_FIELDNAMES) {
case 'BRACKETS':
$fnameq = $zthis->leftBracket.$upperfname.$zthis->rightBracket;break;
case 'LOWER':
$fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
case 'NATIVE':
@ -710,40 +691,57 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
default:
$fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;break;
}
} else
} else {
$fnameq = $upperfname;
}
//********************************************************//
if (is_null($arrFields[$upperfname])
|| (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
|| $arrFields[$upperfname] === $zthis->null2null
)
{
) {
switch ($force) {
//case 0:
// //Ignore empty values. This is allready handled in "adodb_key_exists" function.
// // Ignore empty values. This is already handled in "adodb_key_exists" function.
// break;
case 1:
//Set null
$setFields .= $field->name . " = null, ";
// set null
$setFields .= $fnameq . " = null, ";
break;
case 2:
//Set empty
// set empty
$arrFields[$upperfname] = "";
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq, $arrFields);
break;
default:
case 3:
//Set the value that was given in array, so you can give both null and empty values
// set the value that was given in array, so you can give both null and empty values
if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
$setFields .= $field->name . " = null, ";
$setFields .= $fnameq . " = null, ";
} else {
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq, $arrFields);
}
break;
case ADODB_FORCE_NULL_AND_ZERO:
switch ($type) {
case 'N':
case 'I':
case 'L':
$setFields .= $fnameq . ' = 0, ';
break;
default:
$setFields .= $fnameq . ' = null, ';
break;
}
break;
}
//********************************************************//
} else {
@ -751,8 +749,7 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
// DB specific column types.
// Oracle needs BLOB types to be handled with a returning clause
// postgres has special needs as well
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
$arrFields, $magicq);
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq, $arrFields);
}
}
}
@ -761,13 +758,14 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
// If there were any modified fields then build the rest of the update query.
if ($fieldUpdatedCount > 0 || $forceUpdate) {
// Get the table name from the existing query.
if (!empty($rs->tableName)) $tableName = $rs->tableName;
else {
if (!empty($rs->tableName)) {
$tableName = $rs->tableName;
} else {
preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
$tableName = $tableName[1];
}
// Get the full where clause excluding the word "WHERE" from
// the existing query.
// Get the full where clause excluding the word "WHERE" from the existing query.
preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
$discard = false;
@ -778,18 +776,19 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
else preg_match('/\s.*(\) WHERE .*)/is', $whereClause[1], $discard); # see https://sourceforge.net/p/adodb/bugs/37/
} else
} else {
$whereClause = array(false, false);
}
if ($discard)
if ($discard) {
$whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
}
$sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
if (strlen($whereClause[1]) > 0)
if (strlen($whereClause[1]) > 0) {
$sql .= ' WHERE '.$whereClause[1];
}
return $sql;
} else {
return false;
}
@ -802,10 +801,10 @@ function adodb_key_exists($key, &$arr,$force=2)
return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
}
if (isset($arr[$key])) return true;
if (isset($arr[$key]))
return true;
## null check below
if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
return false;
return array_key_exists($key,$arr);
}
/**
@ -815,7 +814,7 @@ function adodb_key_exists($key, &$arr,$force=2)
*
*
*/
function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
function _adodb_getinsertsql(&$zthis, &$rs, $arrFields, $force=2)
{
static $cacheRS = false;
static $cacheSig = 0;
@ -826,7 +825,8 @@ static $cacheCols;
$values = '';
$fields = '';
$recordSet = null;
$arrFields = _array_change_key_case($arrFields);
if (is_array($arrFields))
$arrFields = array_change_key_case($arrFields,CASE_UPPER);
$fieldInsertedCount = 0;
if (is_string($rs)) {
@ -872,6 +872,8 @@ static $cacheCols;
$bad = false;
if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
switch ($ADODB_QUOTE_FIELDNAMES) {
case 'BRACKETS':
$fnameq = $zthis->leftBracket.$upperfname.$zthis->rightBracket;break;
case 'LOWER':
$fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
case 'NATIVE':
@ -893,29 +895,44 @@ static $cacheCols;
{
switch ($force) {
case 0: // we must always set null if missing
case ADODB_FORCE_IGNORE: // we must always set null if missing
$bad = true;
break;
case 1:
case ADODB_FORCE_NULL:
$values .= "null, ";
break;
case 2:
case ADODB_FORCE_EMPTY:
//Set empty
$arrFields[$upperfname] = "";
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields);
break;
default:
case 3:
case ADODB_FORCE_VALUE:
//Set the value that was given in array, so you can give both null and empty values
if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
$values .= "null, ";
} else {
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields);
}
break;
case ADODB_FORCE_NULL_AND_ZERO:
switch ($type)
{
case 'N':
case 'I':
case 'L':
$values .= '0, ';
break;
default:
$values .= "null, ";
break;
}
break;
} // switch
/*********************************************************/
@ -924,8 +941,7 @@ static $cacheCols;
//DB specific column types.
//Oracle needs BLOB types to be handled with a returning clause
//postgres has special needs as well
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
$arrFields, $magicq);
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields);
}
if ($bad) continue;
@ -976,7 +992,7 @@ static $cacheCols;
* @return string
*
*/
function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields)
{
$sql = '';
@ -1008,7 +1024,7 @@ function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFie
} else {
//this is to maintain compatibility
//with older adodb versions.
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, false);
}
break;
@ -1031,19 +1047,19 @@ function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFie
} else {
//this is to maintain compatibility
//with older adodb versions.
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, false);
}
break;
default:
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, false);
break;
}
return $sql;
}
function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $recurse=true)
{
if ($recurse) {
@ -1052,7 +1068,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields,
if ($type == 'L') $type = 'C';
break;
case 'oci8':
return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields);
}
}
@ -1061,7 +1077,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields,
case "C":
case "X":
case 'B':
$val = $zthis->qstr($arrFields[$fname],$magicq);
$val = $zthis->qstr($arrFields[$fname]);
break;
case "D":
@ -1091,9 +1107,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields,
if ($action == 'I') return $val . ", ";
return $fnameq . "=" . $val . ", ";
}

View file

@ -0,0 +1,773 @@
<?php
/**
* ADOdb Load Balancer
*
* ADOdbLoadBalancer is a class that allows the user to do read/write splitting
* and load balancing across multiple servers. It can handle and load balance
* any number of write capable (AKA: master) or readonly (AKA: slave) connections,
* including dealing with connection failures and retrying queries on a different
* connection instead.
*
* 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.md.
*
* Latest version is available at https://adodb.org/
*
* @package ADOdb
* @version v5.21.0 2021-02-27
* @author Mike Benoit
* @copyright (c) 2016 Mike Benoit and the ADOdb community
* @license BSD-3-Clause
* @license GNU Lesser General Public License (LGPL) v2.1 or later
* @link https://adodb.org/
* @since v5.21.0
*/
/**
* Class ADOdbLoadBalancer
*/
class ADOdbLoadBalancer
{
/**
* @var bool Once a write or readonly connection is made, stick to that connection for the entire request.
*/
public $enable_sticky_sessions = true;
/**
* @var bool|array All connections to each database.
*/
protected $connections = false;
/**
* @var bool|array Just connections to the write capable database.
*/
protected $connections_write = false;
/**
* @var bool|array Just connections to the readonly database.
*/
protected $connections_readonly = false;
/**
* @var array Counts of all connections and their types.
*/
protected $total_connections = array('all' => 0, 'write' => 0, 'readonly' => 0);
/**
* @var array Weights of all connections for each type.
*/
protected $total_connection_weights = array('all' => 0, 'write' => 0, 'readonly' => 0);
/**
* @var bool When in transactions, always use this connection.
*/
protected $pinned_connection_id = false;
/**
* @var array Last connection_id for each database type.
*/
protected $last_connection_id = array('write' => false, 'readonly' => false, 'all' => false);
/**
* @var bool Session variables that must be maintained across all connections, ie: SET TIME ZONE.
*/
protected $session_variables = false;
/**
* @var bool Called immediately after connecting to any DB.
*/
protected $user_defined_session_init_sql = false;
/**
* Defines SQL queries that are executed each time a new database connection is established.
*
* @param $sql
* @return bool
*/
public function setSessionInitSQL($sql)
{
$this->user_defined_session_init_sql[] = $sql;
return true;
}
/**
* Adds a new database connection to the pool, but no actual connection is made until its needed.
*
* @param $obj
* @return bool
* @throws Exception
*/
public function addConnection($obj)
{
if ($obj instanceof ADOdbLoadBalancerConnection) {
$this->connections[] = $obj;
end($this->connections);
$i = key($this->connections);
$this->total_connections[$obj->type]++;
$this->total_connections['all']++;
$this->total_connection_weights[$obj->type] += abs($obj->weight);
$this->total_connection_weights['all'] += abs($obj->weight);
if ($obj->type == 'write') {
$this->connections_write[] = $i;
} else {
$this->connections_readonly[] = $i;
}
return true;
}
throw new Exception('Connection object is not an instance of ADOdbLoadBalancerConnection');
}
/**
* Removes a database connection from the pool.
*
* @param $i
* @return bool
*/
public function removeConnection($i)
{
if (isset($this->connections[$i])) {
$obj = $this->connections[ $i ];
$this->total_connections[ $obj->type ]--;
$this->total_connections['all']--;
$this->total_connection_weights[ $obj->type ] -= abs($obj->weight);
$this->total_connection_weights['all'] -= abs($obj->weight);
if ($obj->type == 'write') {
unset($this->connections_write[array_search($i, $this->connections_write)]);
// Reindex array.
$this->connections_write = array_values($this->connections_write);
} else {
unset($this->connections_readonly[array_search($i, $this->connections_readonly)]);
// Reindex array.
$this->connections_readonly = array_values($this->connections_readonly);
}
// Remove any sticky connections as well.
if ($this->last_connection_id[$obj->type] == $i) {
$this->last_connection_id[$obj->type] = false;
}
unset($this->connections[$i]);
return true;
}
return false;
}
/**
* Returns a database connection of the specified type.
*
* Takes into account the connection weight for load balancing.
*
* @param string $type Type of database connection, either: 'write' capable or 'readonly'
* @return bool|int|string
*/
private function getConnectionByWeight($type)
{
if ($type == 'readonly') {
$total_weight = $this->total_connection_weights['all'];
} else {
$total_weight = $this->total_connection_weights['write'];
}
$i = false;
if (is_array($this->connections)) {
$n = 0;
$num = mt_rand(0, $total_weight);
foreach ($this->connections as $i => $connection_obj) {
if ($connection_obj->weight > 0 && ($type == 'readonly' || $connection_obj->type == 'write')) {
$n += $connection_obj->weight;
if ($n >= $num) {
break;
}
}
}
}
return $i;
}
/**
* Returns the proper database connection when taking into account sticky sessions and load balancing.
*
* @param $type
* @return bool|int|mixed|string
*/
public function getLoadBalancedConnection($type)
{
if ($this->total_connections == 0) {
$connection_id = 0;
} else {
if ($this->enable_sticky_sessions == true && $this->last_connection_id[$type] !== false) {
$connection_id = $this->last_connection_id[$type];
} else {
if ($type == 'write' && $this->total_connections['write'] == 1) {
$connection_id = $this->connections_write[0];
} else {
$connection_id = $this->getConnectionByWeight($type);
}
}
}
return $connection_id;
}
/**
* Returns the ADODB connection object by connection_id.
*
* Ensures that it's connected and the session variables are executed.
*
* @param $connection_id
* @return bool|ADOConnection
* @throws Exception
*/
private function _getConnection($connection_id)
{
if (isset($this->connections[$connection_id])) {
$connection_obj = $this->connections[$connection_id];
/** @var ADOConnection $adodb_obj */
$adodb_obj = $connection_obj->getADOdbObject();
if (is_object($adodb_obj) && $adodb_obj->_connectionID == false) {
try {
if ($connection_obj->persistent_connection == true) {
$adodb_obj->Pconnect(
$connection_obj->host,
$connection_obj->user,
$connection_obj->password,
$connection_obj->database
);
} else {
$adodb_obj->Connect(
$connection_obj->host,
$connection_obj->user,
$connection_obj->password,
$connection_obj->database
);
}
} catch (Exception $e) {
// Connection error, see if there are other connections to try still.
throw $e; // No connections left, reThrow exception so application can catch it.
}
if (is_array($this->user_defined_session_init_sql)) {
foreach ($this->user_defined_session_init_sql as $session_init_sql) {
$adodb_obj->Execute($session_init_sql);
}
}
$this->executeSessionVariables($adodb_obj);
}
return $adodb_obj;
} else {
throw new Exception('Unable to return Connection object...');
}
}
/**
* Returns the ADODB connection object by database type.
*
* Ensures that it's connected and the session variables are executed.
*
* @param string $type
* @param null $pin_connection
* @return ADOConnection|bool
* @throws Exception
*/
public function getConnection($type = 'write', $pin_connection = null)
{
while (($type == 'write' && $this->total_connections['write'] > 0)
|| ($type == 'readonly' && $this->total_connections['all'] > 0)
) {
if ($this->pinned_connection_id !== false) {
$connection_id = $this->pinned_connection_id;
} else {
$connection_id = $this->getLoadBalancedConnection($type);
}
if ($connection_id !== false) {
try {
$adodb_obj = $this->_getConnection($connection_id);
// $connection_obj = $this->connections[$connection_id];
break;
} catch (Exception $e) {
// Connection error, see if there are other connections to try still.
$this->removeConnection($connection_id);
if ( ($type == 'write' && $this->total_connections['write'] == 0)
|| ($type == 'readonly' && $this->total_connections['all'] == 0)
) {
throw $e;
}
}
} else {
throw new Exception('Connection ID is invalid!');
}
}
$this->last_connection_id[$type] = $connection_id;
if ($pin_connection === true) {
$this->pinned_connection_id = $connection_id;
} elseif ($pin_connection === false && $adodb_obj->transOff <= 1) {
// UnPin connection only if we are 1 level deep in a transaction.
$this->pinned_connection_id = false;
// When unpinning connection, reset last_connection_id so readonly
// queries don't get stuck on the write capable connection.
$this->last_connection_id['write'] = false;
$this->last_connection_id['readonly'] = false;
}
return $adodb_obj;
}
/**
* This is a hack to work around pass by reference error.
*
* Parameter 1 to ADOConnection::GetInsertSQL() expected to be a reference,
* value given in adodb-loadbalancer.inc.php on line 83
*
* @param $arr
* @return array
*/
private function makeValuesReferenced($arr)
{
$refs = array();
foreach ($arr as $key => $value) {
$refs[$key] = &$arr[$key];
}
return $refs;
}
/**
* Allow setting session variables that are maintained across connections.
*
* Its important that these are set using name/value, so it can determine
* if the same variable is set multiple times causing bloat/clutter when
* new connections are established. For example if the time_zone is set to
* many different ones through the course of a single connection, a new
* connection should only set it to the most recent value.
*
* @param $name
* @param $value
* @param bool $execute_immediately
* @return array|bool|mixed
* @throws Exception
*/
public function setSessionVariable($name, $value, $execute_immediately = true)
{
$this->session_variables[$name] = $value;
if ($execute_immediately == true) {
return $this->executeSessionVariables();
} else {
return true;
}
}
/**
* Executes the session variables on a given ADODB object.
*
* @param ADOConnection|bool $adodb_obj
* @return array|bool|mixed
* @throws Exception
*/
private function executeSessionVariables($adodb_obj = false)
{
if (is_array($this->session_variables)) {
$sql = '';
foreach ($this->session_variables as $name => $value) {
// $sql .= 'SET SESSION '. $name .' '. $value;
// MySQL uses: SET SESSION foo_bar='foo'
// PGSQL uses: SET SESSION foo_bar 'foo'
// So leave it up to the user to pass the proper value with '=' if needed.
// This may be a candidate to move into ADOdb proper.
$sql .= 'SET SESSION ' . $name . ' ' . $value;
}
if ($adodb_obj !== false) {
return $adodb_obj->Execute($sql);
} else {
return $this->ClusterExecute($sql);
}
}
return false;
}
/**
* Executes the same SQL QUERY on the entire cluster of connections.
* Would be used for things like SET SESSION TIME ZONE calls and such.
*
* @param $sql
* @param bool $inputarr
* @param bool $return_all_results
* @param bool $existing_connections_only
* @return array|bool|mixed
* @throws Exception
*/
public function clusterExecute(
$sql,
$inputarr = false,
$return_all_results = false,
$existing_connections_only = true
) {
if (is_array($this->connections) && count($this->connections) > 0) {
foreach ($this->connections as $key => $connection_obj) {
if ($existing_connections_only == false
|| ($existing_connections_only == true
&& $connection_obj->getADOdbObject()->_connectionID !== false
)
) {
$adodb_obj = $this->_getConnection($key);
if (is_object($adodb_obj)) {
$result_arr[] = $adodb_obj->Execute($sql, $inputarr);
}
}
}
if (isset($result_arr) && $return_all_results == true) {
return $result_arr;
} else {
// Loop through all results checking to see if they match, if they do return the first one
// otherwise return an array of all results.
if (isset($result_arr)) {
foreach ($result_arr as $result) {
if ($result == false) {
return $result_arr;
}
}
return $result_arr[0];
} else {
// When using lazy connections, there are cases where
// setSessionVariable() is called early on, but there are
// no connections to execute the queries on yet.
// This captures that case and forces a RETURN TRUE to occur.
// As likely the queries will be executed as soon as a
// connection is established.
return true;
}
}
}
return false;
}
/**
* Determines if a SQL query is read-only or not.
*
* @param string $sql SQL Query to test.
* @return bool
*/
public function isReadOnlyQuery($sql)
{
if ( stripos($sql, 'SELECT') === 0
&& stripos($sql, 'FOR UPDATE') === false
&& stripos($sql, ' INTO ') === false
&& stripos($sql, 'LOCK IN') === false
) {
return true;
}
return false;
}
/**
* Use this instead of __call() as it significantly reduces the overhead of call_user_func_array().
*
* @param $sql
* @param bool $inputarr
* @return array|bool|mixed
* @throws Exception
*/
public function execute($sql, $inputarr = false)
{
$type = 'write';
$pin_connection = null;
// Prevent leading spaces from causing isReadOnlyQuery/stripos from failing.
$sql = trim($sql);
// SELECT queries that can write and therefore must be run on a write capable connection.
// SELECT ... FOR UPDATE;
// SELECT ... INTO ...
// SELECT .. LOCK IN ... (MYSQL)
if ($this->isReadOnlyQuery($sql) == true) {
$type = 'readonly';
} elseif (stripos($sql, 'SET') === 0) {
// SET SQL statements should likely use setSessionVariable() instead,
// so state is properly maintained across connections, especially when they are lazily created.
return $this->ClusterExecute($sql, $inputarr);
}
$adodb_obj = $this->getConnection($type, $pin_connection);
if ($adodb_obj !== false) {
return $adodb_obj->Execute($sql, $inputarr);
}
return false;
}
/**
* Magic method to intercept method and callback to the proper ADODB object for write/readonly connections.
*
* @param string $method ADODB method to call.
* @param array $args Arguments to the ADODB method.
* @return bool|mixed
* @throws Exception
*/
public function __call($method, $args)
{
$type = 'write';
$pin_connection = null;
// Intercept specific methods to determine if they are read-only or not.
$method = strtolower($method);
switch ($method) {
// case 'execute': // This is the direct overloaded function above instead.
case 'getone':
case 'getrow':
case 'getall':
case 'getcol':
case 'getassoc':
case 'selectlimit':
if ($this->isReadOnlyQuery(trim($args[0])) == true) {
$type = 'readonly';
}
break;
case 'cachegetone':
case 'cachegetrow':
case 'cachegetall':
case 'cachegetcol':
case 'cachegetassoc':
case 'cacheexecute':
case 'cacheselect':
case 'pageexecute':
case 'cachepageexecute':
$type = 'readonly';
break;
// case 'ignoreerrors':
// // When ignoreerrors is called, PIN to the connection until its called again.
// if (!isset($args[0]) || (isset($args[0]) && $args[0] == FALSE)) {
// $pin_connection = TRUE;
// } else {
// $pin_connection = FALSE;
// }
// break;
// Manual transactions
case 'begintrans':
case 'settransactionmode':
$pin_connection = true;
break;
case 'rollbacktrans':
case 'committrans':
$pin_connection = false;
break;
// Smart transactions
case 'starttrans':
$pin_connection = true;
break;
case 'completetrans':
case 'failtrans':
// getConnection() will only unpin the transaction if we're exiting the last nested transaction
$pin_connection = false;
break;
// Functions that don't require any connection and therefore
// shouldn't force a connection be established before they run.
case 'qstr':
case 'escape':
case 'binddate':
case 'bindtimestamp':
case 'setfetchmode':
$type = false; // No connection necessary.
break;
// Default to assuming write connection is required to be on the safe side.
default:
break;
}
if ($type === false) {
if (is_array($this->connections) && count($this->connections) > 0) {
foreach ($this->connections as $key => $connection_obj) {
$adodb_obj = $connection_obj->getADOdbObject();
return call_user_func_array(array($adodb_obj, $method), $this->makeValuesReferenced($args)); // Just makes the function call on the first object.
}
}
} else {
$adodb_obj = $this->getConnection($type, $pin_connection);
if (is_object($adodb_obj)) {
$result = call_user_func_array(array($adodb_obj, $method), $this->makeValuesReferenced($args));
return $result;
}
}
return false;
}
/**
* Magic method to proxy property getter calls back to the proper ADODB object currently in use.
*
* @param $property
* @return mixed
* @throws Exception
*/
public function __get($property)
{
if (is_array($this->connections) && count($this->connections) > 0) {
foreach ($this->connections as $key => $connection_obj) {
// Just returns the property from the first object.
return $connection_obj->getADOdbObject()->$property;
}
}
return false;
}
/**
* Magic method to proxy property setter calls back to the proper ADODB object currently in use.
*
* @param $property
* @param $value
* @return mixed
* @throws Exception
*/
public function __set($property, $value)
{
// Special function to set object properties on all objects
// without initiating a connection to the database.
if (is_array($this->connections) && count($this->connections) > 0) {
foreach ($this->connections as $key => $connection_obj) {
$connection_obj->getADOdbObject()->$property = $value;
}
return true;
}
return false;
}
/**
* Override the __clone() magic method.
*/
private function __clone()
{
}
}
/**
* Class ADOdbLoadBalancerConnection
*/
class ADOdbLoadBalancerConnection
{
/**
* @var bool ADOdb drive name.
*/
protected $driver = false;
/**
* @var bool ADODB object.
*/
protected $adodb_obj = false;
/**
* @var string Type of connection, either 'write' capable or 'readonly'
*/
public $type = 'write';
/**
* @var int Weight of connection, lower receives less queries, higher receives more queries.
*/
public $weight = 1;
/**
* @var bool Determines if the connection persistent.
*/
public $persistent_connection = false;
/**
* @var string Database connection host
*/
public $host = '';
/**
* @var string Database connection user
*/
public $user = '';
/**
* @var string Database connection password
*/
public $password = '';
/**
* @var string Database connection database name
*/
public $database = '';
/**
* ADOdbLoadBalancerConnection constructor to setup the ADODB object.
*
* @param $driver
* @param string $type
* @param int $weight
* @param bool $persistent_connection
* @param string $argHostname
* @param string $argUsername
* @param string $argPassword
* @param string $argDatabaseName
*/
public function __construct(
$driver,
$type = 'write',
$weight = 1,
$persistent_connection = false,
$argHostname = '',
$argUsername = '',
$argPassword = '',
$argDatabaseName = ''
) {
if ($type !== 'write' && $type !== 'readonly') {
return false;
}
$this->adodb_obj = ADONewConnection($driver);
$this->type = $type;
$this->weight = $weight;
$this->persistent_connection = $persistent_connection;
$this->host = $argHostname;
$this->user = $argUsername;
$this->password = $argPassword;
$this->database = $argDatabaseName;
return true;
}
/**
* Returns the ADODB object for this connection.
*
* @return bool
*/
public function getADOdbObject()
{
return $this->adodb_obj;
}
}

View file

@ -11,7 +11,7 @@ if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -19,7 +19,7 @@ if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Usage:
@ -28,11 +28,14 @@ $db->memCache = true; /// should we use memCache instead of caching in files
$db->memCacheHost = array($ip1, $ip2, $ip3);
$db->memCachePort = 11211; /// this is default memCache port
$db->memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib)
/// Note; compression is not supported w/the memcached library
$db->Connect(...);
$db->CacheExecute($sql);
Note the memcache class is shared by all connections, is created during the first call to Connect/PConnect.
Notes; The memcache class is shared by all connections, is created during the first call to Connect/PConnect.
We'll look for both the memcache library (https://pecl.php.net/package/memcache) and the memcached
library (https://pecl.php.net/package/memcached). If both exist, the memcache library will be used.
Class instance is stored in $ADODB_CACHE
*/
@ -40,6 +43,11 @@ $db->CacheExecute($sql);
class ADODB_Cache_MemCache {
var $createdir = false; // create caching directory structure?
// $library will be populated with the proper library on connect
// and is used later when there are differences in specific calls
// between memcache and memcached
var $library = false;
//-----------------------------
// memcache specific variables
@ -60,18 +68,23 @@ $db->CacheExecute($sql);
// implement as lazy connection. The connection only occurs on CacheExecute call
function connect(&$err)
{
if (!function_exists('memcache_pconnect')) {
$err = 'Memcache module PECL extension not found!';
// do we have memcache or memcached?
if (class_exists('Memcache')) {
$this->library='Memcache';
$memcache = new MemCache;
} elseif (class_exists('Memcached')) {
$this->library='Memcached';
$memcache = new MemCached;
} else {
$err = 'Neither the Memcache nor Memcached PECL extensions were found!';
return false;
}
$memcache = new MemCache;
if (!is_array($this->hosts)) $this->hosts = array($this->hosts);
$failcnt = 0;
foreach($this->hosts as $host) {
if (!@$memcache->addServer($host,$this->port,true)) {
if (!@$memcache->addServer($host,$this->port)) {
$failcnt += 1;
}
}
@ -93,8 +106,25 @@ $db->CacheExecute($sql);
}
if (!$this->_memcache) return false;
$failed=false;
switch ($this->library) {
case 'Memcache':
if (!$this->_memcache->set($filename, $contents, $this->compress ? MEMCACHE_COMPRESSED : 0, $secs2cache)) {
if ($debug) ADOConnection::outp(" Failed to save data at the memcached server!<br>\n");
$failed=true;
}
break;
case 'Memcached':
if (!$this->_memcache->set($filename, $contents, $secs2cache)) {
$failed=true;
}
break;
default:
$failed=true;
break;
}
if($failed) {
if ($debug) ADOConnection::outp(" Failed to save data at the memcache server!<br>\n");
return false;
}
@ -110,7 +140,7 @@ $db->CacheExecute($sql);
$rs = $this->_memcache->get($filename);
if (!$rs) {
$err = 'Item with such key doesn\'t exists on the memcached server.';
$err = 'Item with such key doesn\'t exist on the memcache server.';
return $false;
}
@ -176,8 +206,8 @@ $db->CacheExecute($sql);
$del = $this->_memcache->delete($filename);
if ($debug)
if (!$del) ADOConnection::outp("flushcache: $key entry doesn't exist on memcached server!<br>\n");
else ADOConnection::outp("flushcache: $key entry flushed from memcached server!<br>\n");
if (!$del) ADOConnection::outp("flushcache: $key entry doesn't exist on memcache server!<br>\n");
else ADOConnection::outp("flushcache: $key entry flushed from memcache server!<br>\n");
return $del;
}

View file

@ -1,7 +1,7 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -275,7 +275,7 @@ class ADODB_Pager {
}
//------------------------------------------------------
// override this to control overall layout and formating
// override this to control overall layout and formatting
function RenderLayout($header,$grid,$footer,$attributes='border=1 bgcolor=beige')
{
echo "<table ".$attributes."><tr><td>",

View file

@ -1,6 +1,6 @@
<?php
/**
* @version v5.20.16 12-Jan-2020
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
@ -336,7 +336,7 @@ class DB
$parsed['hostspec'] = urldecode($str);
}
// Get dabase if any
// Get database if any
// $dsn => database
if (!empty($dsn)) {
$parsed['database'] = $dsn;

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Library for basic performance monitoring and tuning.
@ -170,6 +170,9 @@ function adodb_log_sql(&$connx,$sql,$inputarr)
mysqli_free_result($conn->_queryID);
}
$ok = $conn->Execute($isql,$arr);
if($conn instanceof ADODB_mysqli && $conn->_queryID){
mysqli_free_result($conn->_queryID);
}
} else
$ok = true;
@ -229,7 +232,7 @@ class adodb_perf {
var $cliFormat = "%32s => %s \r\n";
var $sql1 = 'sql1'; // used for casting sql1 to text for mssql
var $explain = true;
var $helpurl = '<a href="http://adodb.org/dokuwiki/doku.php?id=v5:performance:logsql">LogSQL help</a>';
var $helpurl = '<a href="https://adodb.org/dokuwiki/doku.php?id=v5:performance:logsql">LogSQL help</a>';
var $createTableSQL = false;
var $maxLength = 2000;
@ -263,12 +266,6 @@ processes 69293
// Algorithm is taken from
// http://social.technet.microsoft.com/Forums/en-US/winservergen/thread/414b0e1b-499c-411e-8a02-6a12e339c0f1/
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
static $FAIL = false;
if ($FAIL) return false;
@ -593,7 +590,7 @@ Committed_AS: 348732 kB
}
/*
Raw function returning array of poll paramters
Raw function returning array of poll parameters
*/
function PollParameters()
{
@ -694,12 +691,6 @@ Committed_AS: 348732 kB
}
$this->conn->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'];
@ -724,7 +715,7 @@ Committed_AS: 348732 kB
if (empty($_GET['hidem']))
echo "<table border=1 width=100% bgcolor=lightyellow><tr><td colspan=2>
<b><a href=http://adodb.org/dokuwiki/doku.php?id=v5:performance:performance_index>ADOdb</a> Performance Monitor</b> <font size=1>for $app</font></tr><tr><td>
<b><a href=https://adodb.org/dokuwiki/doku.php?id=v5:performance:performance_index>ADOdb</a> Performance Monitor</b> <font size=1>for $app</font></tr><tr><td>
<a href=?do=stats><b>Performance Stats</b></a> &nbsp; <a href=?do=viewsql><b>View SQL</b></a>
&nbsp; <a href=?do=tables><b>View Tables</b></a> &nbsp; <a href=?do=poll><b>Poll Stats</b></a>",
$allowsql ? ' &nbsp; <a href=?do=dosql><b>Run SQL</b></a>' : '',
@ -767,7 +758,6 @@ Committed_AS: 348732 kB
echo $this->Tables(); break;
}
global $ADODB_vers;
echo "<p><div align=center><font size=1>$ADODB_vers Sponsored by <a href=http://phplens.com/>phpLens</a></font></div>";
}
/*
@ -956,7 +946,7 @@ Committed_AS: 348732 kB
<?php
if (!isset($_REQUEST['sql'])) return;
$sql = $this->undomq(trim($sql));
$sql = trim($sql);
if (substr($sql,strlen($sql)-1) === ';') {
$print = true;
$sqla = $this->SplitSQL($sql);
@ -1000,18 +990,6 @@ Committed_AS: 348732 kB
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;
}
/************************************************************************/
/**

View file

@ -1,7 +1,7 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -2,9 +2,9 @@
/*
ADOdb Date Library, part of the ADOdb abstraction library
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
@ -38,7 +38,7 @@ of date()'s field formats. Mktime() will convert from local time to GMT,
and date() will convert from GMT to local time, but daylight savings is
not handled currently.
This library is independant of the rest of ADOdb, and can be used
This library is independent of the rest of ADOdb, and can be used
as standalone code.
PERFORMANCE
@ -66,13 +66,6 @@ COPYRIGHT
jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year
and originally found at http://www.php.net/manual/en/function.mktime.php
=============================================================================
BUG REPORTS
These should be posted to the ADOdb forums at
http://phplens.com/lens/lensforum/topics.php?id=4
=============================================================================
@ -268,7 +261,7 @@ Changed adodb_get_gm_diff to use DateTimeZone().
* Now adodb_mktime(0,0,0,24,1,2037) works correctly.
- 15 July 2007 0.30
Added PHP 5.2.0 compatability fixes.
Added PHP 5.2.0 compatibility fixes.
* gmtime behaviour for 1970 has changed. We use the actual date if it is between 1970 to 2038 to get the
* timezone, otherwise we use the current year as the baseline to retrieve the timezone.
* Also the timezone's in php 5.2.* support historical data better, eg. if timezone today was +8, but
@ -348,7 +341,7 @@ January!!!), changed adodb_get_gmt_diff() to ignore daylight savings.
- 9 Aug 2003 0.10
Fixed bug with dates after 2038.
See http://phplens.com/lens/lensforum/msgs.php?id=6980
See PHPLens Issue No: 6980
- 1 July 2003 0.09
Added support for Q (Quarter).
@ -404,8 +397,6 @@ First implementation.
*/
define('ADODB_DATE_VERSION',0.35);
$ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2);
/*
This code was originally for windows. But apparently this problem happens
also with Linux, RH 7.3 and later!
@ -532,8 +523,8 @@ function adodb_date_test()
if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>";
if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>";
// Test string formating
print "<p>Testing date formating</p>";
// Test string formatting
print "<p>Testing date formatting</p>";
$fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C2822 r s t U w y Y z Z 2003';
$s1 = date($fmt,0);
@ -738,12 +729,11 @@ function adodb_get_gmt_diff_ts($ts)
function adodb_get_gmt_diff($y,$m,$d)
{
static $TZ,$tzo;
global $ADODB_DATETIME_CLASS;
if (!defined('ADODB_TEST_DATES')) $y = false;
else if ($y < 1970 || $y >= 2038) $y = false;
if ($ADODB_DATETIME_CLASS && $y !== false) {
if ($y !== false) {
$dt = new DateTime();
$dt->setISODate($y,$m,$d);
if (empty($tzo)) {
@ -1035,20 +1025,20 @@ global $_month_table_normal,$_month_table_leaf, $_adodb_last_date_call_failed;
0 => $origd
);
}
/*
if ($isphp5)
$dates .= sprintf('%s%04d',($gmt<=0)?'+':'-',abs($gmt)/36);
else
$dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36);
break;*/
function adodb_tz_offset($gmt,$isphp5)
/**
* Compute timezone offset.
*
* @param int $gmt Time offset from GMT, in seconds
* @param bool $ignored Param leftover from removed PHP4-compatibility code
* kept to avoid altering function signature.
* @return string
*/
function adodb_tz_offset($gmt, $ignored=true)
{
$zhrs = abs($gmt) / 3600;
$hrs = floor($zhrs);
if ($isphp5)
return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
else
return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
return sprintf('%s%02d%02d', ($gmt <= 0) ? '+' : '-', $hrs, ($zhrs - $hrs) * 60);
}
@ -1082,10 +1072,8 @@ function adodb_date2($fmt, $d=false, $is_gmt=false)
function adodb_date($fmt,$d=false,$is_gmt=false)
{
static $daylight;
global $ADODB_DATETIME_CLASS;
static $jan1_1971;
if (!isset($daylight)) {
$daylight = function_exists('adodb_daylight_sv');
if (empty($jan1_1971)) $jan1_1971 = mktime(0,0,0,1,1,1971); // we only use date() when > 1970 as adodb_mktime() only uses mktime() when > 1970
@ -1093,7 +1081,15 @@ static $jan1_1971;
if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
if (!defined('ADODB_TEST_DATES')) {
if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
/*
* Format 'Q' is an ADOdb custom format, not supported in PHP
* so if there is a 'Q' in the format, we force it to use our
* function. There is a trivial overhead in this
*/
if ((abs($d) <= 0x7FFFFFFF) && strpos($fmt,'Q') === false)
{ // check if number in 32-bit signed range
if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= $jan1_1971) // if windows, must be +ve integer
return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
@ -1116,8 +1112,6 @@ static $jan1_1971;
$max = strlen($fmt);
$dates = '';
$isphp5 = PHP_VERSION >= 5;
/*
at this point, we have the following integer vars to manipulate:
$year, $month, $day, $hour, $min, $secs
@ -1128,12 +1122,9 @@ static $jan1_1971;
$dates .= date('e');
break;
case 'T':
if ($ADODB_DATETIME_CLASS) {
$dt = new DateTime();
$dt->SetDate($year,$month,$day);
$dates .= $dt->Format('T');
} else
$dates .= date('T');
break;
// YEAR
case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
@ -1152,14 +1143,16 @@ static $jan1_1971;
$gmt = adodb_get_gmt_diff($year,$month,$day);
$dates .= ' '.adodb_tz_offset($gmt,$isphp5);
$dates .= ' '.adodb_tz_offset($gmt);
break;
case 'Y': $dates .= $year; break;
case 'y': $dates .= substr($year,strlen($year)-2,2); break;
// MONTH
case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
case 'Q': $dates .= ($month+3)>>2; break;
case 'Q':
$dates .= ceil($month / 3);
break;
case 'n': $dates .= $month; break;
case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
@ -1167,6 +1160,9 @@ static $jan1_1971;
case 't': $dates .= $arr['ndays']; break;
case 'z': $dates .= $arr['yday']; break;
case 'w': $dates .= adodb_dow($year,$month,$day); break;
case 'W':
$dates .= sprintf('%02d',ceil( $arr['yday'] / 7) - 1);
break;
case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
case 'j': $dates .= $day; break;
@ -1185,7 +1181,7 @@ static $jan1_1971;
case 'O':
$gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff($year,$month,$day);
$dates .= adodb_tz_offset($gmt,$isphp5);
$dates .= adodb_tz_offset($gmt);
break;
case 'H':
@ -1389,7 +1385,7 @@ global $ADODB_DATE_LOCALE;
$sep = substr($tstr,2,1);
$hasAM = strrpos($tstr,'M') !== false;
*/
# see http://phplens.com/lens/lensforum/msgs.php?id=14865 for reasoning, and changelog for version 0.24
# see PHPLens Issue No: 14865 for reasoning, and changelog for version 0.24
$dstr = gmstrftime('%x',31366800); // 30 Dec 1970, 1 am
$sep = substr($dstr,2,1);
$tstr = strtoupper(gmstrftime('%X',31366800)); // 30 Dec 1970, 1 am

View file

@ -1254,12 +1254,6 @@ class adoSchema {
*/
var $objectPrefix = '';
/**
* @var long Original Magic Quotes Runtime value
* @access private
*/
var $mgq;
/**
* @var long System debug
* @access private
@ -1303,12 +1297,6 @@ class adoSchema {
* @param object $db ADOdb database connection object.
*/
function __construct( $db ) {
// Initialize the environment
$this->mgq = get_magic_quotes_runtime();
if ($this->mgq !== false) {
ini_set('magic_quotes_runtime', 0);
}
$this->db = $db;
$this->debug = $this->db->debug;
$this->dict = NewDataDictionary( $this->db );
@ -2195,11 +2183,7 @@ class adoSchema {
* Call this method to clean up after an adoSchema object that is no longer in use.
* @deprecated adoSchema now cleans up automatically.
*/
function Destroy() {
if ($this->mgq !== false) {
ini_set('magic_quotes_runtime', $this->mgq );
}
}
function Destroy() {}
}
/**

View file

@ -145,7 +145,7 @@ class dbObject {
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
function _tag_open( $parser, $tag, $attributes ) {
}
@ -154,7 +154,7 @@ class dbObject {
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
function _tag_cdata( $parser, $cdata ) {
}
@ -163,7 +163,7 @@ class dbObject {
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
function _tag_close( $parser, $tag ) {
}
@ -204,7 +204,7 @@ class dbObject {
* @param string $field Field.
* @return string Field ID.
*/
function FieldID( $field ) {
function fieldID( $field ) {
return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
}
}
@ -283,7 +283,7 @@ class dbTable extends dbObject {
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
function _tag_open( $parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
@ -345,8 +345,16 @@ class dbTable extends dbObject {
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
function _tag_cdata( $parser, $cdata ) {
switch( $this->currentElement ) {
// Table or field comment
case 'DESCR':
if( isset( $this->current_field ) ) {
$this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );
} else {
$this->addTableComment( $cdata );
}
break;
// Table/field constraint
case 'CONSTRAINT':
if( isset( $this->current_field ) ) {
@ -373,7 +381,7 @@ class dbTable extends dbObject {
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
function _tag_close( $parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
@ -449,7 +457,7 @@ class dbTable extends dbObject {
* @return array Field specifier array
*/
function addField( $name, $type, $size = NULL, $opts = NULL ) {
$field_id = $this->FieldID( $name );
$field_id = $this->fieldID( $name );
// Set the field index so we know where we are
$this->current_field = $field_id;
@ -506,11 +514,15 @@ class dbTable extends dbObject {
*/
function addTableOpt( $opt ) {
if(isset($this->currentPlatform)) {
$this->opts[$this->parent->db->databaseType] = $opt;
$this->opts[$this->parent->db->dataProvider] = $opt;
}
return $this->opts;
}
function addTableComment( $opt ) {
$this->opts['comment'] = $opt;
return $this->opts;
}
/**
* Generates the SQL that will create the table in the database
@ -522,9 +534,9 @@ class dbTable extends dbObject {
$sql = array();
// drop any existing indexes
if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {
if( is_array( $legacy_indexes = $xmls->dict->metaIndexes( $this->name ) ) ) {
foreach( $legacy_indexes as $index => $index_details ) {
$sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );
$sql[] = $xmls->dict->dropIndexSQL( $index, $this->name );
}
}
@ -534,10 +546,10 @@ class dbTable extends dbObject {
}
// if table exists
if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {
if( is_array( $legacy_fields = $xmls->dict->metaColumns( $this->name ) ) ) {
// drop table
if( $this->drop_table ) {
$sql[] = $xmls->dict->DropTableSQL( $this->name );
$sql[] = $xmls->dict->dropTableSQL( $this->name );
return $sql;
}
@ -545,7 +557,7 @@ class dbTable extends dbObject {
// drop any existing fields not in schema
foreach( $legacy_fields as $field_id => $field ) {
if( !isset( $this->fields[$field_id] ) ) {
$sql[] = $xmls->dict->DropColumnSQL( $this->name, $field->name );
$sql[] = $xmls->dict->dropColumnSQL( $this->name, $field->name );
}
}
// if table doesn't exist
@ -591,21 +603,21 @@ class dbTable extends dbObject {
if( empty( $legacy_fields ) ) {
// Create the new table
$sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
logMsg( end( $sql ), 'Generated CreateTableSQL' );
$sql[] = $xmls->dict->createTableSQL( $this->name, $fldarray, $this->opts );
logMsg( end( $sql ), 'Generated createTableSQL' );
} else {
// Upgrade an existing table
logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );
switch( $xmls->upgrade ) {
// Use ChangeTableSQL
case 'ALTER':
logMsg( 'Generated ChangeTableSQL (ALTERing table)' );
$sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );
logMsg( 'Generated changeTableSQL (ALTERing table)' );
$sql[] = $xmls->dict->changeTableSQL( $this->name, $fldarray, $this->opts );
break;
case 'REPLACE':
logMsg( 'Doing upgrade REPLACE (testing)' );
$sql[] = $xmls->dict->DropTableSQL( $this->name );
$sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
$sql[] = $xmls->dict->dropTableSQL( $this->name );
$sql[] = $xmls->dict->createTableSQL( $this->name, $fldarray, $this->opts );
break;
// ignore table
default:
@ -698,7 +710,7 @@ class dbIndex extends dbObject {
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
function _tag_open( $parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
@ -725,7 +737,7 @@ class dbIndex extends dbObject {
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
function _tag_cdata( $parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
case 'COL':
@ -741,7 +753,7 @@ class dbIndex extends dbObject {
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
function _tag_close( $parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
@ -758,7 +770,7 @@ class dbIndex extends dbObject {
* @return string Field list
*/
function addField( $name ) {
$this->columns[$this->FieldID( $name )] = $name;
$this->columns[$this->fieldID( $name )] = $name;
// Return the field list
return $this->columns;
@ -795,7 +807,7 @@ class dbIndex extends dbObject {
}
}
return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
return $xmls->dict->createIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
}
/**
@ -841,7 +853,7 @@ class dbData extends dbObject {
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
function _tag_open( $parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
@ -863,7 +875,7 @@ class dbData extends dbObject {
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
function _tag_cdata( $parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
case 'F':
@ -879,7 +891,7 @@ class dbData extends dbObject {
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
function _tag_close( $parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
@ -903,7 +915,7 @@ class dbData extends dbObject {
// Set the field index so we know where we are
if( isset( $attributes['NAME'] ) ) {
$this->current_field = $this->FieldID( $attributes['NAME'] );
$this->current_field = $this->fieldID( $attributes['NAME'] );
} else {
$this->current_field = count( $this->data[$this->row] );
}
@ -935,12 +947,12 @@ class dbData extends dbObject {
* @return array Array containing index creation SQL
*/
function create( &$xmls ) {
$table = $xmls->dict->TableName($this->parent->name);
$table = $xmls->dict->tableName($this->parent->name);
$table_field_count = count($this->parent->fields);
$tables = $xmls->db->MetaTables();
$tables = $xmls->db->metaTables();
$sql = array();
$ukeys = $xmls->db->MetaPrimaryKeys( $table );
$ukeys = $xmls->db->metaPrimaryKeys( $table );
if( !empty( $this->parent->indexes ) and !empty( $ukeys ) ) {
foreach( $this->parent->indexes as $indexObj ) {
if( !in_array( $indexObj->name, $ukeys ) ) $ukeys[] = $indexObj->name;
@ -1027,19 +1039,19 @@ class dbData extends dbObject {
$where .= $key . ' = ' . $xmls->db->qstr( $mfields[$key] );
}
}
$records = $xmls->db->Execute( 'SELECT * FROM ' . $table . ' WHERE ' . $where );
switch( $records->RecordCount() ) {
$records = $xmls->db->execute( 'SELECT * FROM ' . $table . ' WHERE ' . $where );
switch( $records->recordCount() ) {
case 0:
// No matching record, so safe to insert.
logMsg( "No matching records. Inserting new row with unique data" );
$sql[] = $xmls->db->GetInsertSQL( $records, $mfields );
$sql[] = $xmls->db->getInsertSQL( $records, $mfields );
break;
case 1:
// Exactly one matching record, so we can update if the mode permits.
logMsg( "One matching record..." );
if( $mode == XMLS_MODE_UPDATE ) {
logMsg( "...Updating existing row from unique data" );
$sql[] = $xmls->db->GetUpdateSQL( $records, $mfields );
$sql[] = $xmls->db->getUpdateSQL( $records, $mfields );
}
break;
default:
@ -1115,7 +1127,7 @@ class dbQuerySet extends dbObject {
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
function _tag_open( $parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
switch( $this->currentElement ) {
@ -1137,7 +1149,7 @@ class dbQuerySet extends dbObject {
/**
* XML Callback to process CDATA elements
*/
function _tag_cdata( &$parser, $cdata ) {
function _tag_cdata( $parser, $cdata ) {
switch( $this->currentElement ) {
// Line of queryset SQL data
case 'QUERY':
@ -1153,7 +1165,7 @@ class dbQuerySet extends dbObject {
*
* @access private
*/
function _tag_close( &$parser, $tag ) {
function _tag_close( $parser, $tag ) {
$this->currentElement = '';
switch( strtoupper( $tag ) ) {
@ -1353,12 +1365,6 @@ class adoSchema {
*/
var $objectPrefix = '';
/**
* @var long Original Magic Quotes Runtime value
* @access private
*/
var $mgq;
/**
* @var long System debug
* @access private
@ -1407,12 +1413,6 @@ class adoSchema {
* @param object $db ADOdb database connection object.
*/
function __construct( $db ) {
// Initialize the environment
$this->mgq = get_magic_quotes_runtime();
if ($this->mgq !== false) {
ini_set('magic_quotes_runtime', 0 );
}
$this->db = $db;
$this->debug = $this->db->debug;
$this->dict = NewDataDictionary( $this->db );
@ -1440,7 +1440,7 @@ class adoSchema {
* @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
* @returns string Upgrade method used
*/
function SetUpgradeMethod( $method = '' ) {
function setUpgradeMethod( $method = '' ) {
if( !is_string( $method ) ) {
return FALSE;
}
@ -1488,7 +1488,7 @@ class adoSchema {
* @param int $mode XMLS_MODE_INSERT, XMLS_MODE_UPDATE, or XMLS_MODE_IGNORE
* @return int current mode
*/
function ExistingData( $mode = NULL ) {
function existingData( $mode = NULL ) {
if( is_int( $mode ) ) {
switch( $mode ) {
case XMLS_MODE_UPDATE:
@ -1523,7 +1523,7 @@ class adoSchema {
*
* @see ParseSchema(), ExecuteSchema()
*/
function ExecuteInline( $mode = NULL ) {
function executeInline( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->executeInline = $mode;
}
@ -1544,7 +1544,7 @@ class adoSchema {
*
* @see addSQL(), ExecuteSchema()
*/
function ContinueOnError( $mode = NULL ) {
function continueOnError( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->continueOnError = $mode;
}
@ -1565,8 +1565,8 @@ class adoSchema {
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute
*/
function ParseSchema( $filename, $returnSchema = FALSE ) {
return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
function parseSchema( $filename, $returnSchema = FALSE ) {
return $this->parseSchemaString( $this->convertSchemaFile( $filename ), $returnSchema );
}
/**
@ -1575,22 +1575,22 @@ class adoSchema {
* Call this method to load the specified schema directly from a file (see
* the DTD for the proper format) and generate the SQL necessary to create
* the database described by the schema. Use this method when you are dealing
* with large schema files. Otherwise, ParseSchema() is faster.
* with large schema files. Otherwise, parseSchema() is faster.
* This method does not automatically convert the schema to the latest axmls
* schema version. You must convert the schema manually using either the
* ConvertSchemaFile() or ConvertSchemaString() method.
* @see ParseSchema()
* @see ConvertSchemaFile()
* @see ConvertSchemaString()
* convertSchemaFile() or convertSchemaString() method.
* @see parseSchema()
* @see convertSchemaFile()
* @see convertSchemaString()
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*
* @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
* @see ParseSchema(), ParseSchemaString()
* @deprecated Replaced by adoSchema::parseSchema() and adoSchema::parseSchemaString()
* @see parseSchema(), parseSchemaString()
*/
function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
function parseSchemaFile( $filename, $returnSchema = FALSE ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
logMsg( 'Unable to open file' );
@ -1598,7 +1598,7 @@ class adoSchema {
}
// do version detection here
if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
if( $this->schemaFileVersion( $filename ) != $this->schemaVersion ) {
logMsg( 'Invalid Schema Version' );
return FALSE;
}
@ -1636,13 +1636,13 @@ class adoSchema {
*
* Call this method to parse a string containing an XML schema (see the DTD for the proper format)
* and generate the SQL necessary to create the database described by the schema.
* @see ParseSchema()
* @see parseSchema()
*
* @param string $xmlstring XML schema string.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*/
function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
function parseSchemaString( $xmlstring, $returnSchema = FALSE ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
logMsg( 'Empty or Invalid Schema' );
return FALSE;
@ -1686,8 +1686,8 @@ class adoSchema {
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute
*/
function RemoveSchema( $filename, $returnSchema = FALSE ) {
return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
function removeSchema( $filename, $returnSchema = FALSE ) {
return $this->removeSchemaString( $this->convertSchemaFile( $filename ), $returnSchema );
}
/**
@ -1695,38 +1695,38 @@ class adoSchema {
*
* Call this method to parse a string containing an XML schema (see the DTD for the proper format)
* and generate the SQL necessary to uninstall the database described by the schema.
* @see RemoveSchema()
* @see removeSchema()
*
* @param string $schema XML schema string.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*/
function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
function removeSchemaString( $schema, $returnSchema = FALSE ) {
// grab current version
if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
if( !( $version = $this->schemaStringVersion( $schema ) ) ) {
return FALSE;
}
return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
return $this->parseSchemaString( $this->transformSchema( $schema, 'remove-' . $version), $returnSchema );
}
/**
* Applies the current XML schema to the database (post execution).
*
* Call this method to apply the current schema (generally created by calling
* ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes,
* parseSchema() or parseSchemaString() ) to the database (creating the tables, indexes,
* and executing other SQL specified in the schema) after parsing.
* @see ParseSchema(), ParseSchemaString(), ExecuteInline()
* @see parseSchema(), parseSchemaString(), executeInline()
*
* @param array $sqlArray Array of SQL statements that will be applied rather than
* the current schema.
* @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
* @returns integer 0 if failure, 1 if errors, 2 if successful.
*/
function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
function executeSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
if( !is_bool( $continueOnErr ) ) {
$continueOnErr = $this->ContinueOnError();
$continueOnErr = $this->continueOnError();
}
if( !isset( $sqlArray ) ) {
@ -1736,7 +1736,7 @@ class adoSchema {
if( !is_array( $sqlArray ) ) {
$this->success = 0;
} else {
$this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
$this->success = $this->dict->executeSQLArray( $sqlArray, $continueOnErr );
}
return $this->success;
@ -1746,12 +1746,12 @@ class adoSchema {
* Returns the current SQL array.
*
* Call this method to fetch the array of SQL queries resulting from
* ParseSchema() or ParseSchemaString().
* parseSchema() or parseSchemaString().
*
* @param string $format Format: HTML, TEXT, or NONE (PHP array)
* @return array Array of SQL statements or FALSE if an error occurs
*/
function PrintSQL( $format = 'NONE' ) {
function printSQL( $format = 'NONE' ) {
$sqlArray = null;
return $this->getSQL( $format, $sqlArray );
}
@ -1765,7 +1765,7 @@ class adoSchema {
* @param string $filename Path and name where the file should be saved.
* @return boolean TRUE if save is successful, else FALSE.
*/
function SaveSQL( $filename = './schema.sql' ) {
function saveSQL( $filename = './schema.sql' ) {
if( !isset( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
@ -1806,7 +1806,7 @@ class adoSchema {
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
function _tag_open( $parser, $tag, $attributes ) {
switch( strtoupper( $tag ) ) {
case 'TABLE':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
@ -1831,7 +1831,7 @@ class adoSchema {
*
* @access private
*/
function _tag_cdata( &$parser, $cdata ) {
function _tag_cdata( $parser, $cdata ) {
}
/**
@ -1840,7 +1840,7 @@ class adoSchema {
* @access private
* @internal
*/
function _tag_close( &$parser, $tag ) {
function _tag_close( $parser, $tag ) {
}
@ -1853,17 +1853,17 @@ class adoSchema {
* parameter is specified, the schema will be converted to the current DTD version.
* If the newFile parameter is provided, the converted schema will be written to the specified
* file.
* @see ConvertSchemaFile()
* @see convertSchemaFile()
*
* @param string $schema String containing XML schema that will be converted.
* @param string $newVersion DTD version to convert to.
* @param string $newFile File name of (converted) output file.
* @return string Converted XML schema or FALSE if an error occurs.
*/
function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
function convertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
// grab current version
if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
if( !( $version = $this->schemaStringVersion( $schema ) ) ) {
return FALSE;
}
@ -1874,7 +1874,7 @@ class adoSchema {
if( $version == $newVersion ) {
$result = $schema;
} else {
$result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
$result = $this->transformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
}
if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
@ -1902,17 +1902,17 @@ class adoSchema {
* parameter is specified, the schema will be converted to the current DTD version.
* If the newFile parameter is provided, the converted schema will be written to the specified
* file.
* @see ConvertSchemaString()
* @see convertSchemaString()
*
* @param string $filename Name of XML schema file that will be converted.
* @param string $newVersion DTD version to convert to.
* @param string $newFile File name of (converted) output file.
* @return string Converted XML schema or FALSE if an error occurs.
*/
function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
function convertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
// grab current version
if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
if( !( $version = $this->schemaFileVersion( $filename ) ) ) {
return FALSE;
}
@ -1928,7 +1928,7 @@ class adoSchema {
$result = substr( $result, 3 );
}
} else {
$result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
$result = $this->transformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
}
if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
@ -1939,7 +1939,7 @@ class adoSchema {
return $result;
}
function TransformSchema( $schema, $xsl, $schematype='string' )
function transformSchema( $schema, $xsl, $schematype='string' )
{
// Fail if XSLT extension is not available
if( ! function_exists( 'xslt_create' ) ) {
@ -2050,7 +2050,7 @@ class adoSchema {
* @param string $filename AXMLS schema file
* @return string Schema version number or FALSE on error
*/
function SchemaFileVersion( $filename ) {
function schemaFileVersion( $filename ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
// die( 'Unable to open file' );
@ -2076,7 +2076,7 @@ class adoSchema {
* @param string $xmlstring XML schema string
* @return string Schema version number or FALSE on error
*/
function SchemaStringVersion( $xmlstring ) {
function schemaStringVersion( $xmlstring ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
}
@ -2093,20 +2093,20 @@ class adoSchema {
*
* Call this method to create an XML schema string from an existing database.
* If the data parameter is set to TRUE, AXMLS will include the data from the database
* in the schema.
* tables in the schema.
*
* @param boolean $data Include data in schema dump
* @indent string indentation to use
* @prefix string extract only tables with given prefix
* @stripprefix strip prefix string when storing in XML schema
* @param boolean $data include data in schema dump
* @param string $indent indentation to use
* @param string $prefix extract only tables with given prefix
* @param boolean $stripprefix strip prefix string when storing in XML schema
* @return string Generated XML schema
*/
function ExtractSchema( $data = FALSE, $indent = ' ', $prefix = '' , $stripprefix=false) {
$old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
function extractSchema( $data = FALSE, $indent = ' ', $prefix = '' , $stripprefix=false) {
$old_mode = $this->db->setFetchMode( ADODB_FETCH_NUM );
$schema = '<?xml version="1.0"?>' . "\n"
. '<schema version="' . $this->schemaVersion . '">' . "\n";
if( is_array( $tables = $this->db->MetaTables( 'TABLES' ,false ,($prefix) ? str_replace('_','\_',$prefix).'%' : '') ) ) {
if( is_array( $tables = $this->db->metaTables( 'TABLES' ,false ,($prefix) ? str_replace('_','\_',$prefix).'%' : '') ) ) {
foreach( $tables as $table ) {
$schema .= $indent
. '<table name="'
@ -2114,9 +2114,9 @@ class adoSchema {
. '">' . "\n";
// grab details from database
$rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE -1' );
$fields = $this->db->MetaColumns( $table );
$indexes = $this->db->MetaIndexes( $table );
$rs = $this->db->execute( 'SELECT * FROM ' . $table . ' WHERE -1' );
$fields = $this->db->metaColumns( $table );
$indexes = $this->db->metaIndexes( $table );
if( is_array( $fields ) ) {
foreach( $fields as $details ) {
@ -2148,7 +2148,7 @@ class adoSchema {
// this stops the creation of 'R' columns,
// AUTOINCREMENT is used to create auto columns
$details->primary_key = 0;
$type = $rs->MetaType( $details );
$type = $rs->metaType( $details );
$schema .= str_repeat( $indent, 2 ) . '<field name="' . htmlentities( $details->name ) . '" type="' . $type . '"' . $extra;
@ -2179,12 +2179,12 @@ class adoSchema {
}
if( $data ) {
$rs = $this->db->Execute( 'SELECT * FROM ' . $table );
$rs = $this->db->execute( 'SELECT * FROM ' . $table );
if( is_object( $rs ) && !$rs->EOF ) {
$schema .= str_repeat( $indent, 2 ) . "<data>\n";
while( $row = $rs->FetchRow() ) {
while( $row = $rs->fetchRow() ) {
foreach( $row as $key => $val ) {
if ( $val != htmlentities( $val ) ) {
$row[$key] = '<![CDATA[' . $val . ']]>';
@ -2202,7 +2202,7 @@ class adoSchema {
}
}
$this->db->SetFetchMode( $old_mode );
$this->db->setFetchMode( $old_mode );
$schema .= '</schema>';
return $schema;
@ -2218,7 +2218,7 @@ class adoSchema {
* @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
* @return boolean TRUE if successful, else FALSE
*/
function SetPrefix( $prefix = '', $underscore = TRUE ) {
function setPrefix( $prefix = '', $underscore = TRUE ) {
switch( TRUE ) {
// clear prefix
case empty( $prefix ):
@ -2377,10 +2377,7 @@ class adoSchema {
* Call this method to clean up after an adoSchema object that is no longer in use.
* @deprecated adoSchema now cleans up automatically.
*/
function Destroy() {
if ($this->mgq !== false) {
ini_set('magic_quotes_runtime', $this->mgq );
}
function destroy() {
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,7 +1,6 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -18,6 +17,11 @@ class ADODB2_db2 extends ADODB_DataDict {
var $databaseType = 'db2';
var $seqField = false;
var $dropCol = 'ALTER TABLE %s DROP COLUMN %s';
public $blobAllowsDefaultValue = true;
public $blobAllowsNotNull = true;
function ActualType($meta)
{
@ -60,21 +64,66 @@ class ADODB2_db2 extends ADODB_DataDict {
return $suffix;
}
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
function alterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
return array();
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
$dataTypeWords = array('SET','DATA','TYPE');
foreach($lines as $v)
{
/*
* We must now post-process the line to insert the 'SET DATA TYPE'
* text into the alter statement
*/
$e = explode(' ',$v);
array_splice($e,1,0,$dataTypeWords);
$v = implode(' ',$e);
$sql[] = $alter . $v;
}
if (is_array($idxs))
{
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
function dropColumnSql($tabname, $flds, $tableflds='',$tableoptions='')
{
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
return array();
$tabname = $this->connection->getMetaCasedValue($tabname);
$flds = $this->connection->getMetaCasedValue($flds);
if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_NATIVE )
{
/*
* METACASE_NATIVE
*/
$tabname = $this->connection->nameQuote . $tabname . $this->connection->nameQuote;
$flds = $this->connection->nameQuote . $flds . $this->connection->nameQuote;
}
$sql = sprintf($this->dropCol,$tabname,$flds);
return (array)$sql;
}
function ChangeTableSQL($tablename, $flds, $tableoptions = false)
function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFields=false)
{
/**
@ -86,17 +135,25 @@ class ADODB2_db2 extends ADODB_DataDict {
$validTypes = array("CHAR","VARC");
$invalidTypes = array("BIGI","BLOB","CLOB","DATE", "DECI","DOUB", "INTE", "REAL","SMAL", "TIME");
// check table exists
$cols = $this->MetaColumns($tablename);
$cols = $this->metaColumns($tablename);
if ( empty($cols)) {
return $this->CreateTableSQL($tablename, $flds, $tableoptions);
return $this->createTableSQL($tablename, $flds, $tableoptions);
}
// already exists, alter table instead
list($lines,$pkey) = $this->_GenFields($flds);
$alter = 'ALTER TABLE ' . $this->TableName($tablename);
$alter = 'ALTER TABLE ' . $this->tableName($tablename);
$sql = array();
foreach ( $lines as $id => $v ) {
/*
* If the metaCasing was NATIVE the col returned with nameQuotes
* around the field. We need to remove this for the metaColumn
* match
*/
$id = str_replace($this->connection->nameQuote,'',$id);
if ( isset($cols[$id]) && is_object($cols[$id]) ) {
/**
If the first field of $v is the fieldname, and

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -12,22 +12,31 @@
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_firebird extends ADODB_DataDict {
var $databaseType = 'firebird';
var $seqField = false;
var $seqPrefix = 'gen_';
var $seqPrefix = 's_';
var $blobSize = 40000;
var $renameColumn = 'ALTER TABLE %s ALTER %s TO %s';
var $alterCol = ' ALTER';
var $dropCol = ' DROP';
function ActualType($meta)
{
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL': return 'VARCHAR(32000)';
case 'X': return 'VARCHAR(4000)';
case 'XL':
case 'X': return 'BLOB SUB_TYPE TEXT';
case 'C2': return 'VARCHAR'; // up to 32K
case 'X2': return 'VARCHAR(4000)';
case 'C2': return 'VARCHAR(32765)'; // up to 32K
case 'X2': return 'VARCHAR(4096)';
case 'V': return 'CHAR';
case 'C1': return 'CHAR(1)';
case 'B': return 'BLOB';
@ -40,7 +49,7 @@ class ADODB2_firebird extends ADODB_DataDict {
case 'I1': return 'SMALLINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'INTEGER';
case 'I8': return 'BIGINT';
case 'F': return 'DOUBLE PRECISION';
case 'N': return 'DECIMAL';
@ -49,7 +58,7 @@ class ADODB2_firebird extends ADODB_DataDict {
}
}
function NameQuote($name = NULL)
function NameQuote($name = NULL,$allowBrackets=false)
{
if (!is_string($name)) {
return FALSE;
@ -90,9 +99,9 @@ class ADODB2_firebird extends ADODB_DataDict {
{
if (strpos($t,'.') !== false) {
$tarr = explode('.',$t);
return 'DROP GENERATOR '.$tarr[0].'."gen_'.$tarr[1].'"';
return 'DROP GENERATOR '.$tarr[0].'."s_'.$tarr[1].'"';
}
return 'DROP GENERATOR "GEN_'.$t;
return 'DROP GENERATOR s_'.$t;
}
@ -103,11 +112,41 @@ class ADODB2_firebird extends ADODB_DataDict {
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fautoinc) $this->seqField = $fname;
$fconstraint = preg_replace("/``/", "\"", $fconstraint);
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
/**
Generate the SQL to create table. Returns an array of sql strings.
*/
function CreateTableSQL($tabname, $flds, $tableoptions=array())
{
list($lines,$pkey,$idxs) = $this->_GenFields($flds, true);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$taboptions = $this->_Options($tableoptions);
$tabname = $this->TableName ($tabname);
$sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
if ($this->autoIncrement && !isset($taboptions['DROP']))
{ $tsql = $this->_Triggers($tabname,$taboptions);
foreach($tsql as $s) $sql[] = $s;
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
/*
CREATE or replace TRIGGER jaddress_insert
before insert on jaddress
@ -128,24 +167,60 @@ end;
else $tab = $tab1;
$seqField = $this->seqField;
$seqname = $this->schema.'.'.$this->seqPrefix.$tab;
$trigname = $this->schema.'.trig_'.$this->seqPrefix.$tab;
$trigname = $this->schema.'.t_'.$this->seqPrefix.$tab;
} else {
$seqField = $this->seqField;
$seqname = $this->seqPrefix.$tab1;
$trigname = 'trig_'.$seqname;
$trigname = 't_'.$seqname;
}
if (isset($tableoptions['REPLACE']))
if (isset($tableoptions['DROP']))
{ $sql[] = "DROP GENERATOR $seqname";
}
elseif (isset($tableoptions['REPLACE']))
{ $sql[] = "DROP GENERATOR \"$seqname\"";
$sql[] = "CREATE GENERATOR \"$seqname\"";
$sql[] = "ALTER TRIGGER \"$trigname\" BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END";
}
else
{ $sql[] = "CREATE GENERATOR \"$seqname\"";
$sql[] = "CREATE TRIGGER \"$trigname\" FOR $tabname BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END";
{ $sql[] = "CREATE GENERATOR $seqname";
$sql[] = "CREATE TRIGGER $trigname FOR $tabname BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID($seqname, 1); END";
}
$this->seqField = false;
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 definition 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 definition 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,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
foreach($lines as $v) {
$sql[] = $alter . $v;
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
}

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -269,7 +269,7 @@ CREATE TABLE
}
function _GetSize($ftype, $ty, $fsize, $fprec)
function _GetSize($ftype, $ty, $fsize, $fprec, $options=false)
{
switch ($ftype) {
case 'INT':
@ -279,7 +279,7 @@ CREATE TABLE
return $ftype;
}
if ($ty == 'T') return $ftype;
return parent::_GetSize($ftype, $ty, $fsize, $fprec);
return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options);
}
}

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -53,6 +53,9 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
//var $alterCol = ' ALTER COLUMN ';
public $blobAllowsDefaultValue = true;
public $blobAllowsNotNull = true;
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
@ -94,7 +97,10 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
-3 => 'X'
);
return $_typeConversion($t);
if (isset($_typeConversion[$t]))
return $_typeConversion[$t];
return ADODB_DEFAULT_METATYPE;
}
@ -126,7 +132,6 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
case 'F': return 'REAL';
case 'N': return 'NUMERIC';
default:
print "RETURN $meta";
return $meta;
}
}
@ -353,7 +358,7 @@ CREATE TABLE
}
function _GetSize($ftype, $ty, $fsize, $fprec)
function _GetSize($ftype, $ty, $fsize, $fprec,$options=false)
{
switch ($ftype) {
case 'INT':
@ -363,7 +368,7 @@ CREATE TABLE
return $ftype;
}
if ($ty == 'T') return $ftype;
return parent::_GetSize($ftype, $ty, $fsize, $fprec);
return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options);
}
}

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -24,8 +24,11 @@ class ADODB2_mysql extends ADODB_DataDict {
var $dropIndex = 'DROP INDEX %s ON %s';
var $renameColumn = 'ALTER TABLE %s CHANGE COLUMN %s %s %s'; // needs column-definition!
public $blobAllowsNotNull = true;
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
@ -74,7 +77,7 @@ class ADODB2_mysql extends ADODB_DataDict {
case 'SMALLINT': return $is_serial ? 'R' : 'I2';
case 'MEDIUMINT': return $is_serial ? 'R' : 'I4';
case 'BIGINT': return $is_serial ? 'R' : 'I8';
default: return 'N';
default: return ADODB_DEFAULT_METATYPE;
}
}

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -26,7 +26,17 @@ class ADODB2_oci8 extends ADODB_DataDict {
var $typeX = 'VARCHAR(4000)';
var $typeXL = 'CLOB';
function MetaType($t, $len=-1, $fieldobj=false)
/**
* Legacy compatibility for sequence names for emulated auto-increments.
*
* If set to true, creates sequences and triggers as TRIG_394545594
* instead of TRIG_possibly_too_long_tablename
*
* @var bool $useCompactAutoIncrements
*/
public $useCompactAutoIncrements = false;
function metaType($t, $len=-1, $fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
@ -69,7 +79,7 @@ class ADODB2_oci8 extends ADODB_DataDict {
return 'I';
default:
return 'N';
return ADODB_DEFAULT_METATYPE;
}
}
@ -185,32 +195,52 @@ class ADODB2_oci8 extends ADODB_DataDict {
return $suffix;
}
/*
CREATE or replace TRIGGER jaddress_insert
before insert on jaddress
for each row
begin
select seqaddress.nextval into :new.A_ID from dual;
end;
/**
* Creates an insert trigger to emulate an auto-increment column
* in a table
*
* @param string $tabname The name of the table
* @param string[] $tableoptions Optional configuration items
*
* @return string[] The SQL statements to create the trigger
*/
function _Triggers($tabname,$tableoptions)
{
if (!$this->seqField) return array();
if ($this->schema) {
if ($this->schema)
{
$t = strpos($tabname,'.');
if ($t !== false) $tab = substr($tabname,$t+1);
else $tab = $tabname;
if ($t !== false)
$tab = substr($tabname,$t+1);
else
$tab = $tabname;
if ($this->connection->useCompactAutoIncrements)
$id = sprintf('%u',crc32(strtolower($tab)));
else
$id = $tab;
$seqname = $this->schema.'.'.$this->seqPrefix.$tab;
$trigname = $this->schema.'.'.$this->trigPrefix.$this->seqPrefix.$tab;
} else {
$seqname = $this->seqPrefix.$tabname;
$trigname = $this->trigPrefix.$seqname;
}
else
{
if ($this->connection->useCompactAutoIncrements)
$id = sprintf('%u',crc32(strtolower($tabname)));
else
$id = $tabname;
$seqname = $this->seqPrefix.$id;
$trigname = $this->trigPrefix.$id;
}
if (strlen($seqname) > 30) {
$seqname = $this->seqPrefix.uniqid('');
} // end if
if (strlen($trigname) > 30) {
$trigname = $this->trigPrefix.uniqid('');
} // end if
@ -221,8 +251,8 @@ end;
$seqIncr = '';
if (isset($tableoptions['SEQUENCE_INCREMENT'])){$seqIncr = ' INCREMENT BY '.$tableoptions['SEQUENCE_INCREMENT'];}
$seqStart = '';
if (isset($tableoptions['SEQUENCE_START'])){$seqIncr = ' START WITH '.$tableoptions['SEQUENCE_START'];}
$sql[] = "CREATE SEQUENCE $seqname $seqStart $seqIncr $seqCache";
if (isset($tableoptions['SEQUENCE_START'])){$seqStart = ' START WITH '.$tableoptions['SEQUENCE_START'];}
$sql[] = "CREATE SEQUENCE $seqname MINVALUE 1 $seqStart $seqIncr $seqCache";
$sql[] = "CREATE OR REPLACE TRIGGER $trigname BEFORE insert ON $tabname FOR EACH ROW WHEN (NEW.$this->seqField IS NULL OR NEW.$this->seqField = 0) BEGIN select $seqname.nextval into :new.$this->seqField from dual; END;";
$this->seqField = false;

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -25,6 +25,9 @@ class ADODB2_postgres extends ADODB_DataDict {
var $renameTable = 'ALTER TABLE %s RENAME TO %s'; // at least since 7.1
var $dropTable = 'DROP TABLE %s CASCADE';
public $blobAllowsDefaultValue = true;
public $blobAllowsNotNull = true;
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
@ -85,7 +88,7 @@ class ADODB2_postgres extends ADODB_DataDict {
return 'F';
default:
return 'N';
return ADODB_DEFAULT_METATYPE;
}
}
@ -164,11 +167,11 @@ class ADODB2_postgres extends ADODB_DataDict {
/**
* Change the definition of one column
*
* Postgres can't do that on it's own, you need to supply the complete defintion of the new table,
* Postgres can't do that on it's own, you need to supply the complete definition 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 string $tableflds complete definition of the new table, eg. for postgres, default ''
* @param array/ $tableoptions options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
@ -200,7 +203,7 @@ class ADODB2_postgres extends ADODB_DataDict {
// this next block doesn't work - there is no way that I can see to
// explicitly ask a column to be null using $flds
else if ($set_null = preg_match('/NULL/i',$v)) {
// if they didn't specify not null, see if they explicitely asked for null
// if they didn't specify not null, see if they explicitly asked for null
// Lookbehind pattern covers the case 'fieldname NULL datatype DEFAULT NULL'
// only the first NULL should be removed, not the one specifying
// the default value
@ -274,11 +277,11 @@ class ADODB2_postgres extends ADODB_DataDict {
/**
* Drop one column
*
* Postgres < 7.3 can't do that on it's own, you need to supply the complete defintion of the new table,
* Postgres < 7.3 can't do that on it's own, you need to supply the complete definition 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 string $tableflds complete definition of the new table, eg. for postgres, default ''
* @param array/ $tableoptions options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
@ -303,7 +306,7 @@ class ADODB2_postgres extends ADODB_DataDict {
* @internal
* @param string $tabname table-name
* @param string $dropflds column-names to drop
* @param string $tableflds complete defintion of the new table, eg. for postgres
* @param string $tableflds complete definition of the new table, eg. for postgres
* @param array/string $tableoptions options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
@ -312,22 +315,36 @@ class ADODB2_postgres extends ADODB_DataDict {
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'))) {
if (preg_match('/'.$fld->name.' (\w+)/i', $tableflds, $matches)) {
$new_type = strtoupper($matches[1]);
// AlterColumn of a char column to a nummeric one needs an explicit conversation
if (in_array($new_type, array('I', 'I2', 'I4', 'I8', 'N', 'F')) &&
in_array($fld->type, array('varchar','char','text','bytea'))
) {
$copyflds[] = "to_number($fld->name,'S9999999999999D99')";
} else {
// other column-type changes needs explicit decode, encode for bytea or cast otherwise
$new_actual_type = $this->ActualType($new_type);
if (strtoupper($fld->type) != $new_actual_type) {
if ($new_actual_type == 'BYTEA' && $fld->type == 'text') {
$copyflds[] = "DECODE($fld->name, 'escape')";
} elseif ($fld->type == 'bytea' && $new_actual_type == 'TEXT') {
$copyflds[] = "ENCODE($fld->name, 'escape')";
} else {
$copyflds[] = "CAST($fld->name AS $new_actual_type)";
}
}
}
} 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)) {
preg_match("/nextval\('([^']+)'::(text|regclass)\)/",$fld->default_value,$matches)) {
$seq_name = $matches[1];
$seq_fld = $fld->name;
}
}
}
$copyflds = implode(', ',$copyflds);
$tempname = $tabname.'_tmp';
@ -341,7 +358,7 @@ class ADODB2_postgres extends ADODB_DataDict {
$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
// recreate the indexes, if they not contain one of the dropped columns
foreach($this->MetaIndexes($tabname) as $idx_name => $idx_data)
{
if (substr($idx_name,-5) != '_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data['columns'])))) {
@ -377,7 +394,7 @@ class ADODB2_postgres extends ADODB_DataDict {
return $suffix;
}
// search for a sequece for the given table (asumes the seqence-name contains the table-name!)
// search for a sequence for the given table (asumes the seqence-name contains the table-name!)
// if yes return sql to drop it
// this is still necessary if postgres < 7.3 or the SERIAL was created on an earlier version!!!
function _DropAutoIncrement($tabname)
@ -386,7 +403,7 @@ class ADODB2_postgres extends ADODB_DataDict {
$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
// check if a tables depends on the sequence and it therefore can't and don't need to be dropped separately
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;
}
@ -472,13 +489,75 @@ CREATE [ UNIQUE ] INDEX index_name ON table
return $sql;
}
function _GetSize($ftype, $ty, $fsize, $fprec)
function _GetSize($ftype, $ty, $fsize, $fprec, $options=false)
{
if (strlen($fsize) && $ty != 'X' && $ty != 'B' && $ty != 'I' && strpos($ftype,'(') === false) {
$ftype .= "(".$fsize;
if (strlen($fprec)) $ftype .= ",".$fprec;
$ftype .= ')';
}
/*
* Handle additional options
*/
if (is_array($options))
{
foreach($options as $type=>$value)
{
switch ($type)
{
case 'ENUM':
$ftype .= '(' . $value . ')';
break;
default:
}
}
}
return $ftype;
}
function ChangeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false){
global $ADODB_FETCH_MODE;
parent::ChangeTableSQL($tablename, $flds);
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($this->connection->fetchMode !== false)
$savem = $this->connection->SetFetchMode(false);
// check table exists
$save_handler = $this->connection->raiseErrorFn;
$this->connection->raiseErrorFn = '';
$cols = $this->MetaColumns($tablename);
$this->connection->raiseErrorFn = $save_handler;
if (isset($savem))
$this->connection->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
$sqlResult=array();
if ( empty($cols)) {
$sqlResult=$this->CreateTableSQL($tablename, $flds, $tableoptions);
} else {
$sqlResultAdd = $this->AddColumnSQL($tablename, $flds);
$sqlResultAlter = $this->AlterColumnSQL($tablename, $flds, '', $tableoptions);
$sqlResult = array_merge((array)$sqlResultAdd, (array)$sqlResultAlter);
if ($dropOldFlds) {
// already exists, alter table instead
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null)
$lines = array();
$alter = 'ALTER TABLE ' . $this->TableName($tablename);
foreach ( $cols as $id => $v ){
if ( !isset($lines[$id]) ){
$sqlResult[] = $alter . $this->dropCol . ' ' . $v->name;
}
}
}
}
return $sqlResult;
}
}

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -71,7 +71,7 @@ class ADODB2_sapdb extends ADODB_DataDict {
'FLOAT' => 'F',
'FIXED' => 'N',
);
$type = isset($maxdb_type2adodb[$t]) ? $maxdb_type2adodb[$t] : 'C';
$type = isset($maxdb_type2adodb[$t]) ? $maxdb_type2adodb[$t] : ADODB_DEFAULT_METATYPE;
// convert integer-types simulated with fixed back to integer
if ($t == 'FIXED' && !$fieldobj->scale && ($len == 20 || $len == 3)) {

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -25,7 +25,8 @@ class ADODB2_sqlite extends ADODB_DataDict {
var $dropIndex = 'DROP INDEX IF EXISTS %s';
var $renameTable = 'ALTER TABLE %s RENAME TO %s';
public $blobAllowsDefaultValue = true;
public $blobAllowsNotNull = true;
function ActualType($meta)
{
@ -58,7 +59,7 @@ class ADODB2_sqlite extends ADODB_DataDict {
}
// return string must begin with space
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
{
$suffix = '';
if ($funsigned) $suffix .= ' UNSIGNED';

View file

@ -1,7 +1,7 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,15 +8,16 @@
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Microsoft Access data driver. Requires ODBC. Works only on MS Windows.
Microsoft Access data driver. Requires ODBC. Works only on Microsoft Windows.
*/
if (!defined('_ADODB_ODBC_LAYER')) {
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
if (!defined('_ADODB_ACCESS')) {
define('_ADODB_ACCESS',1);
@ -31,14 +32,6 @@ class ADODB_access extends ADODB_odbc {
var $hasTransactions = false;
var $upperCase = 'ucase';
function __construct()
{
global $ADODB_EXTENSION;
$ADODB_EXTENSION = false;
parent::__construct();
}
function Time()
{
return time();
@ -62,8 +55,6 @@ class ADODB_access extends ADODB_odbc {
$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();
//print_pre($arr);
$arr2 = array();
@ -80,9 +71,6 @@ class ADORecordSet_access extends ADORecordSet_odbc {
var $databaseType = "access";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
} // class
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Microsoft ADO data driver. Requires ADO. Works only on MS Windows.
*/
@ -52,9 +52,7 @@ class ADODB_ado extends ADOConnection {
function _affectedrows()
{
if (PHP_VERSION >= 5) return $this->_affectedRows;
return $this->_affectedRows->value;
return $this->_affectedRows;
}
// you can also pass a connection string like this:
@ -81,7 +79,7 @@ class ADODB_ado extends ADOConnection {
// not yet
//if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
//use trusted conection for SQL if username not specified
//use trusted connection for SQL if username not specified
if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
} else if ($argProvider=='access')
$argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider
@ -350,7 +348,7 @@ class ADORecordSet_ado extends ADORecordSet {
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id,$mode);
parent::__construct($id);
}
@ -538,7 +536,7 @@ class ADORecordSet_ado extends ADORecordSet {
case 19://adUnsignedInt = 19,
case 20://adUnsignedBigInt = 21,
return 'I';
default: return 'N';
default: return ADODB_DEFAULT_METATYPE;
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Microsoft ADO data driver. Requires ADO. Works only on MS Windows. PHP5 compat version.
*/
@ -52,9 +52,7 @@ class ADODB_ado extends ADOConnection {
function _affectedrows()
{
if (PHP_VERSION >= 5) return $this->_affectedRows;
return $this->_affectedRows->value;
return $this->_affectedRows;
}
// you can also pass a connection string like this:
@ -97,7 +95,7 @@ class ADODB_ado extends ADOConnection {
// not yet
//if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
//use trusted conection for SQL if username not specified
//use trusted connection for SQL if username not specified
if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
} else if ($argProvider=='access')
$argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider
@ -384,7 +382,7 @@ class ADORecordSet_ado extends ADORecordSet {
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id,$mode);
parent::__construct($id);
}
@ -579,7 +577,7 @@ class ADORecordSet_ado extends ADORecordSet {
case 19://adUnsignedInt = 19,
case 20://adUnsignedBigInt = 21,
return 'I';
default: return 'N';
default: return ADODB_DEFAULT_METATYPE;
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@ 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.org/
Latest version is available at https://adodb.org/
Microsoft Access ADO data driver. Requires ADO and ODBC. Works only on MS Windows.
*/
@ -17,8 +17,7 @@ Set tabs to 4 for best viewing.
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ADO_LAYER')) {
if (PHP_VERSION >= 5) include(ADODB_DIR."/drivers/adodb-ado5.inc.php");
else include(ADODB_DIR."/drivers/adodb-ado.inc.php");
include_once(ADODB_DIR . "/drivers/adodb-ado5.inc.php");
}
class ADODB_ado_access extends ADODB_ado {
@ -43,8 +42,4 @@ class ADORecordSet_ado_access extends ADORecordSet_ado {
var $databaseType = "ado_access";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Microsoft SQL Server ADO data driver. Requires ADO and MSSQL client.
Works only on MS Windows.
@ -21,8 +21,7 @@ Set tabs to 4 for best viewing.
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ADO_LAYER')) {
if (PHP_VERSION >= 5) include(ADODB_DIR."/drivers/adodb-ado5.inc.php");
else include(ADODB_DIR."/drivers/adodb-ado.inc.php");
include_once(ADODB_DIR . "/drivers/adodb-ado5.inc.php");
}
@ -62,9 +61,9 @@ class ADODB_ado_mssql extends ADODB_ado {
$this->Execute("SET TRANSACTION ".$transaction_mode);
}
function qstr($s,$magic_quotes=false)
function qStr($s, $magic_quotes=false)
{
$s = ADOConnection::qstr($s, $magic_quotes);
$s = ADOConnection::qStr($s);
return str_replace("\0", "\\\\000", $s);
}
@ -143,8 +142,4 @@ class ADODB_ado_mssql extends ADODB_ado {
var $databaseType = 'ado_mssql';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}

View file

@ -36,7 +36,9 @@ DELPHI FOR PHP USERS:
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (!defined('ADODB_DIR')) {
die();
}
define("_ADODB_ADS_LAYER", 2);
@ -44,7 +46,8 @@ if (!defined('ADODB_DIR')) die();
--------------------------------------------------------------------------------------*/
class ADODB_ads extends ADOConnection {
class ADODB_ads extends ADOConnection
{
var $databaseType = "ads";
var $fmt = "'m-d-Y'";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
@ -60,31 +63,33 @@ class ADODB_ads extends ADOConnection {
var $curmode = SQL_CUR_USE_DRIVER; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
var $_genSeqSQL = "create table %s (id integer)";
var $_autocommit = true;
var $_haserrorfunctions = true;
var $_has_stupid_odbc_fetch_api_change = true;
var $_lastAffectedRows = 0;
var $uCaseTables = true; // for meta* functions, uppercase table names
function __construct()
{
$this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
}
// returns true or false
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('ads_connect')) return null;
if (!function_exists('ads_connect')) {
return null;
}
if ($this->debug && $argDatabasename && $this->databaseType != 'vfp') {
ADOConnection::outp("For Advantage Connect(), $argDatabasename is not used. Place dsn in 1st parameter.");
}
$last_php_error = $this->resetLastError();
if ($this->curmode === false) $this->_connectionID = ads_connect($argDSN,$argUsername,$argPassword);
else $this->_connectionID = ads_connect($argDSN,$argUsername,$argPassword,$this->curmode);
if ($this->curmode === false) {
$this->_connectionID = ads_connect($argDSN, $argUsername, $argPassword);
} else {
$this->_connectionID = ads_connect($argDSN, $argUsername, $argPassword, $this->curmode);
}
$this->_errorMsg = $this->getChangedErrorMsg($last_php_error);
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
if (isset($this->connectStmt)) {
$this->Execute($this->connectStmt);
}
return $this->_connectionID != false;
}
@ -92,7 +97,9 @@ class ADODB_ads extends ADOConnection {
// returns true or false
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('ads_connect')) return null;
if (!function_exists('ads_connect')) {
return null;
}
$last_php_error = $this->resetLastError();
$this->_errorMsg = '';
@ -100,12 +107,19 @@ class ADODB_ads extends ADOConnection {
ADOConnection::outp("For PConnect(), $argDatabasename is not used. Place dsn in 1st parameter.");
}
// print "dsn=$argDSN u=$argUsername p=$argPassword<br>"; flush();
if ($this->curmode === false) $this->_connectionID = ads_connect($argDSN,$argUsername,$argPassword);
else $this->_connectionID = ads_pconnect($argDSN,$argUsername,$argPassword,$this->curmode);
if ($this->curmode === false) {
$this->_connectionID = ads_connect($argDSN, $argUsername, $argPassword);
} else {
$this->_connectionID = ads_pconnect($argDSN, $argUsername, $argPassword, $this->curmode);
}
$this->_errorMsg = $this->getChangedErrorMsg($last_php_error);
if ($this->_connectionID && $this->autoRollback) @ads_rollback($this->_connectionID);
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
if ($this->_connectionID && $this->autoRollback) {
@ads_rollback($this->_connectionID);
}
if (isset($this->connectStmt)) {
$this->Execute($this->connectStmt);
}
return $this->_connectionID != false;
}
@ -114,18 +128,17 @@ class ADODB_ads extends ADOConnection {
function ServerInfo()
{
if (!empty($this->host) && ADODB_PHPVER >= 0x4300) {
if (!empty($this->host)) {
$stmt = $this->Prepare('EXECUTE PROCEDURE sp_mgGetInstallInfo()');
$res = $this->Execute($stmt);
if(!$res)
if (!$res) {
print $this->ErrorMsg();
else{
} else {
$ret["version"] = $res->fields[3];
$ret["description"] = "Advantage Database Server";
return $ret;
}
}
else {
} else {
return ADOConnection::ServerInfo();
}
}
@ -138,9 +151,9 @@ class ADODB_ads extends ADOConnection {
if (!$res) {
print $this->ErrorMsg();
return false;
}
else
} else {
return true;
}
}
@ -151,10 +164,10 @@ class ADODB_ads extends ADOConnection {
if (!$res) {
print $this->ErrorMsg();
return false;
}
else
} else {
return true;
}
}
// returns the generated ID or false
@ -165,7 +178,7 @@ class ADODB_ads extends ADOConnection {
$go = $this->Execute("select * from $seqname");
if (!$go) {
$res = $this->Execute("CREATE TABLE $seqname ( ID autoinc( 1 ) ) IN DATABASE");
if(!res){
if (!$res) {
print $this->ErrorMsg();
return false;
}
@ -174,8 +187,7 @@ class ADODB_ads extends ADOConnection {
if (!$res) {
print $this->ErrorMsg();
return false;
}
else{
} else {
$gen = $this->Execute("SELECT LastAutoInc( STATEMENT ) FROM system.iota");
$ret = $gen->fields[0];
return $ret;
@ -184,43 +196,48 @@ class ADODB_ads extends ADOConnection {
}
function ErrorMsg()
{
if ($this->_haserrorfunctions) {
if ($this->_errorMsg !== false) return $this->_errorMsg;
if (empty($this->_connectionID)) return @ads_errormsg();
if ($this->_errorMsg !== false) {
return $this->_errorMsg;
}
if (empty($this->_connectionID)) {
return @ads_errormsg();
}
return @ads_errormsg($this->_connectionID);
} else return ADOConnection::ErrorMsg();
}
function ErrorNo()
{
if ($this->_haserrorfunctions) {
if ($this->_errorCode !== false) {
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
return (strlen($this->_errorCode) <= 2) ? 0 : $this->_errorCode;
}
if (empty($this->_connectionID)) $e = @ads_error();
else $e = @ads_error($this->_connectionID);
if (empty($this->_connectionID)) {
$e = @ads_error();
} else {
$e = @ads_error($this->_connectionID);
}
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
// so we check and patch
if (strlen($e)<=2) return 0;
return $e;
} else return ADOConnection::ErrorNo();
if (strlen($e) <= 2) {
return 0;
}
return $e;
}
function BeginTrans()
{
if (!$this->hasTransactions) return false;
if ($this->transOff) return true;
if (!$this->hasTransactions) {
return false;
}
if ($this->transOff) {
return true;
}
$this->transCnt += 1;
$this->_autocommit = false;
return ads_autocommit($this->_connectionID, false);
@ -228,9 +245,15 @@ class ADODB_ads extends ADOConnection {
function CommitTrans($ok = true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
if ($this->transOff) {
return true;
}
if (!$ok) {
return $this->RollbackTrans();
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$this->_autocommit = true;
$ret = ads_commit($this->_connectionID);
ads_autocommit($this->_connectionID, true);
@ -239,8 +262,12 @@ class ADODB_ads extends ADOConnection {
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
if ($this->transOff) {
return true;
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$this->_autocommit = true;
$ret = ads_rollback($this->_connectionID);
ads_autocommit($this->_connectionID, true);
@ -248,8 +275,8 @@ class ADODB_ads extends ADOConnection {
}
// Returns tables,Views or both on succesfull execution. Returns
// tables by default on succesfull execustion.
// Returns tables,Views or both on successful execution. Returns
// tables by default on successful execution.
function &MetaTables($ttype = false, $showSchema = false, $mask = false)
{
$recordSet1 = $this->Execute("select * from system.tables");
@ -275,16 +302,14 @@ class ADODB_ads extends ADOConnection {
$i = $i + 1;
}
return $arr;
}
elseif($ttype=='VIEWS'){
} elseif ($ttype == 'VIEWS') {
while (!$recordSet2->EOF) {
$arrV["$i"] = $recordSet2->fields[0];
$recordSet2->MoveNext();
$i = $i + 1;
}
return $arrV;
}
else{
} else {
return $arr;
}
@ -379,19 +404,20 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
global $ADODB_FETCH_MODE;
$false = false;
if ($this->uCaseTables) $table = strtoupper($table);
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
/*if (false) { // after testing, confirmed that the following does not work because of a bug
$qid2 = ads_tables($this->_connectionID);
$rs = new ADORecordSet_ads($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) {
@ -421,16 +447,21 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
default:
$qid = @ads_columns($this->_connectionID, '%', '%', strtoupper($table), '%');
if (empty($qid)) $qid = ads_columns($this->_connectionID);
if (empty($qid)) {
$qid = ads_columns($this->_connectionID);
}
break;
}
if (empty($qid)) return $false;
if (empty($qid)) {
return $false;
}
$rs = new ADORecordSet_ads($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
if (!$rs) {
return $false;
}
$rs->_fetch();
$retarr = array();
@ -460,24 +491,34 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
// 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')
if ($this->databaseType == 'access') {
$fld->max_length = $rs->fields[6];
else if ($rs->fields[4] <= -95) // UNICODE
} else {
if ($rs->fields[4] <= -95) // UNICODE
{
$fld->max_length = $rs->fields[7] / 2;
else
} else {
$fld->max_length = $rs->fields[7];
} else
}
}
} 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)
} else {
if (sizeof($retarr) > 0) {
break;
}
}
$rs->MoveNext();
}
$rs->Close(); //-- crashes 4.03pl1 -- why?
if (empty($retarr)) $retarr = false;
if (empty($retarr)) {
$retarr = false;
}
return $retarr;
}
@ -488,8 +529,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
if (!$recordSet) {
print $this->ErrorMsg();
return false;
}
else{
} else {
$i = 0;
while (!$recordSet->EOF) {
$arr["FIELD$i"] = $recordSet->fields[0];
@ -503,7 +543,9 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
function Prepare($sql)
{
if (! $this->_bindInputArray) return $sql; // no binding
if (!$this->_bindInputArray) {
return $sql;
} // no binding
$stmt = ads_prepare($this->_connectionID, $sql);
if (!$stmt) {
// we don't know whether odbc driver is parsing prepared stmts, so just return sql
@ -532,29 +574,26 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
if (!ads_execute($stmtid, $inputarr)) {
//@ads_free_result($stmtid);
if ($this->_haserrorfunctions) {
$this->_errorMsg = ads_errormsg();
$this->_errorCode = ads_error();
}
return false;
}
} else if (is_array($sql)) {
} else {
if (is_array($sql)) {
$stmtid = $sql[1];
if (!ads_execute($stmtid)) {
//@ads_free_result($stmtid);
if ($this->_haserrorfunctions) {
$this->_errorMsg = ads_errormsg();
$this->_errorCode = ads_error();
}
return false;
}
} else
{
} else {
$stmtid = ads_exec($this->_connectionID, $sql);
}
}
$this->_lastAffectedRows = 0;
@ -572,19 +611,11 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
}
if ($this->_haserrorfunctions) {
$this->_errorMsg = '';
$this->_errorCode = 0;
} else {
$this->_errorMsg = $this->getChangedErrorMsg($last_php_error);
}
} else {
if ($this->_haserrorfunctions) {
$this->_errorMsg = ads_errormsg();
$this->_errorCode = ads_error();
} else {
$this->_errorMsg = $this->getChangedErrorMsg($last_php_error);
}
}
return $stmtid;
@ -610,13 +641,11 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
return false;
}
if (!ads_execute($stmtid, array($val), array(SQL_BINARY))) {
if ($this->_haserrorfunctions){
$this->_errorMsg = ads_errormsg();
$this->_errorCode = ads_error();
}
return false;
}
return TRUE;
return true;
}
// returns true or false
@ -638,13 +667,13 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_ads extends ADORecordSet {
class ADORecordSet_ads extends ADORecordSet
{
var $bind = false;
var $databaseType = "ads";
var $dataProvider = "ads";
var $useFetchArray;
var $_has_stupid_odbc_fetch_api_change;
function __construct($id, $mode = false)
{
@ -673,15 +702,22 @@ class ADORecordSet_ads extends ADORecordSet {
$o->name = @ads_field_name($this->_queryID, $off);
$o->type = @ads_field_type($this->_queryID, $off);
$o->max_length = @ads_field_len($this->_queryID, $off);
if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
if (ADODB_ASSOC_CASE == 0) {
$o->name = strtolower($o->name);
} else {
if (ADODB_ASSOC_CASE == 1) {
$o->name = strtoupper($o->name);
}
}
return $o;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
return $this->fields[$colname];
}
if (!$this->bind) {
$this->bind = array();
for ($i = 0; $i < $this->_numOfFields; $i++) {
@ -700,9 +736,10 @@ class ADORecordSet_ads extends ADORecordSet {
$this->_numOfRows = ($ADODB_COUNTRECS) ? @ads_num_rows($this->_queryID) : -1;
$this->_numOfFields = @ads_num_fields($this->_queryID);
// some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
if ($this->_numOfRows == 0) $this->_numOfRows = -1;
if ($this->_numOfRows == 0) {
$this->_numOfRows = -1;
}
//$this->useFetchArray = $this->connection->useFetchArray;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
}
function _seek($row)
@ -753,12 +790,7 @@ class ADORecordSet_ads extends ADORecordSet {
function _fetch()
{
$this->fields = false;
if ($this->_has_stupid_odbc_fetch_api_change)
$rez = @ads_fetch_into($this->_queryID, $this->fields);
else {
$row = 0;
$rez = @ads_fetch_into($this->_queryID,$row,$this->fields);
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields =& $this->GetRowAssoc();

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Support Borland Interbase 6.5 and later
@ -82,8 +82,4 @@ class ADORecordSet_borland_ibase extends ADORecordSet_ibase {
var $databaseType = "borland_ibase";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -38,10 +38,6 @@ class ADODB_csv extends ADOConnection {
var $hasTransactions = false;
var $_errorNo = false;
function __construct()
{
}
function _insertid()
{
return $this->_insertid;
@ -195,10 +191,6 @@ class ADODB_csv extends ADOConnection {
} // class
class ADORecordset_csv extends ADORecordset {
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
function _close()
{

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,56 +8,26 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-db2.inc.php");
include_once(ADODB_DIR."/drivers/adodb-db2.inc.php");
if (!defined('ADODB_DB2OCI')){
define('ADODB_DB2OCI',1);
/*
// regex code for smart remapping of :0, :1 bind vars to ? ?
function _colontrack($p)
{
global $_COLONARR,$_COLONSZ;
$v = (integer) substr($p,1);
if ($v > $_COLONSZ) return $p;
$_COLONARR[] = $v;
return '?';
}
// smart remapping of :0, :1 bind vars to ? ?
function _colonscope($sql,$arr)
{
global $_COLONARR,$_COLONSZ;
$_COLONARR = array();
$_COLONSZ = sizeof($arr);
$sql2 = preg_replace("/(:[0-9]+)/e","_colontrack('\\1')",$sql);
if (empty($_COLONARR)) return array($sql,$arr);
foreach($_COLONARR as $k => $v) {
$arr2[] = $arr[$v];
}
return array($sql2,$arr2);
}
/**
* Smart remapping of :0, :1 bind vars to ? ?
* Handles colons in comments -- and / * * / and in quoted strings.
* @param string $sql SQL statement
* @param array $arr parameters
* @return array
*/
/*
Smart remapping of :0, :1 bind vars to ? ?
Handles colons in comments -- and / * * / and in quoted strings.
*/
function _colonparser($sql,$arr)
{
$lensql = strlen($sql);
@ -217,10 +187,6 @@ class ADORecordSet_db2oci extends ADORecordSet_db2 {
var $databaseType = "db2oci";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
} //define

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,14 +8,14 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include(ADODB_DIR."/drivers/adodb-db2.inc.php");
include_once(ADODB_DIR."/drivers/adodb-db2.inc.php");
if (!defined('ADODB_DB2OCI')){
@ -77,10 +77,6 @@ class ADORecordSet_db2oci extends ADORecordSet_odbc {
var $databaseType = "db2oci";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
} //define

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -25,10 +25,6 @@ class ADODB_fbsql extends ADOConnection {
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $hasLimit = false;
function __construct()
{
}
function _insertid()
{
return fbsql_insert_id($this->_connectionID);
@ -177,7 +173,7 @@ class ADORecordSet_fbsql extends ADORecordSet{
default:
$this->fetchMode = FBSQL_BOTH; break;
}
return parent::__construct($queryID);
parent::__construct($queryID);
}
function _initrs()
@ -259,7 +255,7 @@ class ADORecordSet_fbsql extends ADORecordSet{
if (!empty($fieldobj->primary_key)) return 'R';
else return 'I';
default: return 'N';
default: return ADODB_DEFAULT_METATYPE;
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,20 +8,116 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
firebird data driver. Requires firebird client. Works on Windows and Unix.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-ibase.inc.php");
class ADODB_firebird extends ADODB_ibase {
class ADODB_firebird extends ADOConnection {
var $databaseType = "firebird";
var $dataProvider = "firebird";
var $replaceQuote = "''"; // string to use to replace quotes
var $fbird_datefmt = '%Y-%m-%d'; // For hours,mins,secs change to '%Y-%m-%d %H:%M:%S';
var $fmtDate = "'Y-m-d'";
var $fbird_timestampfmt = "%Y-%m-%d %H:%M:%S";
var $fbird_timefmt = "%H:%M:%S";
var $fmtTimeStamp = "'Y-m-d, H:i:s'";
var $concat_operator='||';
var $_transactionID;
var $metaTablesSQL = "select lower(rdb\$relation_name) from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
//OPN STUFF start
var $metaColumnsSQL = "select lower(a.rdb\$field_name), a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc";
//OPN STUFF end
var $ibasetrans;
var $hasGenID = true;
var $_bindInputArray = true;
var $buffers = 0;
var $dialect = 3;
var $sysDate = "cast('TODAY' as timestamp)";
var $sysTimeStamp = "CURRENT_TIMESTAMP"; //"cast('NOW' as timestamp)";
var $ansiOuter = true;
var $hasAffectedRows = true;
var $poorAffectedRows = false;
var $blobEncodeType = 'C';
var $role = false;
var $nameQuote = ''; /// string to use to quote identifiers and names
function __construct()
{
// Ignore IBASE_DEFAULT we want a more practical transaction!
// if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;
// else
$this->ibasetrans = IBASE_WAIT | IBASE_REC_VERSION | IBASE_COMMITTED;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$persist=false)
{
if (!function_exists('fbird_pconnect')) return null;
if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
$fn = ($persist) ? 'fbird_pconnect':'fbird_connect';
if ($this->role)
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->charSet,$this->buffers,$this->dialect,$this->role);
else
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->charSet,$this->buffers,$this->dialect);
if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
$this->replaceQuote = "''";
}
if ($this->_connectionID === false) {
$this->_handleerror();
return false;
}
// PHP5 change.
if (function_exists('fbird_timefmt')) {
fbird_timefmt($this->fbird_datefmt,fbird_DATE );
if ($this->dialect == 1) {
fbird_timefmt($this->fbird_datefmt,fbird_TIMESTAMP );
} else {
fbird_timefmt($this->fbird_timestampfmt,fbird_TIMESTAMP );
}
fbird_timefmt($this->fbird_timefmt,fbird_TIME );
} else {
ini_set("ibase.timestampformat", $this->fbird_timestampfmt);
ini_set("ibase.dateformat", $this->fbird_datefmt);
ini_set("ibase.timeformat", $this->fbird_timefmt);
}
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,true);
}
function MetaPrimaryKeys($table,$owner_notused=false,$internalKey=false)
{
if ($internalKey) {
return array('RDB$DB_KEY');
}
$table = strtoupper($table);
$sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME
FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
WHERE I.RDB$RELATION_NAME=\''.$table.'\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\'
ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';
$a = $this->GetCol($sql,false,true);
if ($a && sizeof($a)>0) return $a;
return false;
}
function ServerInfo()
{
@ -38,10 +134,597 @@ class ADODB_firebird extends ADODB_ibase {
return $arr;
}
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->autoCommit = false;
$this->_transactionID = fbird_trans( $this->ibasetrans, $this->_connectionID );
return $this->_transactionID;
}
function CommitTrans($ok=true)
{
if (!$ok) {
return $this->RollbackTrans();
}
if ($this->transOff) {
return true;
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$ret = false;
$this->autoCommit = true;
if ($this->_transactionID) {
//print ' commit ';
$ret = fbird_commit($this->_transactionID);
}
$this->_transactionID = false;
return $ret;
}
function _affectedrows()
{
return fbird_affected_rows( $this->_transactionID ? $this->_transactionID : $this->_connectionID );
}
// there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
// it appears that ibase extension cannot support multiple concurrent queryid's
function _Execute($sql,$inputarr=false) {
global $ADODB_COUNTRECS;
if ($this->_logsql) {
$savecrecs = $ADODB_COUNTRECS;
$ADODB_COUNTRECS = true; // force countrecs
$ret =& ADOConnection::_Execute($sql,$inputarr);
$ADODB_COUNTRECS = $savecrecs;
} else {
$ret = ADOConnection::_Execute($sql,$inputarr);
}
return $ret;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$ret = false;
$this->autoCommit = true;
if ($this->_transactionID) {
$ret = fbird_rollback($this->_transactionID);
}
$this->_transactionID = false;
return $ret;
}
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);
}
$table = strtoupper($table);
$sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";
if (!$primary) {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
} else {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
}
// get index details
$rs = $this->Execute($sql);
if (!is_object($rs)) {
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $false;
}
$indexes = array();
while ($row = $rs->FetchRow()) {
$index = $row[0];
if (!isset($indexes[$index])) {
if (is_null($row[3])) {
$row[3] = 0;
}
$indexes[$index] = array(
'unique' => ($row[3] == 1),
'columns' => array()
);
}
$sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '".$index."' ORDER BY RDB\$FIELD_POSITION ASC";
$rs1 = $this->Execute($sql);
while ($row1 = $rs1->FetchRow()) {
$indexes[$index]['columns'][$row1[2]] = $row1[1];
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $indexes;
}
// See http://community.borland.com/article/0,1410,25844,00.html
function RowLock($tables,$where,$col=false)
{
if ($this->autoCommit) {
$this->BeginTrans();
}
$this->Execute("UPDATE $table SET $col=$col WHERE $where "); // is this correct - jlim?
return 1;
}
function CreateSequence($seqname = 'adodbseq', $startID = 1)
{
$ok = $this->Execute(("CREATE GENERATOR $seqname" ));
if (!$ok) return false;
return $this->Execute("SET GENERATOR $seqname TO ".($startID-1));
}
function DropSequence($seqname = 'adodbseq')
{
$seqname = strtoupper($seqname);
return $this->Execute("DROP GENERATOR $seqname");
}
function GenID($seqname='adodbseq',$startID=1)
{
$getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
$rs = @$this->Execute($getnext);
if (!$rs) {
$this->Execute(("CREATE GENERATOR $seqname" ));
$this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
$rs = $this->Execute($getnext);
}
if ($rs && !$rs->EOF) {
$this->genID = (integer) reset($rs->fields);
}
else {
$this->genID = 0; // false
}
if ($rs) {
$rs->Close();
}
return $this->genID;
}
function SelectDB($dbName)
{
return false;
}
function _handleerror()
{
$this->_errorMsg = fbird_errmsg();
}
function ErrorNo()
{
if (preg_match('/error code = ([\-0-9]*)/i', $this->_errorMsg,$arr)) return (integer) $arr[1];
else return 0;
}
function ErrorMsg()
{
return $this->_errorMsg;
}
function Prepare($sql)
{
$stmt = fbird_prepare($this->_connectionID,$sql);
if (!$stmt) return false;
return array($sql,$stmt);
}
// returns query ID if successful, otherwise false
// there have been reports of problems with nested queries - the code is probably not re-entrant?
function _query($sql,$iarr=false)
{
if ( !$this->isConnected() ) return false;
if (!$this->autoCommit && $this->_transactionID) {
$conn = $this->_transactionID;
$docommit = false;
} else {
$conn = $this->_connectionID;
$docommit = true;
}
if (is_array($sql)) {
$fn = 'fbird_execute';
$sql = $sql[1];
if (is_array($iarr)) {
if ( !isset($iarr[0]) )
$iarr[0] = ''; // PHP5 compat hack
$fnarr = array_merge( array($sql) , $iarr);
$ret = call_user_func_array($fn,$fnarr);
}
else {
$ret = $fn($sql);
}
} else {
$fn = 'fbird_query';
if (is_array($iarr))
{
if (sizeof($iarr) == 0)
$iarr[0] = ''; // PHP5 compat hack
$fnarr = array_merge( array($conn,$sql) , $iarr);
$ret = call_user_func_array($fn,$fnarr);
}
else {
$ret = $fn($conn, $sql);
}
}
if ($docommit && $ret === true) {
fbird_commit($this->_connectionID);
}
$this->_handleerror();
return $ret;
}
// returns true or false
function _close()
{
if (!$this->autoCommit) {
@fbird_rollback($this->_connectionID);
}
return @fbird_close($this->_connectionID);
}
//OPN STUFF start
function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $dialect3)
{
$fscale = abs($fscale);
$fld->max_length = $flen;
$fld->scale = null;
switch($ftype){
case 7:
case 8:
if ($dialect3) {
switch($fsubtype){
case 0:
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
break;
case 1:
$fld->type = 'numeric';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
case 2:
$fld->type = 'decimal';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
} // switch
} else {
if ($fscale !=0) {
$fld->type = 'decimal';
$fld->scale = $fscale;
$fld->max_length = ($ftype == 7 ? 4 : 9);
} else {
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
}
}
break;
case 16:
if ($dialect3) {
switch($fsubtype){
case 0:
$fld->type = 'decimal';
$fld->max_length = 18;
$fld->scale = 0;
break;
case 1:
$fld->type = 'numeric';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
case 2:
$fld->type = 'decimal';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
} // switch
}
break;
case 10:
$fld->type = 'float';
break;
case 14:
$fld->type = 'char';
break;
case 27:
if ($fscale !=0) {
$fld->type = 'decimal';
$fld->max_length = 15;
$fld->scale = 5;
} else {
$fld->type = 'double';
}
break;
case 35:
if ($dialect3) {
$fld->type = 'timestamp';
} else {
$fld->type = 'date';
}
break;
case 12:
$fld->type = 'date';
break;
case 13:
$fld->type = 'time';
break;
case 37:
$fld->type = 'varchar';
break;
case 40:
$fld->type = 'cstring';
break;
case 261:
$fld->type = 'blob';
$fld->max_length = -1;
break;
} // switch
}
//OPN STUFF end
// returns array of ADOFieldObjects for current table
function MetaColumns($table, $normalize=true)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
$ADODB_FETCH_MODE = $save;
$false = false;
if ($rs === false) {
return $false;
}
$retarr = array();
//OPN STUFF start
$dialect3 = ($this->dialect==3 ? true : false);
//OPN STUFF end
while (!$rs->EOF) { //print_r($rs->fields);
$fld = new ADOFieldObject();
$fld->name = trim($rs->fields[0]);
//OPN STUFF start
$this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
if (isset($rs->fields[1]) && $rs->fields[1]) {
$fld->not_null = true;
}
if (isset($rs->fields[2])) {
$fld->has_default = true;
$d = substr($rs->fields[2],strlen('default '));
switch ($fld->type)
{
case 'smallint':
case 'integer': $fld->default_value = (int) $d; break;
case 'char':
case 'blob':
case 'text':
case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;
case 'double':
case 'float': $fld->default_value = (float) $d; break;
default: $fld->default_value = $d; break;
}
// case 35:$tt = 'TIMESTAMP'; break;
}
if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {
$fld->sub_type = $rs->fields[5];
} else {
$fld->sub_type = null;
}
//OPN STUFF end
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
$rs->MoveNext();
}
$rs->Close();
if ( empty($retarr)) return $false;
else return $retarr;
}
function BlobEncode( $blob )
{
$blobid = fbird_blob_create( $this->_connectionID);
fbird_blob_add( $blobid, $blob );
return fbird_blob_close( $blobid );
}
// since we auto-decode all blob's since 2.42,
// BlobDecode should not do any transforms
function BlobDecode($blob)
{
return $blob;
}
// old blobdecode function
// still used to auto-decode all blob's
function _BlobDecode_old( $blob )
{
$blobid = fbird_blob_open($this->_connectionID, $blob );
$realblob = fbird_blob_get( $blobid,$this->maxblobsize); // 2nd param is max size of blob -- Kevin Boillet <kevinboillet@yahoo.fr>
while($string = fbird_blob_get($blobid, 8192)){
$realblob .= $string;
}
fbird_blob_close( $blobid );
return( $realblob );
}
function _BlobDecode( $blob )
{
$blob_data = fbird_blob_info($this->_connectionID, $blob );
$blobid = fbird_blob_open($this->_connectionID, $blob );
if( $blob_data[0] > $this->maxblobsize ) {
$realblob = fbird_blob_get($blobid, $this->maxblobsize);
while($string = fbird_blob_get($blobid, 8192)) {
$realblob .= $string;
}
} else {
$realblob = fbird_blob_get($blobid, $blob_data[0]);
}
fbird_blob_close( $blobid );
return( $realblob );
}
function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
{
$fd = fopen($path,'rb');
if ($fd === false) return false;
$blob_id = fbird_blob_create($this->_connectionID);
/* fill with data */
while ($val = fread($fd,32768)){
fbird_blob_add($blob_id, $val);
}
/* close and get $blob_id_str for inserting into table */
$blob_id_str = fbird_blob_close($blob_id);
fclose($fd);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
/*
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
Usage:
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
*/
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$blob_id = fbird_blob_create($this->_connectionID);
// fbird_blob_add($blob_id, $val);
// replacement that solves the problem by which only the first modulus 64K /
// of $val are stored at the blob field ////////////////////////////////////
// Thx Abel Berenstein aberenstein#afip.gov.ar
$len = strlen($val);
$chunk_size = 32768;
$tail_size = $len % $chunk_size;
$n_chunks = ($len - $tail_size) / $chunk_size;
for ($n = 0; $n < $n_chunks; $n++) {
$start = $n * $chunk_size;
$data = substr($val, $start, $chunk_size);
fbird_blob_add($blob_id, $data);
}
if ($tail_size) {
$start = $n_chunks * $chunk_size;
$data = substr($val, $start, $tail_size);
fbird_blob_add($blob_id, $data);
}
// end replacement /////////////////////////////////////////////////////////
$blob_id_str = fbird_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
function OldUpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$blob_id = fbird_blob_create($this->_connectionID);
fbird_blob_add($blob_id, $val);
$blob_id_str = fbird_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
// Format date column in sql string given an input format that understands Y M D
// Only since Interbase 6.0 - uses EXTRACT
// problem - does not zero-fill the day and month yet
function SQLDate($fmt, $col=false)
{
if (!$col) $col = $this->sysDate;
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '||';
$ch = $fmt[$i];
switch($ch) {
case 'Y':
case 'y':
$s .= "extract(year from $col)";
break;
case 'M':
case 'm':
$s .= "extract(month from $col)";
break;
case 'W':
case 'w':
// The more accurate way of doing this is with a stored procedure
// See http://wiki.firebirdsql.org/wiki/index.php?page=DATE+Handling+Functions for details
$s .= "((extract(yearday from $col) - extract(weekday from $col - 1) + 7) / 7)";
break;
case 'Q':
case 'q':
$s .= "cast(((extract(month from $col)+2) / 3) as integer)";
break;
case 'D':
case 'd':
$s .= "(extract(day from $col))";
break;
case 'H':
case 'h':
$s .= "(extract(hour from $col))";
break;
case 'I':
case 'i':
$s .= "(extract(minute from $col))";
break;
case 'S':
case 's':
$s .= "CAST((extract(second from $col)) AS INTEGER)";
break;
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
$s .= $this->qstr($ch);
break;
}
}
return $s;
}
// Note that Interbase 6.5 uses this ROWS instead - don't you love forking wars!
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
{
$nrows = (integer) $nrows;
$offset = (integer) $offset;
@ -58,16 +741,173 @@ class ADODB_firebird extends ADODB_ibase {
return $rs;
}
}
};
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_firebird extends ADORecordSet_ibase {
class ADORecordset_firebird extends ADORecordSet
{
var $databaseType = "firebird";
var $bind=false;
var $_cacheType;
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
global $ADODB_FETCH_MODE;
$this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;
parent::__construct($id);
}
/**
* Get column information in the Recordset object.
* fetchField() can be used in order to obtain information about fields in
* a certain query result. If the field offset isn't specified, the next
* field that wasn't yet retrieved by fetchField() is retrieved.
* @return object containing field information.
*/
function FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$ibf = fbird_field_info($this->_queryID,$fieldOffset);
$name = empty($ibf['alias']) ? $ibf['name'] : $ibf['alias'];
switch (ADODB_ASSOC_CASE) {
case ADODB_ASSOC_CASE_UPPER:
$fld->name = strtoupper($name);
break;
case ADODB_ASSOC_CASE_LOWER:
$fld->name = strtolower($name);
break;
case ADODB_ASSOC_CASE_NATIVE:
default:
$fld->name = $name;
break;
}
$fld->type = $ibf['type'];
$fld->max_length = $ibf['length'];
/* This needs to be populated from the metadata */
$fld->not_null = false;
$fld->has_default = false;
$fld->default_value = 'null';
return $fld;
}
function _initrs()
{
$this->_numOfRows = -1;
$this->_numOfFields = @fbird_num_fields($this->_queryID);
// cache types for blob decode check
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
$f1 = $this->FetchField($i);
$this->_cacheType[] = $f1->type;
}
}
function _seek($row)
{
return false;
}
function _fetch()
{
$f = @fbird_fetch_row($this->_queryID);
if ($f === false) {
$this->fields = false;
return false;
}
// OPN stuff start - optimized
// fix missing nulls and decode blobs automatically
global $ADODB_ANSI_PADDING_OFF;
//$ADODB_ANSI_PADDING_OFF=1;
$rtrim = !empty($ADODB_ANSI_PADDING_OFF);
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
if ($this->_cacheType[$i]=="BLOB") {
if (isset($f[$i])) {
$f[$i] = $this->connection->_BlobDecode($f[$i]);
} else {
$f[$i] = null;
}
} else {
if (!isset($f[$i])) {
$f[$i] = null;
} else if ($rtrim && is_string($f[$i])) {
$f[$i] = rtrim($f[$i]);
}
}
}
// OPN stuff end
$this->fields = $f;
if ($this->fetchMode == ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc();
} else if ($this->fetchMode == ADODB_FETCH_BOTH) {
$this->fields = array_merge($this->fields,$this->GetRowAssoc());
}
return true;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
function _close()
{
return @fbird_free_result($this->_queryID);
}
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
case 'CHAR':
return 'C';
case 'TEXT':
case 'VARCHAR':
case 'VARYING':
if ($len <= $this->blobSize) return 'C';
return 'X';
case 'BLOB':
return 'B';
case 'TIMESTAMP':
case 'DATE': return 'D';
case 'TIME': return 'T';
//case 'T': return 'T';
//case 'L': return 'L';
case 'INT':
case 'SHORT':
case 'INTEGER': return 'I';
default: return ADODB_DEFAULT_METATYPE;
}
}
}

View file

@ -1,13 +1,13 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Interbase data driver. Requires interbase client. Works on Windows and Unix.
@ -350,46 +350,26 @@ class ADODB_ibase extends ADOConnection {
$fn = 'ibase_execute';
$sql = $sql[1];
if (is_array($iarr)) {
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack
if ( !isset($iarr[0]) )
$iarr[0] = ''; // PHP5 compat hack
$fnarr = array_merge( array($sql) , $iarr);
$ret = call_user_func_array($fn,$fnarr);
} else {
switch(sizeof($iarr)) {
case 1: $ret = $fn($sql,$iarr[0]); break;
case 2: $ret = $fn($sql,$iarr[0],$iarr[1]); break;
case 3: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2]); break;
case 4: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
case 5: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
case 6: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
case 7: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
default: ADOConnection::outp( "Too many parameters to ibase query $sql");
case 8: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
}
else {
$ret = $fn($sql);
}
} else $ret = $fn($sql);
} else {
$fn = 'ibase_query';
if (is_array($iarr)) {
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
if (sizeof($iarr) == 0)
$iarr[0] = ''; // PHP5 compat hack
$fnarr = array_merge( array($conn,$sql) , $iarr);
$ret = call_user_func_array($fn,$fnarr);
} else {
switch(sizeof($iarr)) {
case 1: $ret = $fn($conn,$sql,$iarr[0]); break;
case 2: $ret = $fn($conn,$sql,$iarr[0],$iarr[1]); break;
case 3: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2]); break;
case 4: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
case 5: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
case 6: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
case 7: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
default: ADOConnection::outp( "Too many parameters to ibase query $sql");
case 8: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
}
else {
$ret = $fn($conn, $sql);
}
} else $ret = $fn($conn,$sql);
}
if ($docommit && $ret === true) {
ibase_commit($this->_connectionID);
@ -601,14 +581,8 @@ class ADODB_ibase extends ADOConnection {
function _BlobDecode( $blob )
{
if (ADODB_PHPVER >= 0x5000) {
$blob_data = ibase_blob_info($this->_connectionID, $blob );
$blobid = ibase_blob_open($this->_connectionID, $blob );
} else {
$blob_data = ibase_blob_info( $blob );
$blobid = ibase_blob_open( $blob );
}
if( $blob_data[0] > $this->maxblobsize ) {
@ -911,7 +885,7 @@ class ADORecordset_ibase extends ADORecordSet
case 'INT':
case 'SHORT':
case 'INTEGER': return 'I';
default: return 'N';
default: return ADODB_DEFAULT_METATYPE;
}
}

View file

@ -1,6 +1,6 @@
<?php
/**
* @version v5.20.16 12-Jan-2020
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
@ -9,7 +9,7 @@
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://adodb.org/
* Latest version is available at https://adodb.org/
*
* Informix 9 driver that supports SELECT FIRST
*
@ -33,9 +33,4 @@ class ADODB_informix extends ADODB_informix72 {
class ADORecordset_informix extends ADORecordset_informix72 {
var $databaseType = "informix";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim. All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Informix port by Mitchell T. Young (mitch@youngfamily.org)
@ -403,7 +403,7 @@ class ADORecordset_informix72 extends ADORecordSet {
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id);
parent::__construct($id);
}
@ -501,7 +501,7 @@ class ADORecordset_informix72 extends ADORecordSet {
}
/** !Eos
* Auxiliar function to Parse coltype,collength. Used by Metacolumns
* Auxiliary function to Parse coltype,collength. Used by Metacolumns
* return: array ($mtype,$length,$precision,$nullable) (similar to ifx_fieldpropierties)
*/
function ifx_props($coltype,$collength){

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -45,10 +45,6 @@ class ADODB_ldap extends ADOConnection {
# error on binding, eg. "Binding: invalid credentials"
var $_bind_errmsg = "Binding: %s";
function __construct()
{
}
// returns true or false
function _connect( $host, $username, $password, $ldapbase)
@ -331,7 +327,7 @@ class ADORecordSet_ldap extends ADORecordSet{
/*
Return whole recordset as a multi-dimensional associative array
*/
function GetAssoc($force_array = false, $first2cols = false)
function GetAssoc($force_array = false, $first2cols = false, $fetchMode = -1)
{
$records = $this->_numOfRows;
$results = array();

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Native mssql driver. Requires mssql client. Works on Windows.
To configure for Unix, see
@ -39,39 +39,7 @@ if (!defined('ADODB_DIR')) die();
//----------------------------------------------------------------
// has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
if (ADODB_PHPVER >= 0x4300) {
// docs say 4.2.0, but testing shows only since 4.3.0 does it work!
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';
}
}
class ADODB_mssql extends ADOConnection {
var $databaseType = "mssql";
@ -94,7 +62,6 @@ class ADODB_mssql extends ADOConnection {
var $hasGenID = true;
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
var $sysTimeStamp = 'GetDate()';
var $_has_mssql_init;
var $maxParameterLen = 4000;
var $arrayClass = 'ADORecordSet_array_mssql';
var $uniqueSort = true;
@ -107,11 +74,6 @@ class ADODB_mssql extends ADOConnection {
var $_bindInputArray = true;
var $forceNewConnect = false;
function __construct()
{
$this->_has_mssql_init = (strnatcmp(PHP_VERSION,'4.1.0')>=0);
}
function ServerInfo()
{
global $ADODB_FETCH_MODE;
@ -165,38 +127,23 @@ class ADODB_mssql extends ADOConnection {
/**
* Correctly quotes a string so that all strings are escaped. We prefix and append
* to the string single-quotes.
* An example is $db->qstr("Don't bother",magic_quotes_runtime());
* Correctly quotes a string so that all strings are escaped.
* We prefix and append to the string single-quotes.
* An example is $db->qstr("Don't bother");
*
* @param s the string to quote
* @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc().
* This undoes the stupidity of magic quotes for GPC.
* @param string $s The string to quote
* @param bool $magic_quotes This param is not used since 5.21.0.
* It remains for backwards compatibility.
*
* @return quoted string to be sent back to database
* @return string Quoted string to be sent back to database
*
* @noinspection PhpUnusedParameterInspection
*/
function qstr($s,$magic_quotes=false)
function qStr($s, $magic_quotes=false)
{
if (!$magic_quotes) {
return "'" . str_replace("'", $this->replaceQuote, $s) . "'";
}
// undo magic quotes for " unless sybase is on
$sybase = ini_get('magic_quotes_sybase');
if (!$sybase) {
$s = str_replace('\\"','"',$s);
if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything
return "'$s'";
else {// change \' to '' for sybase/mssql
$s = str_replace('\\\\','\\',$s);
return "'".str_replace("\\'",$this->replaceQuote,$s)."'";
}
} else {
return "'".$s."'";
}
}
// moodle change end - see readme_moodle.txt
function _affectedrows()
{
return $this->GetOne('select @@rowcount');
@ -309,7 +256,9 @@ class ADODB_mssql extends ADOConnection {
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
case 'l':
$s .= "datename(dw,$col)";
break;
default:
if ($ch == '\\') {
$i++;
@ -509,9 +458,13 @@ order by constraint_name, referenced_table_name, keyno";
foreach($arr as $k => $v) {
foreach($v as $a => $b) {
if ($upper) $a = strtoupper($a);
if (is_array($arr2[$a])) { // a previous foreign key was define for this reference table, we merge the new one
$arr2[$a] = array_merge($arr2[$a], $b);
} else {
$arr2[$a] = $b;
}
}
}
return $arr2;
}
@ -522,13 +475,15 @@ order by constraint_name, referenced_table_name, keyno";
$qry = $this->metaDatabasesSQL;
if($rs = @mssql_query($qry,$this->_connectionID)) {
$tmpAr = $ar = array();
while($tmpAr=@mssql_fetch_row($rs))
while($tmpAr = @mssql_fetch_row($rs)) {
$ar[]=$tmpAr[0];
}
@mssql_select_db($this->database);
if(sizeof($ar))
if(sizeof($ar)) {
return($ar);
else
} else {
return(false);
}
} else {
@mssql_select_db($this->database);
return(false);
@ -607,14 +562,18 @@ order by constraint_name, referenced_table_name, keyno";
if (!$id) return false;
$arr = mssql_fetch_array($id);
@mssql_free_result($id);
if (is_array($arr)) return $arr[0];
else return -1;
if (is_array($arr)) {
return $arr[0];
} else {
return -1;
}
}
// returns true or false, newconnect supported since php 5.1.0.
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$newconnect=false)
{
if (!function_exists('mssql_pconnect')) return null;
if (!empty($this->port)) $argHostname .= ":".$this->port;
$this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword,$newconnect);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
@ -626,6 +585,7 @@ order by constraint_name, referenced_table_name, keyno";
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('mssql_pconnect')) return null;
if (!empty($this->port)) $argHostname .= ":".$this->port;
$this->_connectionID = mssql_pconnect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
@ -656,10 +616,6 @@ order by constraint_name, referenced_table_name, keyno";
function PrepareSP($sql,$param=true)
{
if (!$this->_has_mssql_init) {
ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
return $sql;
}
$stmt = mssql_init($sql,$this->_connectionID);
if (!$stmt) return $sql;
return array($sql,$stmt);
@ -714,11 +670,6 @@ order by constraint_name, referenced_table_name, keyno";
*/
function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=4000, $type=false)
{
if (!$this->_has_mssql_init) {
ADOConnection::outp( "Parameter: mssql_bind only available since PHP 4.1.0");
return false;
}
$isNull = is_null($var); // php 4.0.4 and above...
if ($type === false)
@ -736,7 +687,7 @@ order by constraint_name, referenced_table_name, keyno";
ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
}
/*
See http://phplens.com/lens/lensforum/msgs.php?id=7231
See PHPLens Issue No: 7231
RETVAL is HARD CODED into php_mssql extension:
The return value (a long integer value) is treated like a special OUTPUT parameter,
@ -805,16 +756,16 @@ order by constraint_name, referenced_table_name, keyno";
$decl .= "@P$i NVARCHAR($len)";
}
if(substr($v,0,1) == "'" && substr($v,-1,1) == "'")
/*
* String is already fully quoted
*/
$inputVar = $v;
else
$inputVar = $this->qstr($v);
$inputVar = $db->this($v);
$params .= "@P$i=N" . $inputVar;
} else if (is_integer($v)) {
$decl .= "@P$i INT";
$params .= "@P$i=".$v;
@ -854,21 +805,42 @@ order by constraint_name, referenced_table_name, keyno";
// returns true or false
function _close()
{
if ($this->transCnt) $this->RollbackTrans();
$rez = @mssql_close($this->_connectionID);
if ($this->transCnt) {
$this->RollbackTrans();
}
if($this->_connectionID) {
$rez = mssql_close($this->_connectionID);
}
$this->_connectionID = false;
return $rez;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssql::UnixDate($v);
}
static function UnixTimeStamp($v)
/**
* Returns a substring of a varchar type field
*
* The SQL server version varies because the length is mandatory, so
* we append a reasonable string length
*
* @param string $fld The field to sub-string
* @param int $start The start point
* @param int $length An optional length
*
* @return The SQL text
*/
function substr($fld,$start,$length=0)
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
if ($length == 0)
/*
* The length available to varchar is 2GB, but that makes no
* sense in a substring, so I'm going to arbitrarily limit
* the length to 1K, but you could change it if you want
*/
$length = 1024;
$text = "SUBSTRING($fld,$start,$length)";
return $text;
}
}
@ -880,7 +852,7 @@ class ADORecordset_mssql extends ADORecordSet {
var $databaseType = "mssql";
var $canSeek = true;
var $hasFetchAssoc; // see http://phplens.com/lens/lensforum/msgs.php?id=6083
var $hasFetchAssoc; // see PHPLens Issue No: 6083
// _mths works only in non-localised system
function __construct($id,$mode=false)
@ -894,7 +866,7 @@ class ADORecordset_mssql extends ADORecordSet {
}
$this->fetchMode = $mode;
return parent::__construct($id,$mode);
return parent::__construct($id);
}
@ -1027,9 +999,9 @@ class ADORecordset_mssql extends ADORecordSet {
$this->fields = @mssql_fetch_assoc($this->_queryID);
else {
$this->fields = @mssql_fetch_array($this->_queryID);
if (@is_array($$this->fields)) {
if (@is_array($this->fields)) {
$fassoc = array();
foreach($$this->fields as $k => $v) {
foreach($this->fields as $k => $v) {
if (is_integer($k)) continue;
$fassoc[$k] = $v;
}
@ -1075,99 +1047,34 @@ class ADORecordset_mssql extends ADORecordSet {
return true;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
/**
* Returns the maximum size of a MetaType C field. Because of the
* database design, SQL Server places no limits on the size of data inserted
* Although the actual limit is 2^31-1 bytes.
*
* @return int
*/
function charMax()
{
return ADORecordSet_array_mssql::UnixDate($v);
return ADODB_STRINGMAX_NOLIMIT;
}
static function UnixTimeStamp($v)
/**
* Returns the maximum size of a MetaType X field. Because of the
* database design, SQL Server places no limits on the size of data inserted
* Although the actual limit is 2^31-1 bytes.
*
* @return int
*/
function textMax()
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
return ADODB_STRINGMAX_NOLIMIT;
}
}
class ADORecordSet_array_mssql extends ADORecordSet_array {
function __construct($id=-1,$mode=false)
{
parent::__construct($id,$mode);
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//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 parent::UnixDate($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 parent::UnixDate($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]);
}
static function UnixTimeStamp($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//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 parent::UnixTimeStamp($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 parent::UnixTimeStamp($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]);
}
}
class ADORecordSet_array_mssql extends ADORecordSet_array {}
/*
Code Example 1:

View file

@ -8,7 +8,7 @@
// //
// ADOdb - Database Abstraction Library for PHP //
// //
// Latest version is available at http://adodb.org //
// Latest version is available at https://adodb.org //
// //
// Copyright (c) 2000-2014 John Lim (jlim\@natsoft.com.my) //
// All rights reserved. //
@ -66,7 +66,7 @@ class ADODB_mssql_n extends ADODB_mssql {
* and ODBTP) keeping SQL compatibility at ADOdb level (instead of hacking every project to add
* the "N" notation when working against MSSQL.
*
* The orginal note indicated that this hack should only be used if ALL the char-based columns
* The original note indicated that this hack should only be used if ALL the char-based columns
* in your DB are of type nchar, nvarchar and ntext, but testing seems to indicate that SQL server
* doesn't seem to care if the statement is used against char etc fields.
*
@ -243,8 +243,4 @@ class ADODB_mssql_n extends ADODB_mssql {
class ADORecordset_mssql_n extends ADORecordset_mssql {
var $databaseType = "mssql_n";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Native mssql driver. Requires mssql client. Works on Windows.
http://www.microsoft.com/sql/technologies/php/default.mspx
@ -43,43 +43,6 @@ if (!function_exists('sqlsrv_log_set_subsystems')) {
}
}
//----------------------------------------------------------------
// MSSQL returns dates with the format Oct 13 2002 or 13 Oct 2002
// and this causes tons of problems because localized versions of
// MSSQL will return the dates in dmy or mdy order; and also the
// month strings depends on what language has been configured. The
// following two variables allow you to control the localization
// settings - Ugh.
//
// MORE LOCALIZATION INFO
// ----------------------
// To configure datetime, look for and modify sqlcommn.loc,
// typically found in c:\mssql\install
// Also read :
// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
// Alternatively use:
// CONVERT(char(12),datecol,120)
//
// Also if your month is showing as month-1,
// e.g. Jan 13, 2002 is showing as 13/0/2002, then see
// http://phplens.com/lens/lensforum/msgs.php?id=7048&x=1
// it's a localisation problem.
//----------------------------------------------------------------
// has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
if (ADODB_PHPVER >= 0x4300) {
// docs say 4.2.0, but testing shows only since 4.3.0 does it work!
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);
}
class ADODB_mssqlnative extends ADOConnection {
var $databaseType = "mssqlnative";
var $dataProvider = "mssqlnative";
@ -124,8 +87,10 @@ class ADODB_mssqlnative extends ADOConnection {
var $uniqueOrderBy = true;
var $_bindInputArray = true;
var $_dropSeqSQL = "drop table %s";
var $connectionInfo = array();
var $connectionInfo = array('ReturnDatesAsStrings'=>true);
var $cachedSchemaFlush = false;
var $sequences = false;
var $mssql_version = '';
@ -189,11 +154,9 @@ class ADODB_mssqlnative extends ADOConnection {
function _insertid()
{
// SCOPE_IDENTITY()
// Returns the last IDENTITY value inserted into an IDENTITY column in
// the same scope. A scope is a module -- a stored procedure, trigger,
// function, or batch. Thus, two statements are in the same scope if
// they are in the same stored procedure, function, or batch.
$rez = sqlsrv_query($this->_connectionID,$this->identitySQL);
sqlsrv_fetch($rez);
$this->lastInsertID = sqlsrv_get_field($rez, 0);
return $this->lastInsertID;
}
@ -204,8 +167,6 @@ class ADODB_mssqlnative extends ADOConnection {
}
function GenID($seq='adodbseq',$start=1) {
if (!$this->mssql_version)
$this->ServerVersion();
switch($this->mssql_version){
case 9:
case 10:
@ -219,9 +180,6 @@ class ADODB_mssqlnative extends ADOConnection {
function CreateSequence($seq='adodbseq',$start=1)
{
if (!$this->mssql_version)
$this->ServerVersion();
switch($this->mssql_version){
case 9:
case 10:
@ -231,7 +189,6 @@ class ADODB_mssqlnative extends ADOConnection {
return $this->CreateSequence2012($seq, $start);
break;
}
}
/**
@ -324,6 +281,20 @@ class ADODB_mssqlnative extends ADOConnection {
if (!$col) $col = $this->sysTimeStamp;
$s = '';
$ConvertableFmt=array(
"m/d/Y"=>101,"m/d/y"=>101 // US
,"Y.m.d"=>102,"y/m/d"=>102 // ANSI
,"d/m/Y"=>103,"d/m/y"=>103 // French /english
,"d.m.Y"=>104,"d.m.y"=>104 // German
,"d-m-Y"=>105,"d-m-y"=>105 // Italian
,"m-d-Y"=>110,"m-d-y"=>110 // US Dash
,"Y/m/d"=>111,"y/m/d"=>111 // Japan
,"Ymd"=>112,"ymd"=>112 // ISO
,"H:i:s"=>108 // Time
);
if(key_exists($fmt,$ConvertableFmt))
return "convert (varchar ,$col,".$ConvertableFmt[$fmt].")";
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '+';
@ -365,7 +336,9 @@ class ADODB_mssqlnative extends ADOConnection {
case 'A':
$s .= "substring(convert(char(19),$col,0),18,2)";
break;
case 'l':
$s .= "datename(dw,$col)";
break;
default:
if ($ch == '\\') {
$i++;
@ -397,6 +370,7 @@ class ADODB_mssqlnative extends ADOConnection {
sqlsrv_commit($this->_connectionID);
return true;
}
function RollbackTrans()
{
if ($this->transOff) return true;
@ -465,30 +439,75 @@ class ADODB_mssqlnative extends ADOConnection {
function ErrorNo()
{
$err = sqlsrv_errors(SQLSRV_ERR_ALL);
if($err[0]) return $err[0]['code'];
else return 0;
if ($err && $err[0])
return $err[0]['code'];
else
return 0;
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sqlsrv_connect')) return null;
if (!function_exists('sqlsrv_connect'))
{
if ($this->debug)
ADOConnection::outp('Microsoft SQL Server native driver (mssqlnative) not installed');
return null;
}
if (!empty($this->port))
/*
* Port uses a comma
*/
$argHostname .= ",".$this->port;
$connectionInfo = $this->connectionInfo;
$connectionInfo["Database"] = $argDatabasename;
if ((string)$argUsername != '' || (string)$argPassword != '')
{
/*
* If they pass either a userid or password, we assume
* SQL Server authentication
*/
$connectionInfo["UID"] = $argUsername;
$connectionInfo["PWD"] = $argPassword;
foreach ($this->connectionParameters as $parameter=>$value)
$connectionInfo[$parameter] = $value;
if ($this->debug)
ADOConnection::outp('userid or password supplied, attempting connection with SQL Server Authentication');
if ($this->debug) ADOConnection::outp("<hr>connecting... hostname: $argHostname params: ".var_export($connectionInfo,true));
//if ($this->debug) ADOConnection::outp("<hr>_connectionID before: ".serialize($this->_connectionID));
if(!($this->_connectionID = sqlsrv_connect($argHostname,$connectionInfo))) {
if ($this->debug) ADOConnection::outp( "<hr><b>errors</b>: ".print_r( sqlsrv_errors(), true));
}
else
{
/*
* If they don't pass either value, we won't add them to the
* connection parameters. This will then force an attempt
* to use windows authentication
*/
if ($this->debug)
ADOConnection::outp('No userid or password supplied, attempting connection with Windows Authentication');
}
/*
* Now merge in the passed connection parameters setting
*/
foreach ($this->connectionParameters as $options)
{
foreach($options as $parameter=>$value)
$connectionInfo[$parameter] = $value;
}
if ($this->debug) ADOConnection::outp("connecting to host: $argHostname params: ".var_export($connectionInfo,true));
if(!($this->_connectionID = @sqlsrv_connect($argHostname,$connectionInfo)))
{
if ($this->debug)
ADOConnection::outp( 'Connection Failed: '.print_r( sqlsrv_errors(), true));
return false;
}
//if ($this->debug) ADOConnection::outp(" _connectionID after: ".serialize($this->_connectionID));
//if ($this->debug) ADOConnection::outp("<hr>defined functions: <pre>".var_export(get_defined_functions(),true)."</pre>");
$this->ServerVersion();
return true;
}
@ -502,10 +521,6 @@ class ADODB_mssqlnative extends ADOConnection {
function Prepare($sql)
{
return $sql; // prepare does not work properly with bind parameters as bind parameters are managed by sqlsrv_prepare!
$stmt = sqlsrv_prepare( $this->_connectionID, $sql);
if (!$stmt) return $sql;
return array($sql,$stmt);
}
// returns concatenated string
@ -565,7 +580,8 @@ class ADODB_mssqlnative extends ADOConnection {
{
$this->_errorMsg = false;
if (is_array($sql)) $sql = $sql[1];
if (is_array($sql))
$sql = $sql[1];
$insert = false;
// handle native driver flaw for retrieving the last insert ID
@ -573,7 +589,14 @@ class ADODB_mssqlnative extends ADOConnection {
$insert = true;
$sql .= '; '.$this->identitySQL; // select scope_identity()
}
if($inputarr) {
if($inputarr)
{
/*
* Ensure that the input array is numeric, as required by
* sqlsrv_query. If param() was used to create portable binds
* then the array might be associative
*/
$inputarr = array_values($inputarr);
$rez = sqlsrv_query($this->_connectionID, $sql, $inputarr);
} else {
$rez = sqlsrv_query($this->_connectionID,$sql);
@ -581,37 +604,25 @@ class ADODB_mssqlnative extends ADOConnection {
if ($this->debug) ADOConnection::outp("<hr>running query: ".var_export($sql,true)."<hr>input array: ".var_export($inputarr,true)."<hr>result: ".var_export($rez,true));
if(!$rez) {
if(!$rez)
$rez = false;
} else if ($insert) {
// retrieve the last insert ID (where applicable)
while ( sqlsrv_next_result($rez) ) {
sqlsrv_fetch($rez);
$this->lastInsertID = sqlsrv_get_field($rez, 0);
}
}
return $rez;
}
// returns true or false
function _close()
{
if ($this->transCnt) $this->RollbackTrans();
$rez = @sqlsrv_close($this->_connectionID);
if ($this->transCnt) {
$this->RollbackTrans();
}
if($this->_connectionID) {
$rez = sqlsrv_close($this->_connectionID);
}
$this->_connectionID = false;
return $rez;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssqlnative::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssqlnative::UnixTimeStamp($v);
}
function MetaIndexes($table,$primary=false, $owner = false)
{
@ -670,7 +681,7 @@ class ADODB_mssqlnative extends ADOConnection {
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
$constraints =& $this->GetArray($sql);
$constraints = $this->GetArray($sql);
$ADODB_FETCH_MODE = $save;
@ -686,9 +697,13 @@ class ADODB_mssqlnative extends ADOConnection {
foreach($arr as $k => $v) {
foreach($v as $a => $b) {
if ($upper) $a = strtoupper($a);
if (is_array($arr2[$a])) { // a previous foreign key was define for this reference table, we merge the new one
$arr2[$a] = array_merge($arr2[$a], $b);
} else {
$arr2[$a] = $b;
}
}
}
return $arr2;
}
@ -752,7 +767,9 @@ class ADODB_mssqlnative extends ADOConnection {
}
function MetaColumns($table, $upper=true, $schema=false){
# start adg
/*
* A simple caching mechanism, to be replaced in ADOdb V6
*/
static $cached_columns = array();
if ($this->cachedSchemaFlush)
$cached_columns = array();
@ -760,10 +777,7 @@ class ADODB_mssqlnative extends ADOConnection {
if (array_key_exists($table,$cached_columns)){
return $cached_columns[$table];
}
# end adg
if (!$this->mssql_version)
$this->ServerVersion();
$this->_findschema($table,$schema);
if ($schema) {
@ -825,12 +839,126 @@ class ADODB_mssqlnative extends ADOConnection {
}
$rs->Close();
# start adg
$cached_columns[$table] = $retarr;
# end adg
return $retarr;
}
/**
* Returns a substring of a varchar type field
*
* The SQL server version varies because the length is mandatory, so
* we append a reasonable string length
*
* @param string $fld The field to sub-string
* @param int $start The start point
* @param int $length An optional length
*
* @return The SQL text
*/
function substr($fld,$start,$length=0)
{
if ($length == 0)
/*
* The length available to varchar is 2GB, but that makes no
* sense in a substring, so I'm going to arbitrarily limit
* the length to 1K, but you could change it if you want
*/
$length = 1024;
$text = "SUBSTRING($fld,$start,$length)";
return $text;
}
/**
* Returns the maximum size of a MetaType C field. Because of the
* database design, SQL Server places no limits on the size of data inserted
* Although the actual limit is 2^31-1 bytes.
*
* @return int
*/
function charMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/**
* Returns the maximum size of a MetaType X field. Because of the
* database design, SQL Server places no limits on the size of data inserted
* Although the actual limit is 2^31-1 bytes.
*
* @return int
*/
function textMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/**
* Lists procedures, functions and methods in an array.
*
* @param string $procedureNamePattern (optional)
* @param string $catalog (optional)
* @param string $schemaPattern (optional)
* @return array of stored objects in current database.
*
*/
public function metaProcedures($procedureNamePattern = null, $catalog = null, $schemaPattern = null)
{
$metaProcedures = array();
$procedureSQL = '';
$catalogSQL = '';
$schemaSQL = '';
if ($procedureNamePattern)
$procedureSQL = "AND ROUTINE_NAME LIKE " . strtoupper($this->qstr($procedureNamePattern));
if ($catalog)
$catalogSQL = "AND SPECIFIC_SCHEMA=" . strtoupper($this->qstr($catalog));
if ($schemaPattern)
$schemaSQL = "AND ROUTINE_SCHEMA LIKE {$this->qstr($schemaPattern)}";
$fields = " ROUTINE_NAME,ROUTINE_TYPE,ROUTINE_SCHEMA,ROUTINE_CATALOG";
$SQL = "SELECT $fields
FROM {$this->database}.information_schema.routines
WHERE 1=1
$procedureSQL
$catalogSQL
$schemaSQL
ORDER BY ROUTINE_NAME
";
$result = $this->execute($SQL);
if (!$result)
return false;
while ($r = $result->fetchRow()){
if (!isset($r[0]))
/*
* Convert to numeric
*/
$r = array_values($r);
$procedureName = $r[0];
$schemaName = $r[2];
$routineCatalog= $r[3];
$metaProcedures[$procedureName] = array('type'=> $r[1],
'catalog' => $routineCatalog,
'schema' => $schemaName,
'remarks' => '',
);
}
return $metaProcedures;
}
}
/*--------------------------------------------------------------------------------------
@ -844,77 +972,38 @@ class ADORecordset_mssqlnative extends ADORecordSet {
var $fieldOffset = 0;
// _mths works only in non-localised system
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$this->fetchMode = $mode;
return parent::__construct($id,$mode);
}
function _initrs()
{
global $ADODB_COUNTRECS;
# KMN # if ($this->connection->debug) ADOConnection::outp("(before) ADODB_COUNTRECS: {$ADODB_COUNTRECS} _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
/*$retRowsAff = sqlsrv_rows_affected($this->_queryID);//"If you need to determine the number of rows a query will return before retrieving the actual results, appending a SELECT COUNT ... query would let you get that information, and then a call to next_result would move you to the "real" results."
ADOConnection::outp("rowsaff: ".serialize($retRowsAff));
$this->_numOfRows = ($ADODB_COUNTRECS)? $retRowsAff:-1;*/
$this->_numOfRows = -1;//not supported
$fieldmeta = sqlsrv_field_metadata($this->_queryID);
$this->_numOfFields = ($fieldmeta)? count($fieldmeta):-1;
# KMN # if ($this->connection->debug) ADOConnection::outp("(after) _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
/*
* Copy the oracle method and cache the metadata at init time
* Holds a cached version of the metadata
*/
if ($this->_numOfFields>0) {
$this->_fieldobjs = array();
$max = $this->_numOfFields;
for ($i=0;$i<$max; $i++) $this->_fieldobjs[] = $this->_FetchField($i);
}
private $fieldObjects = false;
}
//Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
// get next resultset - requires PHP 4.0.5 or later
function NextRecordSet()
{
if (!sqlsrv_next_result($this->_queryID)) return false;
$this->_inited = false;
$this->bind = false;
$this->_currentRow = -1;
$this->Init();
return true;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if ($this->fetchMode != ADODB_FETCH_NUM) return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved.
Designed By jcortinap#jc.com.mx
/*
* Flags if we have retrieved the metadata
*/
function _FetchField($fieldOffset = -1)
{
$_typeConversion = array(
private $fieldObjectsRetrieved = false;
/*
* Cross-reference the objects by name for easy access
*/
private $fieldObjectsIndex = array();
/*
* Cross references the dateTime objects for faster decoding
*/
private $dateTimeObjects = array();
/*
* flags that we have dateTimeObjects to handle
*/
private $hasDateTimeObjects = false;
/*
* This is cross reference between how the types are stored
* in SQL Server and their english-language description
* -154 is a time field, see #432
*/
private $_typeConversion = array(
-155 => 'datetimeoffset',
-154 => 'char',
-152 => 'xml',
@ -942,43 +1031,132 @@ class ADORecordset_mssqlnative extends ADORecordSet {
93 => 'datetime'
);
$fa = @sqlsrv_field_metadata($this->_queryID);
if ($fieldOffset != -1) {
$fa = $fa[$fieldOffset];
function __construct($id,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
$false = false;
if (empty($fa)) {
$f = false;//PHP Notice: Only variable references should be returned by reference
$this->fetchMode = $mode;
parent::__construct($id);
}
function _initrs()
{
$this->_numOfRows = -1;//not supported
// Cache the metadata right now
$this->_fetchField();
}
//Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
// get next resultset - requires PHP 4.0.5 or later
function NextRecordSet()
{
if (!sqlsrv_next_result($this->_queryID)) return false;
$this->_inited = false;
$this->bind = false;
$this->_currentRow = -1;
$this->Init();
return true;
}
/* Use associative array to get fields array */
function Fields($colname)
{
if (!is_array($this->fields))
/*
* Too early
*/
return;
if ($this->fetchMode != ADODB_FETCH_NUM)
return $this->fields[$colname];
if (!$this->bind) {
$this->bind = array();
for ($i=0; $i < $this->_numOfFields; $i++) {
$o = $this->FetchField($i);
$this->bind[strtoupper($o->name)] = $i;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
/**
* Returns: an object containing field information.
*
* Get column information in the Recordset object. fetchField()
* can be used in order to obtain information about fields in a
* certain query result. If the field offset isn't specified,
* the next field that wasn't yet retrieved by fetchField()
* is retrieved.
*
* $param int $fieldOffset (optional default=-1 for all
* @return mixed an ADOFieldObject, or array of objects
*/
private function _fetchField($fieldOffset = -1)
{
if ($this->fieldObjectsRetrieved){
if ($this->fieldObjects) {
/*
* Already got the information
*/
if ($fieldOffset == -1)
return $this->fieldObjects;
else
return $this->fieldObjects[$fieldOffset];
}
else
{
// Convert to an object
$fa = array_change_key_case($fa, CASE_LOWER);
$fb = array();
if ($fieldOffset != -1)
{
$fb = array(
'name' => $fa['name'],
'max_length' => $fa['size'],
'column_source' => $fa['name'],
'type' => $_typeConversion[$fa['type']]
);
/*
* No metadata available
*/
return false;
}
else
$this->fieldObjectsRetrieved = true;
/*
* Retrieve all metadata in one go. This is always returned as a
* numeric array.
*/
$fieldMetaData = sqlsrv_field_metadata($this->_queryID);
if (!$fieldMetaData)
/*
* Not a statement that gives us metaData
*/
return false;
$this->_numOfFields = count($fieldMetaData);
foreach ($fieldMetaData as $key=>$value)
{
foreach ($fa as $key => $value)
{
$fb[] = array(
'name' => $value['name'],
'max_length' => $value['size'],
'column_source' => $value['name'],
'type' => $_typeConversion[$value['type']]
);
$fld = new ADOFieldObject;
/*
* Caution - keys are case-sensitive, must respect
* casing of values
*/
$fld->name = $value['Name'];
$fld->max_length = $value['Size'];
$fld->column_source = $value['Name'];
$fld->type = $this->_typeConversion[$value['Type']];
$this->fieldObjects[$key] = $fld;
$this->fieldObjectsIndex[$fld->name] = $key;
}
}
$f = (object) $fb;
}
return $f;
if ($fieldOffset == -1)
return $this->fieldObjects;
return $this->fieldObjects[$fieldOffset];
}
/*
@ -986,12 +1164,16 @@ class ADORecordset_mssqlnative extends ADORecordSet {
* into the _fieldobjs array once, to save multiple calls to the
* sqlsrv_field_metadata function
*
* @param int $fieldOffset (optional)
*
* @return adoFieldObject
*
* @author KM Newnham
* @date 02/20/2013
*/
function FetchField($fieldOffset = -1)
function fetchField($fieldOffset = -1)
{
return $this->_fieldobjs[$fieldOffset];
return $this->fieldObjects[$fieldOffset];
}
function _seek($row)
@ -1002,178 +1184,73 @@ class ADORecordset_mssqlnative extends ADORecordSet {
// speedup
function MoveNext()
{
//# KMN # if ($this->connection->debug) ADOConnection::outp("movenext()");
//# KMN # if ($this->connection->debug) ADOConnection::outp("eof (beginning): ".$this->EOF);
if ($this->EOF) return false;
if ($this->EOF)
return false;
$this->_currentRow++;
// # KMN # if ($this->connection->debug) ADOConnection::outp("_currentRow: ".$this->_currentRow);
if ($this->_fetch()) return true;
if ($this->_fetch())
return true;
$this->EOF = true;
//# KMN # if ($this->connection->debug) ADOConnection::outp("eof (end): ".$this->EOF);
return false;
}
// INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
// also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
function _fetch($ignore_fields=false)
{
# KMN # if ($this->connection->debug) ADOConnection::outp("_fetch()");
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
if ($this->fetchMode & ADODB_FETCH_NUM) {
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: both");
if ($this->fetchMode & ADODB_FETCH_NUM)
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_BOTH);
} else {
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: assoc");
else
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_ASSOC);
}
if (is_array($this->fields)) {
if (ADODB_ASSOC_CASE == 0) {
foreach($this->fields as $k=>$v) {
$this->fields[strtolower($k)] = $v;
}
} else if (ADODB_ASSOC_CASE == 1) {
foreach($this->fields as $k=>$v) {
$this->fields[strtoupper($k)] = $v;
if (is_array($this->fields))
{
if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER)
$this->fields = array_change_key_case($this->fields,CASE_LOWER);
else if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_UPPER)
$this->fields = array_change_key_case($this->fields,CASE_UPPER);
}
}
}
} else {
//# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: num");
else
$this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_NUMERIC);
}
if(is_array($this->fields) && array_key_exists(1,$this->fields) && !array_key_exists(0,$this->fields)) {//fix fetch numeric keys since they're not 0 based
$arrFixed = array();
foreach($this->fields as $key=>$value) {
if(is_numeric($key)) {
$arrFixed[$key-1] = $value;
} else {
$arrFixed[$key] = $value;
}
}
//if($this->connection->debug) ADOConnection::outp("<hr>fixing non 0 based return array, old: ".print_r($this->fields,true)." new: ".print_r($arrFixed,true));
$this->fields = $arrFixed;
}
if(is_array($this->fields)) {
foreach($this->fields as $key=>$value) {
if (is_object($value) && method_exists($value, 'format')) {//is DateTime object
$this->fields[$key] = $value->format("Y-m-d\TH:i:s\Z");
}
}
}
if($this->fields === null) $this->fields = false;
# KMN # if ($this->connection->debug) ADOConnection::outp("<hr>after _fetch, fields: <pre>".print_r($this->fields,true)." backtrace: ".adodb_backtrace(false));
if (!$this->fields)
return false;
return $this->fields;
}
/* close() only needs to be called if you are worried about using too much memory while your script
is running. All associated result memory for the specified result identifier will automatically be freed. */
/**
* close() only needs to be called if you are worried about using too much
* memory while your script is running. All associated result memory for
* the specified result identifier will automatically be freed.
*
* @return bool tru if we succeeded in closing down
*/
function _close()
{
/*
* If we are closing down a failed query, collect any
* error messages. This is a hack fix to the "close too early"
* problem so this might go away later
*/
$this->connection->errorMsg();
if(is_resource($this->_queryID)) {
$rez = sqlsrv_free_stmt($this->_queryID);
$this->_queryID = false;
return $rez;
}
return true;
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
return ADORecordSet_array_mssqlnative::UnixDate($v);
}
static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssqlnative::UnixTimeStamp($v);
}
}
class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
function __construct($id=-1,$mode=false)
{
parent::__construct($id,$mode);
}
// mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//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 parent::UnixDate($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 parent::UnixDate($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 adodb_mktime(0,0,0,$themth,$theday,$rr[3]);
}
static function UnixTimeStamp($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
//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 parent::UnixTimeStamp($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 parent::UnixTimeStamp($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 adodb_mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
}
}
class ADORecordSet_array_mssqlnative extends ADORecordSet_array {}
/*
Code Example 1:

View file

@ -1,6 +1,6 @@
<?php
/**
* @version v5.20.16 12-Jan-2020
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
@ -9,7 +9,7 @@
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://adodb.org/
* Latest version is available at https://adodb.org/
*
* Portable MSSQL Driver that supports || instead of +
*
@ -32,10 +32,6 @@ class ADODB_mssqlpo extends ADODB_mssql {
function PrepareSP($sql, $param = true)
{
if (!$this->_has_mssql_init) {
ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
return $sql;
}
if (is_string($sql)) $sql = str_replace('||','+',$sql);
$stmt = mssql_init($sql,$this->_connectionID);
if (!$stmt) return $sql;
@ -51,8 +47,4 @@ class ADODB_mssqlpo extends ADODB_mssql {
class ADORecordset_mssqlpo extends ADORecordset_mssql {
var $databaseType = "mssqlpo";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -9,7 +9,7 @@
Set tabs to 8.
This driver only supports the original non-transactional MySQL driver. It
is deprected in PHP version 5.5 and removed in PHP version 7. It is deprecated
is deprecated in PHP version 5.5 and removed in PHP version 7. It is deprecated
as of ADOdb version 5.20.0. Use the mysqli driver instead, which supports both
transactional and non-transactional updates
@ -51,14 +51,33 @@ class ADODB_mysql extends ADOConnection {
var $nameQuote = '`'; /// string to use to quote identifiers and names
var $compat323 = false; // true if compat with mysql 3.23
function __construct()
{
if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
/**
* ADODB_mysql constructor.
*/
public function __construct() {
if(version_compare(PHP_VERSION, '7.0.0', '>=')) {
$this->outp_throw(
'mysql extension is not supported since PHP 7.0.0, use mysqli instead',
__METHOD__
);
die(1); // Stop execution even if not using Exceptions
} elseif(version_compare(PHP_VERSION, '5.5.0', '>=')) {
// If mysql extension is available just print a warning,
// otherwise die with an error message
if(function_exists('mysql_connect')) {
$this->outp('mysql extension is deprecated since PHP 5.5.0, consider using mysqli');
} else {
$this->outp_throw(
'mysql extension is not available, use mysqli instead',
__METHOD__
);
die(1); // Stop execution even if not using Exceptions
}
}
}
// SetCharSet - switch the client encoding
function SetCharSet($charset_name)
function setCharSet($charset_name)
{
if (!function_exists('mysql_set_charset')) {
return false;
@ -75,19 +94,19 @@ class ADODB_mysql extends ADOConnection {
return true;
}
function ServerInfo()
function serverInfo()
{
$arr['description'] = ADOConnection::GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
function IfNull( $field, $ifNull )
function ifNull( $field, $ifNull )
{
return " IFNULL($field, $ifNull) "; // if MySQL
}
function MetaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
function metaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
@ -153,7 +172,7 @@ class ADODB_mysql extends ADOConnection {
*
* @return array list of tables
*/
function MetaTables($ttype=false,$showSchema=false,$mask=false)
function metaTables($ttype=false,$showSchema=false,$mask=false)
{
$save = $this->metaTablesSQL;
if ($showSchema && is_string($showSchema)) {
@ -173,7 +192,7 @@ class ADODB_mysql extends ADOConnection {
}
function MetaIndexes ($table, $primary = FALSE, $owner=false)
function metaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
@ -226,34 +245,41 @@ class ADODB_mysql extends ADOConnection {
}
// if magic quotes disabled, use mysql_real_escape_string()
function qstr($s,$magic_quotes=false)
/**
* Appropriately quotes strings with ' characters for insertion into the database.
*
* Relies on mysql_real_escape_string()
* @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:qstr
*
* @param string $s The string to quote
* @param bool $magic_quotes This param is not used since 5.21.0.
* It remains for backwards compatibility.
*
* @return string Quoted string
*/
function qStr($s, $magic_quotes=false)
{
if (is_null($s)) return 'NULL';
if (!$magic_quotes) {
if (is_null($s)) {
return 'NULL';
}
if (ADODB_PHPVER >= 0x4300) {
if (is_resource($this->_connectionID))
if (is_resource($this->_connectionID)) {
return "'" . mysql_real_escape_string($s, $this->_connectionID) . "'";
}
if ($this->replaceQuote[0] == '\\') {
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
$s = str_replace(array('\\', "\0"), array('\\\\', "\\\0"), $s);
}
return "'" . str_replace("'", $this->replaceQuote, $s) . "'";
}
// undo magic quotes for "
$s = str_replace('\\"','"',$s);
return "'$s'";
}
function _insertid()
{
return ADOConnection::GetOne('SELECT LAST_INSERT_ID()');
//return mysql_insert_id($this->_connectionID);
}
function GetOne($sql,$inputarr=false)
function getOne($sql,$inputarr=false)
{
global $ADODB_GETONE_EOF;
if ($this->compat323 == false && strncasecmp($sql,'sele',4) == 0) {
@ -269,7 +295,7 @@ class ADODB_mysql extends ADOConnection {
return false;
}
function BeginTrans()
function beginTrans()
{
if ($this->debug) ADOConnection::outp("Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver");
}
@ -287,7 +313,7 @@ class ADODB_mysql extends ADOConnection {
var $_genSeq2SQL = "insert into %s values (%s)";
var $_dropSeqSQL = "drop table if exists %s";
function CreateSequence($seqname='adodbseq',$startID=1)
function createSequence($seqname='adodbseq',$startID=1)
{
if (empty($this->_genSeqSQL)) return false;
$u = strtoupper($seqname);
@ -298,7 +324,7 @@ class ADODB_mysql extends ADOConnection {
}
function GenID($seqname='adodbseq',$startID=1)
function genID($seqname='adodbseq',$startID=1)
{
// post-nuke sets hasGenID to false
if (!$this->hasGenID) return false;
@ -327,7 +353,7 @@ class ADODB_mysql extends ADOConnection {
return $this->genID;
}
function MetaDatabases()
function metaDatabases()
{
$qid = mysql_list_dbs($this->_connectionID);
$arr = array();
@ -343,7 +369,7 @@ class ADODB_mysql extends ADOConnection {
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
function sqlDate($fmt, $col=false)
{
if (!$col) $col = $this->sysTimeStamp;
$s = 'DATE_FORMAT('.$col.",'";
@ -431,7 +457,7 @@ class ADODB_mysql extends ADOConnection {
// returns concatenated string
// much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
function Concat()
function concat()
{
$s = "";
$arr = func_get_args();
@ -442,7 +468,7 @@ class ADODB_mysql extends ADOConnection {
else return '';
}
function OffsetDate($dayFraction,$date=false)
function offsetDate($dayFraction,$date=false)
{
if (!$date) $date = $this->sysDate;
@ -455,19 +481,23 @@ class ADODB_mysql extends ADOConnection {
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!empty($this->port)) $argHostname .= ":".$this->port;
if (!empty($this->port))
$argHostname .= ":".$this->port;
if (ADODB_PHPVER >= 0x4300)
$this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
$this->forceNewConnect,$this->clientFlags);
else if (ADODB_PHPVER >= 0x4200)
$this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
$this->forceNewConnect);
else
$this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword);
$this->_connectionID =
mysql_connect($argHostname,
$argUsername,
$argPassword,
$this->forceNewConnect,
$this->clientFlags
);
if ($this->_connectionID === false)
return false;
if ($argDatabasename)
return $this->SelectDB($argDatabasename);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
}
@ -476,13 +506,18 @@ class ADODB_mysql extends ADOConnection {
{
if (!empty($this->port)) $argHostname .= ":".$this->port;
if (ADODB_PHPVER >= 0x4300)
$this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword,$this->clientFlags);
else
$this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($this->autoRollback) $this->RollbackTrans();
if ($argDatabasename) return $this->SelectDB($argDatabasename);
$this->_connectionID =
mysql_pconnect($argHostname,
$argUsername,
$argPassword,
$this->clientFlags);
if ($this->_connectionID === false)
return false;
if ($this->autoRollback)
$this->RollbackTrans();
if ($argDatabasename)
return $this->SelectDB($argDatabasename);
return true;
}
@ -492,7 +527,7 @@ class ADODB_mysql extends ADOConnection {
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
function MetaColumns($table, $normalize=true)
function metaColumns($table, $normalize=true)
{
$this->_findschema($table,$schema);
if ($schema) {
@ -572,7 +607,7 @@ class ADODB_mysql extends ADOConnection {
}
// returns true or false
function SelectDB($dbName)
function selectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
@ -583,12 +618,12 @@ class ADODB_mysql extends ADOConnection {
}
// parameters use PostgreSQL convention, not MySQL
function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
function selectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
{
$nrows = (int) $nrows;
$offset = (int) $offset;
$offsetStr =($offset>=0) ? ((integer)$offset)."," : '';
// jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
// jason judge, see PHPLens Issue No: 9220
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
@ -613,7 +648,7 @@ class ADODB_mysql extends ADOConnection {
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
function errorMsg()
{
if ($this->_logsql) return $this->_errorMsg;
@ -623,7 +658,7 @@ class ADODB_mysql extends ADOConnection {
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
function errorNo()
{
if ($this->_logsql) return $this->_errorCode;
if (empty($this->_connectionID)) return @mysql_errno();
@ -643,7 +678,7 @@ class ADODB_mysql extends ADOConnection {
/*
* Maximum size of C field
*/
function CharMax()
function charMax()
{
return 255;
}
@ -651,13 +686,13 @@ class ADODB_mysql extends ADOConnection {
/*
* Maximum size of X field
*/
function TextMax()
function textMax()
{
return 4294967295;
}
// "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
function metaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
{
global $ADODB_FETCH_MODE;
if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode == ADODB_FETCH_ASSOC) $associative = true;
@ -743,7 +778,7 @@ class ADORecordSet_mysql extends ADORecordSet{
$this->_numOfFields = @mysql_num_fields($this->_queryID);
}
function FetchField($fieldOffset = -1)
function fetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$o = @mysql_fetch_field($this->_queryID, $fieldOffset);
@ -761,7 +796,7 @@ class ADORecordSet_mysql extends ADORecordSet{
return $o;
}
function GetRowAssoc($upper = ADODB_ASSOC_CASE)
function getRowAssoc($upper = ADODB_ASSOC_CASE)
{
if ($this->fetchMode == MYSQL_ASSOC && $upper == ADODB_ASSOC_CASE_LOWER) {
$row = $this->fields;
@ -773,7 +808,7 @@ class ADORecordSet_mysql extends ADORecordSet{
}
/* Use associative array to get fields array */
function Fields($colname)
function fields($colname)
{
// added @ by "Michael William Miller" <mille562@pilot.msu.edu>
if ($this->fetchMode != MYSQL_NUM) return @$this->fields[$colname];
@ -794,10 +829,8 @@ class ADORecordSet_mysql extends ADORecordSet{
return @mysql_data_seek($this->_queryID,$row);
}
function MoveNext()
function moveNext()
{
//return adodb_movenext($this);
//if (defined('ADODB_EXTENSION')) return adodb_movenext($this);
if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
$this->_updatefields();
$this->_currentRow += 1;
@ -822,7 +855,7 @@ class ADORecordSet_mysql extends ADORecordSet{
$this->_queryID = false;
}
function MetaType($t,$len=-1,$fieldobj=false)
function metaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
@ -872,19 +905,18 @@ class ADORecordSet_mysql extends ADORecordSet{
if (!empty($fieldobj->primary_key)) return 'R';
else return 'I';
default: return 'N';
default: return ADODB_DEFAULT_METATYPE;
}
}
}
/**
* Class ADORecordSet_ext_mysql
*/
class ADORecordSet_ext_mysql extends ADORecordSet_mysql {
function __construct($queryID,$mode=false)
{
parent::__construct($queryID,$mode);
}
function MoveNext()
function moveNext()
{
return @adodb_movenext($this);
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -32,11 +32,6 @@ class ADODB_mysqlt extends ADODB_mysql {
var $hasTransactions = true;
var $autoRollback = true; // apparently mysql does not autorollback properly
function __construct()
{
global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 'ext_';
}
function BeginTrans()
{
if ($this->transOff) return true;
@ -116,11 +111,6 @@ class ADORecordSet_mysqlt extends ADORecordSet_mysql{
class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
function __construct($queryID,$mode=false)
{
parent::__construct($queryID,$mode);
}
function MoveNext()
{
return adodb_movenext($this);

View file

@ -1,7 +1,7 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -10,7 +10,7 @@
Set tabs to 8.
This driver only supports the original MySQL driver in transactional mode. It
is deprected in PHP version 5.5 and removed in PHP version 7. It is deprecated
is deprecated in PHP version 5.5 and removed in PHP version 7. It is deprecated
as of ADOdb version 5.20.0. Use the mysqli driver instead, which supports both
transactional and non-transactional updates
@ -29,11 +29,6 @@ class ADODB_mysqlt extends ADODB_mysql {
var $hasTransactions = true;
var $autoRollback = true; // apparently mysql does not autorollback properly
function __construct()
{
global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 'ext_';
}
/* set transaction mode
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
@ -14,7 +14,7 @@
Fixed the way data types and lengths are returned in MetaColumns()
as well as added the default lengths for certain types
Updated public variables for Netezza
Still need to remove blob functions, as Netezza doesn't suppport blob
Still need to remove blob functions, as Netezza doesn't support blob
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
@ -50,11 +50,6 @@ class ADODB_netezza extends ADODB_postgres64 {
// http://bugs.php.net/bug.php?id=25404
function __construct()
{
}
function MetaColumns($table,$upper=true)
{
@ -141,11 +136,6 @@ class ADORecordSet_netezza extends ADORecordSet_postgres64
var $databaseType = "netezza";
var $canSeek = true;
function __construct($queryID,$mode=false)
{
parent::__construct($queryID,$mode);
}
// _initrs modified to disable blob handling
function _initrs()
{

View file

@ -1,7 +1,7 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim. All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
@ -9,7 +9,7 @@
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Code contributed by George Fourlanos <fou@infomap.gr>
@ -89,7 +89,6 @@ END;
var $connectSID = false;
var $_bind = false;
var $_nestedSQL = true;
var $_hasOciFetchStatement = false;
var $_getarray = false; // currently not working
var $leftOuter = ''; // oracle wierdness, $col = $value (+) for LEFT OUTER, $col (+)= $value for RIGHT OUTER
var $session_sharing_force_blob = false; // alter session on updateblob if set to true
@ -103,13 +102,20 @@ END;
// var $ansiOuter = true; // if oracle9
function __construct()
{
$this->_hasOciFetchStatement = ADODB_PHPVER >= 0x4200;
if (defined('ADODB_EXTENSION')) {
$this->rsPrefix .= 'ext_';
}
}
/*
* Legacy compatibility for sequence names for emulated auto-increments
*/
public $useCompactAutoIncrements = false;
/*
* Defines the schema name for emulated auto-increment columns
*/
public $schema = false;
/*
* Defines the prefix for emulated auto-increment columns
*/
public $seqPrefix = 'SEQ_';
/* function MetaColumns($table, $normalize=true) added by smondino@users.sourceforge.net*/
function MetaColumns($table, $normalize=true)
@ -308,6 +314,43 @@ END;
return " NVL($field, $ifNull) "; // if Oracle
}
function _insertid($tabname,$column='')
{
if (!$this->seqField)
return false;
if ($this->schema)
{
$t = strpos($tabname,'.');
if ($t !== false)
$tab = substr($tabname,$t+1);
else
$tab = $tabname;
if ($this->useCompactAutoIncrements)
$tab = sprintf('%u',crc32(strtolower($tab)));
$seqname = $this->schema.'.'.$this->seqPrefix.$tab;
}
else
{
if ($this->useCompactAutoIncrements)
$tabname = sprintf('%u',crc32(strtolower($tabname)));
$seqname = $this->seqPrefix.$tabname;
}
if (strlen($seqname) > 30)
/*
* We cannot successfully identify the sequence
*/
return false;
return $this->getOne("SELECT $seqname.currval FROM dual");
}
// format and return date string in database date format
function DBDate($d,$isfld=false)
{
@ -947,7 +990,7 @@ END;
$element0 = reset($inputarr);
$array2d = $this->bulkBind && is_array($element0) && !is_object(reset($element0));
# see http://phplens.com/lens/lensforum/msgs.php?id=18786
# see PHPLens Issue No: 18786
if ($array2d || !$this->_bindInputArray) {
# is_object check because oci8 descriptors can be passed in
@ -1497,39 +1540,29 @@ SELECT /*+ RULE */ distinct b.column_name
}
/**
* Quotes a string.
* An example is $db->qstr("Don't bother",magic_quotes_runtime());
* Correctly quotes a string so that all strings are escaped.
* We prefix and append to the string single-quotes.
* An example is $db->qstr("Don't bother");
*
* @param string $s the string to quote
* @param bool $magic_quotes if $s is GET/POST var, set to get_magic_quotes_gpc().
* This undoes the stupidity of magic quotes for GPC.
* @param string $s The string to quote
* @param bool $magic_quotes This param is not used since 5.21.0.
* It remains for backwards compatibility.
*
* @return string quoted string to be sent back to database
* @return string Quoted string to be sent back to database
*
* @noinspection PhpUnusedParameterInspection
*/
function qstr($s,$magic_quotes=false)
function qStr($s, $magic_quotes=false)
{
//$nofixquotes=false;
if ($this->noNullStrings && strlen($s) == 0) {
$s = ' ';
}
if (!$magic_quotes) {
if ($this->replaceQuote[0] == '\\'){
$s = str_replace('\\','\\\\',$s);
}
return "'" . str_replace("'", $this->replaceQuote, $s) . "'";
}
// undo magic quotes for " unless sybase is on
if (!ini_get('magic_quotes_sybase')) {
$s = str_replace('\\"','"',$s);
$s = str_replace('\\\\','\\',$s);
return "'".str_replace("\\'",$this->replaceQuote,$s)."'";
} else {
return "'".$s."'";
}
}
}
/*--------------------------------------------------------------------------------------
@ -1591,7 +1624,7 @@ class ADORecordset_oci8 extends ADORecordSet {
/*
// based on idea by Gaetano Giunta to detect unusual oracle errors
// see http://phplens.com/lens/lensforum/msgs.php?id=6771
// see PHPLens Issue No: 6771
$err = oci_error($this->_queryID);
if ($err && $this->connection->debug) {
ADOConnection::outp($err);
@ -1751,6 +1784,7 @@ class ADORecordset_oci8 extends ADORecordSet {
oci_free_cursor($this->_refcursor);
$this->_refcursor = false;
}
if (is_resource($this->_queryID))
@oci_free_statement($this->_queryID);
$this->_queryID = false;
}
@ -1808,16 +1842,12 @@ class ADORecordset_oci8 extends ADORecordSet {
return 'I';
default:
return 'N';
return ADODB_DEFAULT_METATYPE;
}
}
}
class ADORecordSet_ext_oci8 extends ADORecordSet_oci8 {
function __construct($queryID,$mode=false)
{
parent::__construct($queryID, $mode);
}
function MoveNext()
{

View file

@ -1,6 +1,6 @@
<?php
/**
* @version v5.20.16 12-Jan-2020
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
* Released under both BSD license and Lesser GPL library license.
@ -9,7 +9,7 @@
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://adodb.org/
* Latest version is available at https://adodb.org/
*
* Oracle 8.0.5 driver
*/
@ -48,8 +48,4 @@ class ADODB_oci805 extends ADODB_oci8 {
class ADORecordset_oci805 extends ADORecordset_oci8 {
var $databaseType = "oci805";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}

View file

@ -1,13 +1,13 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim. All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Portable version of oci8 driver, to make it more similar to other database drivers.
The main differences are
@ -30,12 +30,6 @@ class ADODB_oci8po extends ADODB_oci8 {
var $metaColumnsSQL = "select lower(cname),coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno"; //changed by smondino@users.sourceforge. net
var $metaTablesSQL = "select lower(table_name),table_type from cat where table_type in ('TABLE','VIEW')";
function __construct()
{
$this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
# oci8po does not support adodb extension: adodb_movenext()
}
function Param($name,$type='C')
{
return '?';
@ -86,6 +80,7 @@ class ADODB_oci8po extends ADODB_oci8 {
}
return ADODB_oci8::_query($sql,$inputarr);
}
/**
* Replaces compatibility bind markers with oracle ones and returns a
* valid sql statement
@ -173,11 +168,6 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
var $databaseType = 'oci8po';
function __construct($queryID,$mode=false)
{
parent::__construct($queryID,$mode);
}
function Fields($colname)
{
if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname];

View file

@ -1,13 +1,13 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim. All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Portable version of oci8 driver, to make it more similar to other database drivers.
The main differences are
@ -28,10 +28,6 @@ class ADODB_oci8quercus extends ADODB_oci8 {
var $databaseType = 'oci8quercus';
var $dataProvider = 'oci8';
function __construct()
{
}
}
/*--------------------------------------------------------------------------------------
@ -42,11 +38,6 @@ class ADORecordset_oci8quercus extends ADORecordset_oci8 {
var $databaseType = 'oci8quercus';
function __construct($queryID,$mode=false)
{
parent::__construct($queryID,$mode);
}
function _FetchField($fieldOffset = -1)
{
global $QUERCUS;

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Requires ODBC. Works on Windows and Unix.
*/
@ -17,6 +17,18 @@ if (!defined('ADODB_DIR')) die();
define("_ADODB_ODBC_LAYER", 2 );
/*
* These constants are used to set define MetaColumns() method's behavior.
* - METACOLUMNS_RETURNS_ACTUAL makes the driver return the actual type,
* like all other drivers do (default)
* - METACOLUMNS_RETURNS_META is provided for legacy compatibility (makes
* driver behave as it did prior to v5.21)
*
* @see $metaColumnsReturnType
*/
DEFINE('METACOLUMNS_RETURNS_ACTUAL', 0);
DEFINE('METACOLUMNS_RETURNS_META', 1);
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
@ -36,16 +48,15 @@ class ADODB_odbc extends ADOConnection {
var $curmode = SQL_CUR_USE_DRIVER; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
var $_genSeqSQL = "create table %s (id integer)";
var $_autocommit = true;
var $_haserrorfunctions = true;
var $_has_stupid_odbc_fetch_api_change = true;
var $_lastAffectedRows = 0;
var $uCaseTables = true; // for meta* functions, uppercase table names
function __construct()
{
$this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
}
/*
* Tells the metaColumns feature whether to return actual or meta type
*/
public $metaColumnsReturnType = METACOLUMNS_RETURNS_ACTUAL;
function __construct() {}
// returns true or false
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
@ -93,7 +104,7 @@ class ADODB_odbc extends ADOConnection {
function ServerInfo()
{
if (!empty($this->host) && ADODB_PHPVER >= 0x4300) {
if (!empty($this->host)) {
$dsn = strtoupper($this->host);
$first = true;
$found = false;
@ -180,17 +191,13 @@ class ADODB_odbc extends ADOConnection {
function ErrorMsg()
{
if ($this->_haserrorfunctions) {
if ($this->_errorMsg !== false) return $this->_errorMsg;
if (empty($this->_connectionID)) return @odbc_errormsg();
return @odbc_errormsg($this->_connectionID);
} else return ADOConnection::ErrorMsg();
}
function ErrorNo()
{
if ($this->_haserrorfunctions) {
if ($this->_errorCode !== false) {
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
@ -203,7 +210,6 @@ class ADODB_odbc extends ADOConnection {
// so we check and patch
if (strlen($e)<=2) return 0;
return $e;
} else return ADOConnection::ErrorNo();
}
@ -258,7 +264,6 @@ class ADODB_odbc extends ADOConnection {
$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();
@ -287,7 +292,6 @@ class ADODB_odbc extends ADOConnection {
$false = false;
return $false;
}
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$arr = $rs->GetArray();
//print_r($arr);
@ -390,12 +394,11 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
$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
/*if (false) { // after testing, confirmed that the following does not work because 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) {
@ -434,7 +437,6 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
$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();
@ -459,7 +461,16 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[3];
if ($this->metaColumnsReturnType == METACOLUMNS_RETURNS_META)
/*
* This is the broken, original value
*/
$fld->type = $this->ODBCTypes($rs->fields[4]);
else
/*
* This is the correct new value
*/
$fld->type = $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
@ -516,10 +527,8 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
if (! odbc_execute($stmtid,$inputarr)) {
//@odbc_free_result($stmtid);
if ($this->_haserrorfunctions) {
$this->_errorMsg = odbc_errormsg();
$this->_errorCode = odbc_error();
}
return false;
}
@ -527,10 +536,8 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
$stmtid = $sql[1];
if (!odbc_execute($stmtid)) {
//@odbc_free_result($stmtid);
if ($this->_haserrorfunctions) {
$this->_errorMsg = odbc_errormsg();
$this->_errorCode = odbc_error();
}
return false;
}
} else
@ -547,19 +554,11 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
odbc_longreadlen($stmtid,$this->maxblobsize);
}
if ($this->_haserrorfunctions) {
$this->_errorMsg = '';
$this->_errorCode = 0;
} else {
$this->_errorMsg = $this->getChangedErrorMsg($last_php_error);
}
} else {
if ($this->_haserrorfunctions) {
$this->_errorMsg = odbc_errormsg();
$this->_errorCode = odbc_error();
} else {
$this->_errorMsg = $this->getChangedErrorMsg($last_php_error);
}
}
return $stmtid;
}
@ -603,7 +602,6 @@ class ADORecordSet_odbc extends ADORecordSet {
var $databaseType = "odbc";
var $dataProvider = "odbc";
var $useFetchArray;
var $_has_stupid_odbc_fetch_api_change;
function __construct($id,$mode=false)
{
@ -661,7 +659,6 @@ class ADORecordSet_odbc extends ADORecordSet {
// some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
if ($this->_numOfRows == 0) $this->_numOfRows = -1;
//$this->useFetchArray = $this->connection->useFetchArray;
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
}
function _seek($row)
@ -712,12 +709,7 @@ class ADORecordSet_odbc extends ADORecordSet {
function _fetch()
{
$this->fields = false;
if ($this->_has_stupid_odbc_fetch_api_change)
$rez = @odbc_fetch_into($this->_queryID,$this->fields);
else {
$row = 0;
$rez = @odbc_fetch_into($this->_queryID,$row,$this->fields);
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
$this->fields = $this->GetRowAssoc();

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
DB2 data driver. Requires ODBC.
@ -28,7 +28,7 @@ to SQL_CUR_USE_ODBC Cursor Type, then
the whole query speed up from 1 till 10 seconds
to 0.2 till 0.3 seconds for 100 records. Amazing!!!
Therfore, PHP is just almost fast as calling the DB2
Therefore, PHP is just almost fast as calling the DB2
from Servlets using JDBC (don't take too much care
about the speed at whole: the database was on a
completely other location, so the whole connection
@ -92,7 +92,7 @@ to DB2 full rights to the DB2 SQLLIB directory, and place the user in the DBUSER
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ODBC_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
if (!defined('ADODB_ODBC_DB2')){
define('ADODB_ODBC_DB2',1);
@ -157,7 +157,6 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
$false = false;
return $false;
}
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$arr = $rs->GetArray();
//print_r($arr);
@ -306,11 +305,6 @@ class ADORecordSet_odbc_db2 extends ADORecordSet_odbc {
var $databaseType = "db2";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
function MetaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
@ -361,7 +355,7 @@ class ADORecordSet_odbc_db2 extends ADORecordSet_odbc {
case 'I':
return 'I';
default: return 'N';
default: return ADODB_DEFAULT_METATYPE;
}
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
MSSQL support via ODBC. Requires ODBC. Works on Windows and Unix.
For Unix configuration, see http://phpbuilder.com/columns/alberto20000919.php3
@ -18,7 +18,7 @@ Set tabs to 4 for best viewing.
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ODBC_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
@ -47,12 +47,6 @@ class ADODB_odbc_mssql extends ADODB_odbc {
var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL OFF'; # When SET CONCAT_NULL_YIELDS_NULL is ON,
# concatenating a null value with a string yields a NULL result
function __construct()
{
parent::__construct();
//$this->curmode = SQL_CUR_USE_ODBC;
}
// crashes php...
function ServerInfo()
{
@ -352,14 +346,89 @@ order by constraint_name, referenced_table_name, keyno";
return $s;
}
/**
* Returns a substring of a varchar type field
*
* The SQL server version varies because the length is mandatory, so
* we append a reasonable string length
*
* @param string $fld The field to sub-string
* @param int $start The start point
* @param int $length An optional length
*
* @return The SQL text
*/
function substr($fld,$start,$length=0)
{
if ($length == 0)
/*
* The length available to varchar is 2GB, but that makes no
* sense in a substring, so I'm going to arbitrarily limit
* the length to 1K, but you could change it if you want
*/
$length = 1024;
$text = "SUBSTRING($fld,$start,$length)";
return $text;
}
/**
* Returns the maximum size of a MetaType C field. Because of the
* database design, SQL Server places no limits on the size of data inserted
* Although the actual limit is 2^31-1 bytes.
*
* @return int
*/
function charMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/**
* Returns the maximum size of a MetaType X field. Because of the
* database design, SQL Server places no limits on the size of data inserted
* Although the actual limit is 2^31-1 bytes.
*
* @return int
*/
function textMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
// returns concatenated string
// MSSQL requires integers to be cast as strings
// automatically cast every datatype to VARCHAR(255)
// @author David Rogers (introspectshun)
function Concat()
{
$s = "";
$arr = func_get_args();
// Split single record on commas, if possible
if (sizeof($arr) == 1) {
foreach ($arr as $arg) {
$args = explode(',', $arg);
}
$arr = $args;
}
array_walk(
$arr,
function(&$value, $key) {
$value = "CAST(" . $value . " AS VARCHAR(255))";
}
);
$s = implode('+',$arr);
if (sizeof($arr) > 0) return "$s";
return '';
}
}
class ADORecordSet_odbc_mssql extends ADORecordSet_odbc {
var $databaseType = 'odbc_mssql';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}

View file

@ -0,0 +1,28 @@
<?php
/*
@version v5.21.0 2021-02-27
@copyright (c) 2015 Damien Regad, Mark Newnham and the ADOdb community
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.
Microsoft SQL Server 2012 via ODBC
*/
if (!defined('ADODB_DIR'))
die();
include_once(ADODB_DIR."/drivers/adodb-odbc_mssql.inc.php");
class ADODB_odbc_mssql2012 extends ADODB_odbc_mssql
{
/*
* Makes behavior similar to prior versions of SQL Server
*/
var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL ON';
}
class ADORecordSet_odbc_mssql2012 extends ADORecordSet_odbc_mssql
{
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Oracle support via ODBC. Requires ODBC. Works on Windows.
*/
@ -16,7 +16,7 @@ Set tabs to 4 for best viewing.
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ODBC_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
@ -101,8 +101,4 @@ class ADORecordSet_odbc_oracle extends ADORecordSet_odbc {
var $databaseType = 'odbc_oracle';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}

View file

@ -1,13 +1,13 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.org/
Latest version is available at https://adodb.org/
*/
// Code contributed by "stefan bogdan" <sbogdan#rsb.ro>
@ -35,10 +35,6 @@ class ADODB_odbtp extends ADOConnection{
var $_canPrepareSP = false;
var $_dontPoolDBC = true;
function __construct()
{
}
function ServerInfo()
{
return array('description' => @odbtp_get_attr( ODB_ATTR_DBMSNAME, $this->_connectionID),
@ -792,48 +788,28 @@ class ADORecordSet_odbtp_mssql extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_mssql';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
class ADORecordSet_odbtp_access extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_access';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
class ADORecordSet_odbtp_vfp extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_vfp';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
class ADORecordSet_odbtp_oci8 extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_oci8';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}
class ADORecordSet_odbtp_sybase extends ADORecordSet_odbtp {
var $databaseType = 'odbtp_sybase';
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
}

View file

@ -1,13 +1,13 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.org/
Latest version is available at https://adodb.org/
*/
// Code contributed by "Robert Twitty" <rtwitty#neutron.ushmm.org>
@ -26,7 +26,7 @@ if (!defined('ADODB_DIR')) die();
*/
if (!defined('_ADODB_ODBTP_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbtp.inc.php");
include_once(ADODB_DIR."/drivers/adodb-odbtp.inc.php");
}
class ADODB_odbtp_unicode extends ADODB_odbtp {

View file

@ -1,13 +1,13 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Oracle data driver. Requires Oracle client. Works on Windows and Unix and Oracle 7.
@ -29,10 +29,6 @@ class ADODB_oracle extends ADOConnection {
var $sysTimeStamp = 'SYSDATE';
var $connectSID = true;
function __construct()
{
}
// format and return date string in database date format
function DBDate($d, $isfld = false)
{

View file

@ -1,6 +1,6 @@
<?php
/**
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
@ -10,7 +10,7 @@
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Requires ODBC. Works on Windows and Unix.
@ -77,7 +77,6 @@ class ADODB_pdo extends ADOConnection {
var $_genSeqSQL = "create table %s (id integer)";
var $_dropSeqSQL;
var $_autocommit = true;
var $_haserrorfunctions = true;
var $_lastAffectedRows = 0;
var $_errormsg = false;
@ -87,9 +86,12 @@ class ADODB_pdo extends ADOConnection {
var $stmt = false;
var $_driver;
function __construct()
{
}
/*
* Describe parameters passed directly to the PDO driver
*
* @example $db->pdoOptions = [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION];
*/
public $pdoParameters = array();
function _UpdatePDO()
{
@ -102,6 +104,7 @@ class ADODB_pdo extends ADOConnection {
$this->random = $d->random;
$this->concat_operator = $d->concat_operator;
$this->nameQuote = $d->nameQuote;
$this->arrayClass = $d->arrayClass;
$this->hasGenID = $d->hasGenID;
$this->_genIDSQL = $d->_genIDSQL;
@ -144,12 +147,22 @@ class ADODB_pdo extends ADOConnection {
case 'oci':
case 'pgsql':
case 'sqlite':
case 'firebird':
default:
$argDSN .= ';dbname='.$argDatabasename;
}
}
/*
* Configure for persistent connection if required,
* by adding the the pdo parameter into any provided
* ones
*/
if ($persist) {
$this->pdoParameters[\PDO::ATTR_PERSISTENT] = true;
}
try {
$this->_connectionID = new PDO($argDSN, $argUsername, $argPassword);
$this->_connectionID = new \PDO($argDSN, $argUsername, $argPassword, $this->pdoParameters);
} catch (Exception $e) {
$this->_connectionID = false;
$this->_errorno = -1;
@ -175,6 +188,16 @@ class ADODB_pdo extends ADOConnection {
//$this->_connectionID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT );
$this->_connectionID->setAttribute(PDO::ATTR_CASE,$m);
// Now merge in any provided attributes for PDO
foreach ($this->connectionParameters as $options) {
foreach($options as $k=>$v) {
if ($this->debug) {
ADOconnection::outp('Setting attribute: ' . $k . ' to ' . $v);
}
$this->_connectionID->setAttribute($k,$v);
}
}
$class = 'ADODB_pdo_'.$this->dsnType;
//$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
switch($this->dsnType) {
@ -184,6 +207,8 @@ class ADODB_pdo extends ADOConnection {
case 'pgsql':
case 'sqlite':
case 'sqlsrv':
case 'firebird':
case 'dblib':
include_once(ADODB_DIR.'/drivers/adodb-pdo_'.$this->dsnType.'.inc.php');
break;
}
@ -210,11 +235,8 @@ class ADODB_pdo extends ADOConnection {
return call_user_func_array(array($this->_driver, 'Concat'), $args);
}
if (PHP_VERSION >= 5.3) {
return call_user_func_array('parent::Concat', $args);
}
return call_user_func_array(array($this,'parent::Concat'), $args);
}
// returns true or false
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
@ -251,6 +273,64 @@ class ADODB_pdo extends ADOConnection {
return $this->_driver->MetaColumns($table,$normalize);
}
public function metaIndexes($table,$normalize=true)
{
if (method_exists($this->_driver,'metaIndexes'))
return $this->_driver->metaIndexes($table,$normalize);
}
/**
* Return a list of Primary Keys for a specified table.
*
* @param string $table
* @param bool $owner (optional) not used in this driver
*
* @return string[] Array of indexes
*/
public function metaPrimaryKeys($table,$owner=false)
{
if (method_exists($this->_driver,'metaPrimaryKeys'))
return $this->_driver->metaPrimaryKeys($table,$owner);
}
/**
* Returns a list of Foreign Keys for a specified table.
*
* @param string $table
* @param bool $owner (optional) not used in this driver
* @param bool $upper
* @param bool $associative
*
* @return string[] where keys are tables, and values are foreign keys
*/
public function metaForeignKeys($table, $owner=false, $upper=false,$associative=false) {
if (method_exists($this->_driver,'metaForeignKeys'))
return $this->_driver->metaForeignKeys($table,$owner,$upper,$associative);
}
/**
* List procedures or functions in an array.
*
* @param $procedureNamePattern A procedure name pattern; must match the procedure name as it is stored in the database.
* @param $catalog A catalog name; must match the catalog name as it is stored in the database.
* @param $schemaPattern A schema name pattern.
*
* @return false|array false if not supported, or array of procedures on current database with structure below
* Array(
* [name_of_procedure] => Array(
* [type] => PROCEDURE or FUNCTION
* [catalog] => Catalog_name
* [schema] => Schema_name
* [remarks] => explanatory comment on the procedure
* )
* )
*/
public function metaProcedures($procedureNamePattern = null, $catalog = null, $schemaPattern = null) {
if (method_exists($this->_driver,'metaProcedures'))
return $this->_driver->metaProcedures($procedureNamePattern,$catalog,$schemaPattern);
return false;
}
function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
{
$obj = $stmt[1];
@ -352,13 +432,13 @@ class ADODB_pdo extends ADOConnection {
return $this->_driver->SetTransactionMode($transaction_mode);
}
return parent::SetTransactionMode($seqname);
return parent::SetTransactionMode($transaction_mode);
}
function BeginTrans()
function beginTrans()
{
if(method_exists($this->_driver, 'BeginTrans')) {
return $this->_driver->BeginTrans();
if(method_exists($this->_driver, 'beginTrans')) {
return $this->_driver->beginTrans();
}
if (!$this->hasTransactions) {
@ -374,10 +454,11 @@ class ADODB_pdo extends ADOConnection {
return $this->_connectionID->beginTransaction();
}
function CommitTrans($ok=true)
function commitTrans($ok=true)
{
if(method_exists($this->_driver, 'CommitTrans')) {
return $this->_driver->CommitTrans($ok);
if(method_exists($this->_driver, 'commitTrans')) {
return $this->_driver->commitTrans($ok);
}
if (!$this->hasTransactions) {
@ -387,7 +468,7 @@ class ADODB_pdo extends ADOConnection {
return true;
}
if (!$ok) {
return $this->RollbackTrans();
return $this->rollbackTrans();
}
if ($this->transCnt) {
$this->transCnt -= 1;
@ -441,10 +522,10 @@ class ADODB_pdo extends ADOConnection {
return $obj;
}
function CreateSequence($seqname='adodbseq',$startID=1)
public function createSequence($seqname='adodbseq',$startID=1)
{
if(method_exists($this->_driver, 'CreateSequence')) {
return $this->_driver->CreateSequence($seqname, $startID);
if(method_exists($this->_driver, 'createSequence')) {
return $this->_driver->createSequence($seqname, $startID);
}
return parent::CreateSequence($seqname, $startID);
@ -478,10 +559,11 @@ class ADODB_pdo extends ADOConnection {
} else {
$stmt = $this->_connectionID->prepare($sql);
}
#adodb_backtrace();
#var_dump($this->_bindInputArray);
if ($stmt) {
if ($this->_driver instanceof ADODB_pdo) {
$this->_driver->debug = $this->debug;
}
if ($inputarr) {
$ok = $stmt->execute($inputarr);
}
@ -523,6 +605,9 @@ class ADODB_pdo extends ADOConnection {
function _affectedrows()
{
if(method_exists($this->_driver, '_affectedrows'))
return $this->_driver->_affectedrows();
return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
}
@ -533,27 +618,25 @@ class ADODB_pdo extends ADOConnection {
/**
* Quotes a string to be sent to the database.
*
* If we have an active connection, delegates quoting to the underlying
* PDO object. Otherwise, replace "'" by the value of $replaceQuote (same
* behavior as mysqli driver)
* PDO object PDO::quote(). Otherwise, replace "'" by the value of
* $replaceQuote (same behavior as mysqli driver).
*
* @param string $s The string to quote
* @param boolean $magic_quotes If false, use PDO::quote().
* @param bool $magic_quotes This param is not used since 5.21.0.
* It remains for backwards compatibility.
*
* @return string Quoted string
*/
function qstr($s, $magic_quotes = false)
function qStr($s, $magic_quotes = false)
{
if (!$magic_quotes) {
if ($this->_connectionID) {
return $this->_connectionID->quote($s);
}
return "'" . str_replace("'", $this->replaceQuote, $s) . "'";
}
// undo magic quotes for "
$s = str_replace('\\"', '"', $s);
return "'$s'";
}
}
class ADODB_pdo_base extends ADODB_pdo {
@ -813,3 +896,5 @@ class ADORecordSet_pdo extends ADORecordSet {
}
}
class ADORecordSet_array_pdo extends ADORecordSet_array {}

View file

@ -0,0 +1,182 @@
<?php
/**
* ADOdb PDO dblib driver.
*
* 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.
*
* @version v5.21.0 2021-02-27
* @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
* @copyright (c) 2019 Damien Regad, Mark Newnham and the ADOdb community
*/
class ADODB_pdo_dblib extends ADODB_pdo
{
var $hasTop = 'top';
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
var $sysTimeStamp = 'GetDate()';
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 = "SELECT c.NAME, OBJECT_NAME(c.id) as tbl_name, c.length, c.isnullable, c.status, ( CASE WHEN c.xusertype=61 THEN 0 ELSE c.xprec END), ( CASE WHEN c.xusertype=61 THEN 0 ELSE c.xscale END), ISNULL(i.is_primary_key, 0) as primary_key FROM syscolumns c INNER JOIN systypes t ON t.xusertype=c.xusertype INNER JOIN sysobjects o ON o.id=c.id LEFT JOIN sys.index_columns ic ON ic.object_id = c.id AND c.colid = ic.column_id LEFT JOIN sys.indexes i ON i.object_id = ic.object_id AND i.index_id = ic.index_id WHERE c.id = OBJECT_ID('%s') ORDER by c.colid";
function _init(ADODB_pdo $parentDriver)
{
$parentDriver->hasTransactions = true;
$parentDriver->_bindInputArray = true;
$parentDriver->hasInsertID = true;
$parentDriver->fmtTimeStamp = "'Y-m-d H:i:s'";
$parentDriver->fmtDate = "'Y-m-d'";
}
function BeginTrans()
{
$returnval = parent::BeginTrans();
return $returnval;
}
function MetaColumns($table, $normalize=true)
{
$this->_findschema($table,$schema);
if ($schema) {
$dbName = $this->database;
$this->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];
$fld->type = $rs->fields[1];
$fld->primary_key = $rs->fields[7];
$fld->not_null = (!$rs->fields[3]);
$fld->auto_increment = ($rs->fields[4] == 128); // sys.syscolumns status field. 0x80 = 128 ref: http://msdn.microsoft.com/en-us/library/ms186816.aspx
if (isset($rs->fields[5]) && $rs->fields[5]) {
if ($rs->fields[5]>0) $fld->max_length = $rs->fields[5];
$fld->scale = $rs->fields[6];
if ($fld->scale>0) $fld->max_length += 1;
} else
$fld->max_length = $rs->fields[2];
if ($save == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
$retarr[strtoupper($fld->name)] = $fld;
}
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(($mask));
$this->metaTablesSQL .= " AND name like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
return $ret;
}
function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
if ($nrows > 0 && $offset <= 0) {
$sql = preg_replace(
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
if ($secs2cache)
$rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
else
$rs = $this->Execute($sql,$inputarr);
} else
$rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
}
function _query($sql,$inputarr=false)
{
$this->_connectionID->setAttribute(\PDO::ATTR_EMULATE_PREPARES , true);
if (is_array($sql)) {
$stmt = $sql[1];
} else {
$stmt = $this->_connectionID->prepare($sql);
}
if ($stmt) {
$this->_driver->debug = $this->debug;
if ($inputarr) {
foreach ($inputarr as $key => $value) {
if(gettype($key) == 'integer') {
$key += 1;
}
$stmt->bindValue($key, $value, $this->GetPDODataType($value));
}
}
}
$ok = $stmt->execute();
$this->_errormsg = false;
$this->_errorno = false;
if ($ok) {
$this->_stmt = $stmt;
return $stmt;
}
if ($stmt) {
$arr = $stmt->errorinfo();
if ((integer)$arr[1]) {
$this->_errormsg = $arr[2];
$this->_errorno = $arr[1];
}
} else {
$this->_errormsg = false;
$this->_errorno = false;
}
return false;
}
private function GetPDODataType($var)
{
if(gettype($var) == 'integer') {
return PDO::PARAM_INT ;
}
return PDO::PARAM_STR;
}
function ServerInfo()
{
return ADOConnection::ServerInfo();
}
}

View file

@ -0,0 +1,447 @@
<?php
/**
* ADOdb PDO Firebird driver
*
* @version v5.21.0 2021-02-27
* @copyright (c) 2019 Damien Regad, Mark Newnham and the ADOdb community
*
* 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 https://adodb.org/
*
* This version has only been tested on Firebird 3.0 and PHP 7
*/
/**
* Class ADODB_pdo_firebird
*/
class ADODB_pdo_firebird extends ADODB_pdo
{
public $dialect = 3;
public $metaTablesSQL = "select lower(rdb\$relation_name) from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
public $metaColumnsSQL = "select lower(a.rdb\$field_name), a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc";
var $arrayClass = 'ADORecordSet_array_pdo_firebird';
function _init($parentDriver)
{
$this->pdoDriver = $parentDriver;
//$parentDriver->_bindInputArray = true;
//$parentDriver->hasTransactions = false; // // should be set to false because of PDO SQLite driver not supporting changing autocommit mode
//$parentDriver->hasInsertID = true;
}
/**
* Gets the version iformation from the server
*
* @return string[]
*/
public function serverInfo()
{
$arr['dialect'] = $this->dialect;
switch ($arr['dialect']) {
case '':
case '1':
$s = 'Firebird Dialect 1';
break;
case '2':
$s = 'Firebird Dialect 2';
break;
default:
case '3':
$s = 'Firebird Dialect 3';
break;
}
$arr['version'] = ADOConnection::_findvers($s);
$arr['description'] = $s;
return $arr;
}
/**
* Returns the tables in the database.
*
* @param mixed $ttype
* @param bool $showSchema
* @param mixed $mask
*
* @return string[]
*/
public function metaTables($ttype = false, $showSchema = false, $mask = false)
{
$ret = ADOConnection::MetaTables($ttype, $showSchema);
return $ret;
}
public function metaColumns($table, $normalize = true)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs = $this->Execute(sprintf($this->metaColumnsSQL, strtoupper($table)));
$ADODB_FETCH_MODE = $save;
if ($rs === false) {
return false;
}
$retarr = array();
$dialect3 = $this->dialect == 3;
while (!$rs->EOF) { //print_r($rs->fields);
$fld = new ADOFieldObject();
$fld->name = trim($rs->fields[0]);
$this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5],
$rs->fields[6], $dialect3);
if (isset($rs->fields[1]) && $rs->fields[1]) {
$fld->not_null = true;
}
if (isset($rs->fields[2])) {
$fld->has_default = true;
$d = substr($rs->fields[2], strlen('default '));
switch ($fld->type) {
case 'smallint':
case 'integer':
$fld->default_value = (int)$d;
break;
case 'char':
case 'blob':
case 'text':
case 'varchar':
$fld->default_value = (string)substr($d, 1, strlen($d) - 2);
break;
case 'double':
case 'float':
$fld->default_value = (float)$d;
break;
default:
$fld->default_value = $d;
break;
}
}
if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {
$fld->sub_type = $rs->fields[5];
} else {
$fld->sub_type = null;
}
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
$retarr[strtoupper($fld->name)] = $fld;
}
$rs->MoveNext();
}
$rs->Close();
if (empty($retarr)) {
return false;
} else {
return $retarr;
}
}
public function metaIndexes($table, $primary = false, $owner = false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) {
$savem = $this->SetFetchMode(false);
}
$table = strtoupper($table);
$sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '" . $table . "'";
if (!$primary) {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
} else {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
}
// get index details
$rs = $this->Execute($sql);
if (!is_object($rs)) {
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return false;
}
$indexes = array();
while ($row = $rs->FetchRow()) {
$index = $row[0];
if (!isset($indexes[$index])) {
if (is_null($row[3])) {
$row[3] = 0;
}
$indexes[$index] = array(
'unique' => ($row[3] == 1),
'columns' => array()
);
}
$sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '" . $index . "' ORDER BY RDB\$FIELD_POSITION ASC";
$rs1 = $this->Execute($sql);
while ($row1 = $rs1->FetchRow()) {
$indexes[$index]['columns'][$row1[2]] = $row1[1];
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $indexes;
}
public function metaPrimaryKeys($table, $owner_notused = false, $internalKey = false)
{
if ($internalKey) {
return array('RDB$DB_KEY');
}
$table = strtoupper($table);
$sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME
FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
WHERE I.RDB$RELATION_NAME=\'' . $table . '\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\'
ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';
$a = $this->GetCol($sql, false, true);
if ($a && sizeof($a) > 0) {
return $a;
}
return false;
}
public function createSequence($seqname = 'adodbseq', $startID = 1)
{
$ok = $this->execute("CREATE SEQUENCE $seqname");
if (!$ok) {
return false;
}
return $this->execute("ALTER SEQUENCE $seqname RESTART WITH " . ($startID - 1));
}
public function dropSequence($seqname = 'adodbseq')
{
$seqname = strtoupper($seqname);
return $this->Execute("DROP SEQUENCE $seqname");
}
public function _affectedrows()
{
return fbird_affected_rows($this->_transactionID ? $this->_transactionID : $this->_connectionID);
}
public function genId($seqname = 'adodbseq', $startID = 1)
{
$getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
$rs = @$this->execute($getnext);
if (!$rs) {
$this->execute(("CREATE SEQUENCE $seqname"));
$this->execute("ALTER SEQUENCE $seqname RESTART WITH " . ($startID - 1) . ';');
$rs = $this->execute($getnext);
}
if ($rs && !$rs->EOF) {
$this->genID = (integer)reset($rs->fields);
} else {
$this->genID = 0; // false
}
if ($rs) {
$rs->Close();
}
return $this->genID;
}
public function selectLimit($sql, $nrows = -1, $offset = -1, $inputarr = false, $secs = 0)
{
$nrows = (integer)$nrows;
$offset = (integer)$offset;
$str = 'SELECT ';
if ($nrows >= 0) {
$str .= "FIRST $nrows ";
}
$str .= ($offset >= 0) ? "SKIP $offset " : '';
$sql = preg_replace('/^[ \t]*select/i', $str, $sql);
if ($secs) {
$rs = $this->cacheExecute($secs, $sql, $inputarr);
} else {
$rs = $this->execute($sql, $inputarr);
}
return $rs;
}
/**
* Sets the appropriate type into the $fld variable
*
* @param ADOFieldObject $fld By reference
* @param int $ftype
* @param int $flen
* @param int $fscale
* @param int $fsubtype
* @param int $fprecision
* @param bool $dialect3
*/
final private function _convertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $dialect3)
{
$fscale = abs($fscale);
$fld->max_length = $flen;
$fld->scale = null;
switch ($ftype) {
case 7:
case 8:
if ($dialect3) {
switch ($fsubtype) {
case 0:
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
break;
case 1:
$fld->type = 'numeric';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
case 2:
$fld->type = 'decimal';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
} // switch
} else {
if ($fscale != 0) {
$fld->type = 'decimal';
$fld->scale = $fscale;
$fld->max_length = ($ftype == 7 ? 4 : 9);
} else {
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
}
}
break;
case 16:
if ($dialect3) {
switch ($fsubtype) {
case 0:
$fld->type = 'decimal';
$fld->max_length = 18;
$fld->scale = 0;
break;
case 1:
$fld->type = 'numeric';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
case 2:
$fld->type = 'decimal';
$fld->max_length = $fprecision;
$fld->scale = $fscale;
break;
} // switch
}
break;
case 10:
$fld->type = 'float';
break;
case 14:
$fld->type = 'char';
break;
case 27:
if ($fscale != 0) {
$fld->type = 'decimal';
$fld->max_length = 15;
$fld->scale = 5;
} else {
$fld->type = 'double';
}
break;
case 35:
if ($dialect3) {
$fld->type = 'timestamp';
} else {
$fld->type = 'date';
}
break;
case 12:
$fld->type = 'date';
break;
case 13:
$fld->type = 'time';
break;
case 37:
$fld->type = 'varchar';
break;
case 40:
$fld->type = 'cstring';
break;
case 261:
$fld->type = 'blob';
$fld->max_length = -1;
break;
} // switch
}
}
/**
* Class ADORecordSet_pdo_firebird
*/
class ADORecordSet_pdo_firebird extends ADORecordSet_pdo
{
public $databaseType = "pdo_firebird";
/**
* returns the field object
*
* @param int $fieldOffset Optional field offset
*
* @return object The ADOFieldObject describing the field
*/
public function fetchField($fieldOffset = 0)
{
}
}
/**
* Class ADORecordSet_array_pdo_firebird
*/
class ADORecordSet_array_pdo_firebird extends ADORecordSet_array_pdo
{
public $databaseType = "pdo_firebird";
public $canSeek = true;
/**
* returns the field object
*
* @param int $fieldOffset Optional field offset
*
* @return object The ADOFieldObject describing the field
*/
public function fetchField($fieldOffset = 0)
{
$fld = new ADOFieldObject;
$fld->name = $fieldOffset;
$fld->type = 'C';
$fld->max_length = 0;
// This needs to be populated from the metadata
$fld->not_null = false;
$fld->has_default = false;
$fld->default_value = 'null';
return $fld;
}
}

View file

@ -2,7 +2,7 @@
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -21,7 +21,10 @@ class ADODB_pdo_mysql extends ADODB_pdo {
var $sysDate = 'CURDATE()';
var $sysTimeStamp = 'NOW()';
var $hasGenID = true;
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
var $_genIDSQL = "UPDATE %s SET id=LAST_INSERT_ID(id+1);";
var $_genSeqSQL = "CREATE TABLE if NOT EXISTS %s (id int not null)";
var $_genSeqCountSQL = "SELECT count(*) FROM %s";
var $_genSeq2SQL = "INSERT INTO %s VALUES (%s)";
var $_dropSeqSQL = "drop table %s";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $nameQuote = '`';
@ -204,7 +207,7 @@ class ADODB_pdo_mysql extends ADODB_pdo {
$nrows = (int) $nrows;
$offset = (int) $offset;
$offsetStr =($offset>=0) ? "$offset," : '';
// jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
// jason judge, see PHPLens Issue No: 9220
if ($nrows < 0) {
$nrows = '18446744073709551615';
}
@ -310,4 +313,41 @@ class ADODB_pdo_mysql extends ADODB_pdo {
}
return $s;
}
function GenID($seqname='adodbseq',$startID=1)
{
$getnext = sprintf($this->_genIDSQL,$seqname);
$holdtransOK = $this->_transOK; // save the current status
$rs = @$this->Execute($getnext);
if (!$rs) {
if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
$this->Execute(sprintf($this->_genSeqSQL,$seqname));
$cnt = $this->GetOne(sprintf($this->_genSeqCountSQL,$seqname));
if (!$cnt) $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
$rs = $this->Execute($getnext);
}
if ($rs) {
$this->genID = $this->_connectionID->lastInsertId($seqname);
$rs->Close();
} else {
$this->genID = 0;
}
return $this->genID;
}
function createSequence($seqname='adodbseq',$startID=1)
{
if (empty($this->_genSeqSQL)) {
return false;
}
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
if (!$ok) {
return false;
}
return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
}
}

View file

@ -2,7 +2,7 @@
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,7 +1,7 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -229,4 +229,64 @@ select viewname,'V' from pg_views where viewname like $mask";
}
function BeginTrans()
{
if (!$this->hasTransactions) {
return false;
}
if ($this->transOff) {
return true;
}
$this->transCnt += 1;
return $this->_connectionID->beginTransaction();
}
function CommitTrans($ok = true)
{
if (!$this->hasTransactions) {
return false;
}
if ($this->transOff) {
return true;
}
if (!$ok) {
return $this->RollbackTrans();
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$this->_autocommit = true;
$ret = $this->_connectionID->commit();
return $ret;
}
function RollbackTrans()
{
if (!$this->hasTransactions) {
return false;
}
if ($this->transOff) {
return true;
}
if ($this->transCnt) {
$this->transCnt -= 1;
}
$this->_autocommit = true;
$ret = $this->_connectionID->rollback();
return $ret;
}
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
$this->_connectionID->query('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
return;
}
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->_connectionID->query("SET TRANSACTION ".$transaction_mode);
}
}

View file

@ -1,7 +1,7 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -9,7 +9,7 @@
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Thanks Diogo Toscano (diogo#scriptcase.net) for the code.
And also Sid Dunayer [sdunayer#interserv.com] for extensive fixes.

View file

@ -5,10 +5,10 @@
*/
class ADODB_pdo_sqlsrv extends ADODB_pdo
{
var $hasTop = 'top';
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
var $sysTimeStamp = 'GetDate()';
var $arrayClass = 'ADORecordSet_array_pdo_sqlsrv';
function _init(ADODB_pdo $parentDriver)
{
@ -45,5 +45,120 @@ class ADODB_pdo_sqlsrv extends ADODB_pdo
{
return ADOConnection::ServerInfo();
}
}
class ADORecordSet_pdo_sqlsrv extends ADORecordSet_pdo
{
public $databaseType = "pdo_sqlsrv";
/**
* returns the field object
*
* @param int $fieldOffset Optional field offset
*
* @return object The ADOFieldObject describing the field
*/
public function fetchField($fieldOffset = 0)
{
// Default behavior allows passing in of -1 offset, which crashes the method
if ($fieldOffset == -1) {
$fieldOffset++;
}
$o = new ADOFieldObject();
$arr = @$this->_queryID->getColumnMeta($fieldOffset);
if (!$arr) {
$o->name = 'bad getColumnMeta()';
$o->max_length = -1;
$o->type = 'VARCHAR';
$o->precision = 0;
return $o;
}
$o->name = $arr['name'];
if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null") {
// Use the SQL Server driver specific value
$o->type = $arr['sqlsrv:decl_type'];
} else {
$o->type = adodb_pdo_type($arr['pdo_type']);
}
$o->max_length = $arr['len'];
$o->precision = $arr['precision'];
switch (ADODB_ASSOC_CASE) {
case ADODB_ASSOC_CASE_LOWER:
$o->name = strtolower($o->name);
break;
case ADODB_ASSOC_CASE_UPPER:
$o->name = strtoupper($o->name);
break;
}
return $o;
}
}
class ADORecordSet_array_pdo_sqlsrv extends ADORecordSet_array_pdo
{
/**
* returns the field object
*
* Note that this is a direct copy of the ADORecordSet_pdo_sqlsrv method
*
* @param int $fieldOffset Optional field offset
*
* @return object The ADOfieldobject describing the field
*/
public function fetchField($fieldOffset = 0)
{
// Default behavior allows passing in of -1 offset, which crashes the method
if ($fieldOffset == -1) {
$fieldOffset++;
}
$o = new ADOFieldObject();
$arr = @$this->_queryID->getColumnMeta($fieldOffset);
if (!$arr) {
$o->name = 'bad getColumnMeta()';
$o->max_length = -1;
$o->type = 'VARCHAR';
$o->precision = 0;
return $o;
}
$o->name = $arr['name'];
if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null") {
// Use the SQL Server driver specific value
$o->type = $arr['sqlsrv:decl_type'];
} else {
$o->type = adodb_pdo_type($arr['pdo_type']);
}
$o->max_length = $arr['len'];
$o->precision = $arr['precision'];
switch (ADODB_ASSOC_CASE) {
case ADODB_ASSOC_CASE_LOWER:
$o->name = strtolower($o->name);
break;
case ADODB_ASSOC_CASE_UPPER:
$o->name = strtoupper($o->name);
break;
}
return $o;
}
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
$this->_connectionID->query('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
return;
}
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->_connectionID->query("SET TRANSACTION ".$transaction_mode);
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -9,6 +9,7 @@
Set tabs to 4.
NOTE: Since 3.31, this file is no longer used, and the "postgres" driver is
remapped to "postgres7". Maintaining multiple postgres drivers is no easy
job, so hopefully this will ensure greater consistency and fewer bugs.
remapped to lastest available postgres version. Maintaining multiple
postgres drivers is no easy job, so hopefully this will ensure greater
consistency and fewer bugs.
*/

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -114,6 +114,7 @@ class ADODB_postgres64 extends ADOConnection{
var $_bindInputArray = false; // requires postgresql 7.3+ and ability to modify database
var $disableBlobs = false; // set to true to disable blob checking, resulting in 2-5% improvement in performance.
/** @var int $_pnum Number of the last assigned query parameter {@see param()} */
var $_pnum = 0;
// The last (fmtTimeStamp is not entirely correct:
@ -124,19 +125,40 @@ class ADODB_postgres64 extends ADOConnection{
// to know what the concequences are. The other values are correct (wheren't in 0.94)
// -- Freek Dijkstra
function __construct()
/**
* Retrieve Server information.
* In addition to server version and description, the function also returns
* the client version.
* @param bool $detailed If true, retrieve detailed version string (executes
* a SQL query) in addition to the version number
* @return array|bool Server info or false if version could not be retrieved
* e.g. if there is no active connection
*/
function ServerInfo($detailed = true)
{
// changes the metaColumnsSQL, adds columns: attnum[6]
if (empty($this->version['version'])) {
// We don't have a connection, so we can't retrieve server info
if (!$this->_connectionID) {
return false;
}
function ServerInfo()
{
if (isset($this->version)) return $this->version;
$version = pg_version($this->_connectionID);
$this->version = array(
// If PHP has been compiled with PostgreSQL 7.3 or lower, then
// server version is not set so we use pg_parameter_status()
// which includes logic to obtain values server_version
'version' => isset($version['server'])
? $version['server']
: pg_parameter_status($this->_connectionID, 'server_version'),
'client' => $version['client'],
'description' => null,
);
}
if ($detailed && $this->version['description'] === null) {
$this->version['description'] = $this->GetOne('select version()');
}
$arr['description'] = $this->GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
$this->version = $arr;
return $arr;
return $this->version;
}
function IfNull( $field, $ifNull )
@ -165,7 +187,7 @@ class ADODB_postgres64 extends ADOConnection{
function _insertid($table,$column)
{
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
$oid = pg_getlastoid($this->_resultid);
$oid = pg_last_oid($this->_resultid);
// to really return the id, we need the table and column-name, else we can only return the oid != id
return empty($table) || empty($column) ? $oid : $this->GetOne("SELECT $column FROM $table WHERE oid=".(int)$oid);
}
@ -243,29 +265,30 @@ class ADODB_postgres64 extends ADOConnection{
}
// if magic quotes disabled, use pg_escape_string()
function qstr($s,$magic_quotes=false)
/**
* Quotes a string to be sent to the database.
*
* Relies on pg_escape_string()
* @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:qstr
*
* @param string $s The string to quote
* @param bool $magic_quotes This param is not used since 5.21.0.
* It remains for backwards compatibility.
*
* @return string Quoted string
*/
function qStr($s, $magic_quotes=false)
{
if (is_bool($s)) return $s ? 'true' : 'false';
if (!$magic_quotes) {
if (ADODB_PHPVER >= 0x5200 && $this->_connectionID) {
return "'".pg_escape_string($this->_connectionID,$s)."'";
if (is_bool($s)) {
return $s ? 'true' : 'false';
}
if (ADODB_PHPVER >= 0x4200) {
if ($this->_connectionID) {
return "'" . pg_escape_string($this->_connectionID, $s) . "'";
} else {
return "'" . pg_escape_string($s) . "'";
}
if ($this->replaceQuote[0] == '\\'){
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\\000"),$s);
}
return "'".str_replace("'",$this->replaceQuote,$s)."'";
}
// undo magic quotes for "
$s = str_replace('\\"','"',$s);
return "'$s'";
}
// Format date column in sql string given an input format that understands Y M D
@ -393,7 +416,7 @@ class ADODB_postgres64 extends ADOConnection{
}
/*
Hueristic - not guaranteed to work.
Heuristic - not guaranteed to work.
*/
function GuessOID($oid)
{
@ -425,29 +448,25 @@ class ADODB_postgres64 extends ADOConnection{
}
if (!$maxsize) $maxsize = $this->maxblobsize;
$realblob = @pg_lo_read($fd,$maxsize);
@pg_loclose($fd);
@pg_lo_close($fd);
if ($hastrans) pg_query($this->_connectionID,'commit');
return $realblob;
}
/*
See http://www.postgresql.org/idocs/index.php?datatype-binary.html
NOTE: SQL string literals (input strings) must be preceded with two backslashes
due to the fact that they must pass through two parsers in the PostgreSQL
backend.
/**
* Encode binary value prior to DB storage.
*
* See https://www.postgresql.org/docs/current/static/datatype-binary.html
*
* NOTE: SQL string literals (input strings) must be preceded with two
* backslashes due to the fact that they must pass through two parsers in
* the PostgreSQL backend.
*
* @param string $blob
*/
function BlobEncode($blob)
{
if (ADODB_PHPVER >= 0x5200) return pg_escape_bytea($this->_connectionID, $blob);
if (ADODB_PHPVER >= 0x4200) return pg_escape_bytea($blob);
/*92=backslash, 0=null, 39=single-quote*/
$badch = array(chr(92),chr(0),chr(39)); # \ null '
$fixch = array('\\\\134','\\\\000','\\\\047');
return adodb_str_replace($badch,$fixch,$blob);
// note that there is a pg_escape_bytea function only for php 4.2.0 or later
return pg_escape_bytea($this->_connectionID, $blob);
}
// assumes bytea for blob, and varchar for clob
@ -492,7 +511,7 @@ class ADODB_postgres64 extends ADOConnection{
// for schema support, pass in the $table param "$schema.$tabname".
// converts field names to lowercase, $upper is ignored
// see http://phplens.com/lens/lensforum/msgs.php?id=14018 for more info
// see PHPLens Issue No: 14018 for more info
function MetaColumns($table,$normalize=true)
{
global $ADODB_FETCH_MODE;
@ -606,15 +625,18 @@ class ADODB_postgres64 extends ADOConnection{
}
function Param($name,$type='C')
function param($name, $type='C')
{
if ($name) {
$this->_pnum += 1;
} else {
// Reset param num if $name is false
$this->_pnum = 1;
if (!$name) {
// Reset parameter number if $name is falsy
$this->_pnum = 0;
if ($name === false) {
// and don't return placeholder if false (see #380)
return '';
}
return '$'.$this->_pnum;
}
return '$' . ++$this->_pnum;
}
function MetaIndexes ($table, $primary = FALSE, $owner = false)
@ -729,9 +751,9 @@ class ADODB_postgres64 extends ADOConnection{
if ($this->_connectionID === false) return false;
$this->Execute("set datestyle='ISO'");
$info = $this->ServerInfo();
$this->pgVersion = (float) substr($info['version'],0,3);
if ($this->pgVersion >= 7.1) { // good till version 999
$info = $this->ServerInfo(false);
if (version_compare($info['version'], '7.1', '>=')) {
$this->_nestedSQL = true;
}
@ -740,8 +762,11 @@ class ADODB_postgres64 extends ADOConnection{
# https://bugs.php.net/bug.php?id=59831 states this is in fact not a bug,
# so we manually set bytea_output
if (!empty($this->connection->noBlobs) && version_compare($info['version'], '9.0', '>=')) {
$version = pg_version($this->connectionID);
if (version_compare($info['client'], '9.2', '<')) {
$this->Execute('set bytea_output=escape');
}
}
return true;
}
@ -848,20 +873,23 @@ class ADODB_postgres64 extends ADOConnection{
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
if ($this->_errorMsg !== false) return $this->_errorMsg;
if (ADODB_PHPVER >= 0x4300) {
if ($this->_errorMsg !== false) {
return $this->_errorMsg;
}
if (!empty($this->_resultid)) {
$this->_errorMsg = @pg_result_error($this->_resultid);
if ($this->_errorMsg) return $this->_errorMsg;
if ($this->_errorMsg) {
return $this->_errorMsg;
}
}
if (!empty($this->_connectionID)) {
$this->_errorMsg = @pg_last_error($this->_connectionID);
} else $this->_errorMsg = $this->_errconnect();
} else {
if (empty($this->_connectionID)) $this->_errconnect();
else $this->_errorMsg = @pg_errormessage($this->_connectionID);
$this->_errorMsg = $this->_errconnect();
}
return $this->_errorMsg;
}
@ -986,7 +1014,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
$o= new ADOFieldObject();
$o->name = @pg_field_name($this->_queryID,$off);
$o->type = @pg_field_type($this->_queryID,$off);
$o->max_length = @pg_fieldsize($this->_queryID,$off);
$o->max_length = @pg_field_size($this->_queryID,$off);
return $o;
}
@ -998,7 +1026,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
function _decode($blob)
{
if ($blob === NULL) return NULL;
// eval('$realblob="'.adodb_str_replace(array('"','$'),array('\"','\$'),$blob).'";');
// eval('$realblob="'.str_replace(array('"','$'),array('\"','\$'),$blob).'";');
return pg_unescape_bytea($blob);
}
@ -1049,7 +1077,12 @@ class ADORecordSet_postgres64 extends ADORecordSet{
function _close()
{
return @pg_free_result($this->_queryID);
if (!is_resource($this->_queryID)
|| get_resource_type($this->_queryID) != 'pgsql result'
) {
return true;
}
return pg_free_result($this->_queryID);
}
function MetaType($t,$len=-1,$fieldobj=false)
@ -1068,6 +1101,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
case 'NAME':
case 'BPCHAR':
case '_VARCHAR':
case 'CIDR':
case 'INET':
case 'MACADDR':
if ($len <= $this->blobSize) return 'C';
@ -1111,7 +1145,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
return 'R';
default:
return 'N';
return ADODB_DEFAULT_METATYPE;
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -101,7 +101,7 @@ class ADODB_postgres7 extends ADODB_postgres64 {
if (ADODB_ASSOC_CASE !== ADODB_ASSOC_CASE_NATIVE) {
$this->rsPrefix .= 'assoc_';
}
$this->_bindInputArray = PHP_VERSION >= 5.1;
$this->_bindInputArray = true;
}
@ -309,12 +309,6 @@ class ADORecordSet_postgres7 extends ADORecordSet_postgres64{
var $databaseType = "postgres7";
function __construct($queryID, $mode=false)
{
parent::__construct($queryID, $mode);
}
// 10% speedup to move MoveNext to child class
function MoveNext()
{
@ -341,11 +335,6 @@ class ADORecordSet_assoc_postgres7 extends ADORecordSet_postgres64{
var $databaseType = "postgres7";
function __construct($queryID, $mode=false)
{
parent::__construct($queryID, $mode);
}
function _fetch()
{
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0) {

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -16,18 +16,15 @@ if (!defined('ADODB_DIR')) die();
if (! defined("_ADODB_PROXY_LAYER")) {
define("_ADODB_PROXY_LAYER", 1 );
include(ADODB_DIR."/drivers/adodb-csv.inc.php");
include_once(ADODB_DIR."/drivers/adodb-csv.inc.php");
class ADODB_proxy extends ADODB_csv {
var $databaseType = 'proxy';
var $databaseProvider = 'csv';
}
class ADORecordset_proxy extends ADORecordset_csv {
var $databaseType = "proxy";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
};
} // define

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
SAPDB data driver. Requires ODBC.
@ -18,7 +18,7 @@ Set tabs to 4 for best viewing.
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ODBC_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
if (!defined('ADODB_SAPDB')){
define('ADODB_SAPDB',1);
@ -33,12 +33,6 @@ class ADODB_SAPDB extends ADODB_odbc {
var $hasInsertId = true;
var $_bindInputArray = true;
function __construct()
{
//if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC;
parent::__construct();
}
function ServerInfo()
{
$info = ADODB_odbc::ServerInfo();
@ -176,10 +170,6 @@ class ADORecordSet_sapdb extends ADORecordSet_odbc {
var $databaseType = "sapdb";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}
} //define

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
reserved.
@ -9,7 +9,7 @@ reserved.
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
21.02.2002 - Wade Johnson wade@wadejohnson.de
Extended ODBC class for Sybase SQLAnywhere.
@ -47,7 +47,7 @@ Set tabs to 4 for best viewing.
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ODBC_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
if (!defined('ADODB_SYBASE_SQLANYWHERE')){
@ -153,11 +153,6 @@ if (!defined('ADODB_SYBASE_SQLANYWHERE')){
var $databaseType = "sqlanywhere";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}; //class

View file

@ -1,13 +1,13 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
SQLite info: http://www.hwaci.com/sw/sqlite/
@ -22,6 +22,7 @@ if (!defined('ADODB_DIR')) die();
class ADODB_sqlite extends ADOConnection {
var $databaseType = "sqlite";
var $dataProvider = "sqlite";
var $replaceQuote = "''"; // string to use to replace quotes
var $concat_operator='||';
var $_errorNo = 0;
@ -33,10 +34,6 @@ class ADODB_sqlite extends ADOConnection {
var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
function __construct()
{
}
function ServerInfo()
{
$arr['version'] = sqlite_libversion();
@ -355,6 +352,63 @@ class ADODB_sqlite extends ADOConnection {
return $indexes;
}
/**
* Returns the maximum size of a MetaType C field. Because of the
* database design, sqlite places no limits on the size of data inserted
*
* @return int
*/
function charMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/**
* Returns the maximum size of a MetaType X field. Because of the
* database design, sqlite places no limits on the size of data inserted
*
* @return int
*/
function textMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/*
* Converts a date to a month only field and pads it to 2 characters
*
* @param str $fld The name of the field to process
* @return str The SQL Statement
*/
function month($fld)
{
$x = "strftime('%m',$fld)";
return $x;
}
/*
* Converts a date to a day only field and pads it to 2 characters
*
* @param str $fld The name of the field to process
* @return str The SQL Statement
*/
function day($fld) {
$x = "strftime('%d',$fld)";
return $x;
}
/*
* Converts a date to a year only field
*
* @param str $fld The name of the field to process
* @return str The SQL Statement
*/
function year($fld) {
$x = "strftime('%Y',$fld)";
return $x;
}
}
/*--------------------------------------------------------------------------------------

View file

@ -1,13 +1,13 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
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.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
SQLite info: http://www.hwaci.com/sw/sqlite/
@ -22,6 +22,7 @@ if (!defined('ADODB_DIR')) die();
class ADODB_sqlite3 extends ADOConnection {
var $databaseType = "sqlite3";
var $dataProvider = "sqlite";
var $replaceQuote = "''"; // string to use to replace quotes
var $concat_operator='||';
var $_errorNo = 0;
@ -33,10 +34,6 @@ class ADODB_sqlite3 extends ADOConnection {
var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
function __construct()
{
}
function ServerInfo()
{
$version = SQLite3::version();
@ -82,6 +79,73 @@ class ADODB_sqlite3 extends ADOConnection {
return !empty($ret);
}
function metaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t))
{
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
/*
* We are using the Sqlite affinity method here
* @link https://www.sqlite.org/datatype3.html
*/
$affinity = array(
'INT'=>'INTEGER',
'INTEGER'=>'INTEGER',
'TINYINT'=>'INTEGER',
'SMALLINT'=>'INTEGER',
'MEDIUMINT'=>'INTEGER',
'BIGINT'=>'INTEGER',
'UNSIGNED BIG INT'=>'INTEGER',
'INT2'=>'INTEGER',
'INT8'=>'INTEGER',
'CHARACTER'=>'TEXT',
'VARCHAR'=>'TEXT',
'VARYING CHARACTER'=>'TEXT',
'NCHAR'=>'TEXT',
'NATIVE CHARACTER'=>'TEXT',
'NVARCHAR'=>'TEXT',
'TEXT'=>'TEXT',
'CLOB'=>'TEXT',
'BLOB'=>'BLOB',
'REAL'=>'REAL',
'DOUBLE'=>'REAL',
'DOUBLE PRECISION'=>'REAL',
'FLOAT'=>'REAL',
'NUMERIC'=>'NUMERIC',
'DECIMAL'=>'NUMERIC',
'BOOLEAN'=>'NUMERIC',
'DATE'=>'NUMERIC',
'DATETIME'=>'NUMERIC'
);
if (!isset($affinity[$t]))
return ADODB_DEFAULT_METATYPE;
$subt = $affinity[$t];
/*
* Now that we have subclassed the provided data down
* the sqlite 'affinity', we convert to ADOdb metatype
*/
$subclass = array('INTEGER'=>'I',
'TEXT'=>'X',
'BLOB'=>'B',
'REAL'=>'N',
'NUMERIC'=>'N');
return $subclass[$subt];
}
// mark newnham
function MetaColumns($table, $normalize=true)
{
@ -129,6 +193,60 @@ class ADODB_sqlite3 extends ADOConnection {
return $arr;
}
function metaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
{
global $ADODB_FETCH_MODE;
if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC
|| $this->fetchMode == ADODB_FETCH_ASSOC)
$associative = true;
/*
* Read sqlite master to find foreign keys
*/
$sql = "SELECT sql
FROM (
SELECT sql sql, type type, tbl_name tbl_name, name name
FROM sqlite_master
)
WHERE type != 'meta'
AND sql NOTNULL
AND LOWER(name) ='" . strtolower($table) . "'";
$tableSql = $this->getOne($sql);
$fkeyList = array();
$ylist = preg_split("/,+/",$tableSql);
foreach ($ylist as $y)
{
if (!preg_match('/FOREIGN/',$y))
continue;
$matches = false;
preg_match_all('/\((.+?)\)/i',$y,$matches);
$tmatches = false;
preg_match_all('/REFERENCES (.+?)\(/i',$y,$tmatches);
if ($associative)
{
if (!isset($fkeyList[$tmatches[1][0]]))
$fkeyList[$tmatches[1][0]] = array();
$fkeyList[$tmatches[1][0]][$matches[1][0]] = $matches[1][1];
}
else
$fkeyList[$tmatches[1][0]][] = $matches[1][0] . '=' . $matches[1][1];
}
if ($associative)
{
if ($upper)
$fkeyList = array_change_key_case($fkeyList,CASE_UPPER);
else
$fkeyList = array_change_key_case($fkeyList,CASE_LOWER);
}
return $fkeyList;
}
function _init($parentDriver)
{
$parentDriver->hasTransactions = false;
@ -160,11 +278,22 @@ class ADODB_sqlite3 extends ADOConnection {
function SQLDate($fmt, $col=false)
{
/*
* In order to map the values correctly, we must ensure the proper
* casing for certain fields
* Y must be UC, because y is a 2 digit year
* d must be LC, because D is 3 char day
* A must be UC because a is non-portable am
* Q must be UC because q means nothing
*/
$fromChars = array('y','D','a','q');
$toChars = array('Y','d','A','Q');
$fmt = str_replace($fromChars,$toChars,$fmt);
$fmt = $this->qstr($fmt);
return ($col) ? "adodb_date2($fmt,$col)" : "adodb_date($fmt)";
}
function _createFunctions()
{
$this->_connectionID->createFunction('adodb_date', 'adodb_date', 1);
@ -289,7 +418,7 @@ class ADODB_sqlite3 extends ADOConnection {
return $this->_connectionID->close();
}
function MetaIndexes($table, $primary = FALSE, $owner = false)
function metaIndexes($table, $primary = FALSE, $owner = false)
{
$false = false;
// save old fetch mode
@ -299,8 +428,36 @@ class ADODB_sqlite3 extends ADOConnection {
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
$SQL=sprintf("SELECT name,sql FROM sqlite_master WHERE type='index' AND tbl_name='%s'", strtolower($table));
$rs = $this->Execute($SQL);
$pragmaData = array();
/*
* If we want the primary key, we must extract
* it from the table statement, and the pragma
*/
if ($primary)
{
$sql = sprintf('PRAGMA table_info([%s]);',
strtolower($table)
);
$pragmaData = $this->getAll($sql);
}
/*
* Exclude the empty entry for the primary index
*/
$sqlite = "SELECT name,sql
FROM sqlite_master
WHERE type='index'
AND sql IS NOT NULL
AND LOWER(tbl_name)='%s'";
$SQL = sprintf($sqlite,
strtolower($table)
);
$rs = $this->execute($SQL);
if (!is_object($rs)) {
if (isset($savem)) {
$this->SetFetchMode($savem);
@ -310,10 +467,10 @@ class ADODB_sqlite3 extends ADOConnection {
}
$indexes = array ();
while ($row = $rs->FetchRow()) {
if ($primary && preg_match("/primary/i",$row[1]) == 0) {
continue;
}
while ($row = $rs->FetchRow())
{
if (!isset($indexes[$row[0]])) {
$indexes[$row[0]] = array(
'unique' => preg_match("/unique/i",$row[1]),
@ -321,23 +478,122 @@ class ADODB_sqlite3 extends ADOConnection {
);
}
/**
* There must be a more elegant way of doing this,
* the index elements appear in the SQL statement
* The index elements appear in the SQL statement
* in cols[1] between parentheses
* e.g CREATE UNIQUE INDEX ware_0 ON warehouse (org,warehouse)
*/
$cols = explode("(",$row[1]);
$cols = explode(")",$cols[1]);
array_pop($cols);
$indexes[$row[0]]['columns'] = $cols;
preg_match_all('/\((.*)\)/',$row[1],$indexExpression);
$indexes[$row[0]]['columns'] = array_map('trim',explode(',',$indexExpression[1][0]));
}
if (isset($savem)) {
$this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
}
/*
* If we want primary, add it here
*/
if ($primary){
/*
* Check the previously retrieved pragma to search
* with a closure
*/
$pkIndexData = array('unique'=>1,'columns'=>array());
$pkCallBack = function ($value, $key) use (&$pkIndexData) {
/*
* As we iterate the elements check for pk index and sort
*/
if ($value[5] > 0)
{
$pkIndexData['columns'][$value[5]] = strtolower($value[1]);
ksort($pkIndexData['columns']);
}
};
array_walk($pragmaData,$pkCallBack);
/*
* If we found no columns, there is no
* primary index
*/
if (count($pkIndexData['columns']) > 0)
$indexes['PRIMARY'] = $pkIndexData;
}
return $indexes;
}
/**
* Returns the maximum size of a MetaType C field. Because of the
* database design, sqlite places no limits on the size of data inserted
*
* @return int
*/
function charMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/**
* Returns the maximum size of a MetaType X field. Because of the
* database design, sqlite places no limits on the size of data inserted
*
* @return int
*/
function textMax()
{
return ADODB_STRINGMAX_NOLIMIT;
}
/**
* Converts a date to a month only field and pads it to 2 characters
*
* This uses the more efficient strftime native function to process
*
* @param str $fld The name of the field to process
*
* @return str The SQL Statement
*/
function month($fld)
{
$x = "strftime('%m',$fld)";
return $x;
}
/**
* Converts a date to a day only field and pads it to 2 characters
*
* This uses the more efficient strftime native function to process
*
* @param str $fld The name of the field to process
*
* @return str The SQL Statement
*/
function day($fld) {
$x = "strftime('%d',$fld)";
return $x;
}
/**
* Converts a date to a year only field
*
* This uses the more efficient strftime native function to process
*
* @param str $fld The name of the field to process
*
* @return str The SQL Statement
*/
function year($fld)
{
$x = "strftime('%Y',$fld)";
return $x;
}
}
/*--------------------------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -35,11 +35,6 @@ class ADORecordset_sqlitepo extends ADORecordset_sqlite {
var $databaseType = 'sqlitepo';
function __construct($queryID,$mode=false)
{
parent::__construct($queryID,$mode);
}
// Modified to strip table names from returned fields
function _fetch($ignore_fields=false)
{

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim. All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Sybase driver contributed by Toni (toni.tunkkari@finebyte.com)
@ -44,10 +44,6 @@ class ADODB_sybase extends ADOConnection {
var $port;
function __construct()
{
}
// might require begintrans -- committrans
function _insertid()
{
@ -171,7 +167,7 @@ class ADODB_sybase extends ADOConnection {
{
global $ADODB_COUNTRECS;
if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300)
if ($ADODB_COUNTRECS == false)
return sybase_unbuffered_query($sql,$this->_connectionID);
else
return sybase_query($sql,$this->_connectionID);
@ -320,7 +316,7 @@ class ADORecordset_sybase extends ADORecordSet {
}
if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
else $this->fetchMode = $mode;
parent::__construct($id,$mode);
parent::__construct($id);
}
/* Returns: an object containing field information.
@ -393,10 +389,6 @@ class ADORecordset_sybase extends ADORecordSet {
}
class ADORecordSet_array_sybase extends ADORecordSet_array {
function __construct($id=-1)
{
parent::__construct($id);
}
// sybase/mssql uses a default date like Dec 30 2000 12:00AM
static function UnixDate($v)

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -22,10 +22,6 @@ class ADODB_sybase_ase extends ADODB_sybase {
var $metaColumnsSQL = "SELECT syscolumns.name AS field_name, systypes.name AS type, systypes.length AS width FROM sysobjects, syscolumns, systypes WHERE sysobjects.name='%s' AND syscolumns.id = sysobjects.id AND systypes.type=syscolumns.type";
var $metaDatabasesSQL ="SELECT a.name FROM master.dbo.sysdatabases a, master.dbo.syslogins b WHERE a.suid = b.suid and a.name like '%' and a.name != 'tempdb' and a.status3 != 256 order by 1";
function __construct()
{
}
// split the Views, Tables and procedures.
function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
@ -112,9 +108,4 @@ class ADODB_sybase_ase extends ADODB_sybase {
class adorecordset_sybase_ase extends ADORecordset_sybase {
var $databaseType = "sybase_ase";
function __construct($id,$mode=false)
{
parent::__construct($id,$mode);
}
}

View file

@ -0,0 +1,384 @@
<?php
/*
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Set tabs to 4.
*/
/*
Setup:
$db = NewADOConnection('text');
$db->Connect($array,[$types],[$colnames]);
Parameter $array is the 2 dimensional array of data. The first row can contain the
column names. If column names is not defined in first row, you MUST define $colnames,
the 3rd parameter.
Parameter $types is optional. If defined, it should contain an array matching
the number of columns in $array, with each element matching the correct type defined
by MetaType: (B,C,I,L,N). If undefined, we will probe for $this->_proberows rows
to guess the type. Only C,I and N are recognised.
Parameter $colnames is optional. If defined, it is an array that contains the
column names of $array. If undefined, we assume the first row of $array holds the
column names.
The Execute() function will return a recordset. The recordset works like a normal recordset.
We have partial support for SQL parsing. We process the SQL using the following rules:
1. SQL order by's always work for the first column ordered. Subsequent cols are ignored
2. All operations take place on the same table. No joins possible. In fact the FROM clause
is ignored! You can use any name for the table.
3. To simplify code, all columns are returned, except when selecting 1 column
$rs = $db->Execute('select col1,col2 from table'); // sql ignored, will generate all cols
We special case handling of 1 column because it is used in filter popups
$rs = $db->Execute('select col1 from table');
// sql accepted and processed -- any table name is accepted
$rs = $db->Execute('select distinct col1 from table');
// sql accepted and processed
4. Where clauses are ignored, but searching with the 3rd parameter of Execute is permitted.
This has to use PHP syntax and we will eval() it. You can even use PHP functions.
$rs = $db->Execute('select * from table',false,"\$COL1='abc' and $\COL2=3")
// the 3rd param is searched -- make sure that $COL1 is a legal column name
// and all column names must be in upper case.
4. Group by, having, other clauses are ignored
5. Expression columns, min(), max() are ignored
6. All data is readonly. Only SELECTs permitted.
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (! defined("_ADODB_TEXT_LAYER")) {
define("_ADODB_TEXT_LAYER", 1 );
// for sorting in _query()
function adodb_cmp($a, $b) {
if ($a[0] == $b[0]) return 0;
return ($a[0] < $b[0]) ? -1 : 1;
}
// for sorting in _query()
function adodb_cmpr($a, $b) {
if ($a[0] == $b[0]) return 0;
return ($a[0] > $b[0]) ? -1 : 1;
}
class ADODB_text extends ADOConnection {
var $databaseType = 'text';
var $_origarray; // original data
var $_types;
var $_proberows = 8;
var $_colnames;
var $_skiprow1=false;
var $readOnly = true;
var $hasTransactions = false;
var $_rezarray;
var $_reznames;
var $_reztypes;
function RSRecordCount()
{
if (!empty($this->_rezarray)) return sizeof($this->_rezarray);
return sizeof($this->_origarray);
}
function _insertid()
{
return false;
}
function _affectedrows()
{
return false;
}
// returns true or false
function PConnect(&$array, $types = false, $colnames = false)
{
return $this->Connect($array, $types, $colnames);
}
// returns true or false
function Connect(&$array, $types = false, $colnames = false)
{
if (is_string($array) and $array === 'iluvphplens') return 'me2';
if (!$array) {
$this->_origarray = false;
return true;
}
$row = $array[0];
$cols = sizeof($row);
if ($colnames) $this->_colnames = $colnames;
else {
$this->_colnames = $array[0];
$this->_skiprow1 = true;
}
if (!$types) {
// probe and guess the type
$types = array();
$firstrow = true;
if ($this->_proberows > sizeof($array)) $max = sizeof($array);
else $max = $this->_proberows;
for ($j=($this->_skiprow1)?1:0;$j < $max; $j++) {
$row = $array[$j];
if (!$row) break;
$i = -1;
foreach($row as $v) {
$i += 1;
//print " ($i ".$types[$i]. "$v) ";
$v = trim($v);
if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
$types[$i] = 'C'; // once C, always C
continue;
}
if (isset($types[$i]) && $types[$i]=='C') continue;
if ($firstrow) {
// If empty string, we presume is character
// test for integer for 1st row only
// after that it is up to testing other rows to prove
// that it is not an integer
if (strlen($v) == 0) $types[0] = 'C';
if (strpos($v,'.') !== false) $types[0] = 'N';
else $types[$i] = 'I';
continue;
}
if (strpos($v,'.') !== false) $types[$i] = 'N';
}
$firstrow = false;
}
}
//print_r($types);
$this->_origarray = $array;
$this->_types = $types;
return true;
}
// returns queryID or false
// We presume that the select statement is on the same table (what else?),
// with the only difference being the order by.
//You can filter by using $eval and each clause is stored in $arr .eg. $arr[1] == 'name'
// also supports SELECT [DISTINCT] COL FROM ... -- only 1 col supported
function _query($sql,$input_arr,$eval=false)
{
if ($this->_origarray === false) return false;
$eval = $this->evalAll;
$usql = strtoupper(trim($sql));
$usql = preg_replace("/[\t\n\r]/",' ',$usql);
$usql = preg_replace('/ *BY/i',' BY',strtoupper($usql));
$eregword ='([A-Z_0-9]*)';
//print "<BR> $sql $eval ";
if ($eval) {
$i = 0;
foreach($this->_colnames as $n) {
$n = strtoupper(trim($n));
$eval = str_replace("\$$n","\$arr[$i]",$eval);
$i += 1;
}
$i = 0;
$eval = "\$rez=($eval);";
//print "<p>Eval string = $eval </p>";
$where_arr = array();
reset($this->_origarray);
foreach ($this->_origarray as $arr) {
if ($i == 0 && $this->_skiprow1)
$where_arr[] = $arr;
else {
eval($eval);
//print " $i: result=$rez arr[0]={$arr[0]} arr[1]={$arr[1]} <BR>\n ";
if ($rez) $where_arr[] = $arr;
}
$i += 1;
}
$this->_rezarray = $where_arr;
}else
$where_arr = $this->_origarray;
// THIS PROJECTION CODE ONLY WORKS FOR 1 COLUMN,
// OTHERWISE IT RETURNS ALL COLUMNS
if (substr($usql,0,7) == 'SELECT ') {
$at = strpos($usql,' FROM ');
$sel = trim(substr($usql,7,$at-7));
$distinct = false;
if (substr($sel,0,8) == 'DISTINCT') {
$distinct = true;
$sel = trim(substr($sel,8,$at));
}
// $sel holds the selection clause, comma delimited
// currently we only project if one column is involved
// this is to support popups in PHPLens
if (strpos(',',$sel)===false) {
$colarr = array();
preg_match("/$eregword/",$sel,$colarr);
$col = $colarr[1];
$i = 0;
$n = '';
reset($this->_colnames);
foreach ($this->_colnames as $n) {
if ($col == strtoupper(trim($n))) break;
$i += 1;
}
if ($n && $col) {
$distarr = array();
$projarray = array();
$projtypes = array($this->_types[$i]);
$projnames = array($n);
foreach ($where_arr as $a) {
if ($i == 0 && $this->_skiprow1) {
$projarray[] = array($n);
continue;
}
if ($distinct) {
$v = strtoupper($a[$i]);
if (! $distarr[$v]) {
$projarray[] = array($a[$i]);
$distarr[$v] = 1;
}
} else
$projarray[] = array($a[$i]);
} //foreach
//print_r($projarray);
}
} // check 1 column in projection
} // is SELECT
if (empty($projarray)) {
$projtypes = $this->_types;
$projarray = $where_arr;
$projnames = $this->_colnames;
}
$this->_rezarray = $projarray;
$this->_reztypes = $projtypes;
$this->_reznames = $projnames;
$pos = strpos($usql,' ORDER BY ');
if ($pos === false) return $this;
$orderby = trim(substr($usql,$pos+10));
preg_match("/$eregword/",$orderby,$arr);
if (sizeof($arr) < 2) return $this; // actually invalid sql
$col = $arr[1];
$at = (integer) $col;
if ($at == 0) {
$i = 0;
reset($projnames);
foreach ($projnames as $n) {
if (strtoupper(trim($n)) == $col) {
$at = $i+1;
break;
}
$i += 1;
}
}
if ($at <= 0 || $at > sizeof($projarray[0])) return $this; // cannot find sort column
$at -= 1;
// generate sort array consisting of (sortval1, row index1) (sortval2, row index2)...
$sorta = array();
$t = $projtypes[$at];
$num = ($t == 'I' || $t == 'N');
for ($i=($this->_skiprow1)?1:0, $max = sizeof($projarray); $i < $max; $i++) {
$row = $projarray[$i];
$val = ($num)?(float)$row[$at]:$row[$at];
$sorta[]=array($val,$i);
}
// check for desc sort
$orderby = substr($orderby,strlen($col)+1);
$arr = array();
preg_match('/([A-Z_0-9]*)/i',$orderby,$arr);
if (trim($arr[1]) == 'DESC') $sortf = 'adodb_cmpr';
else $sortf = 'adodb_cmp';
// hasta la sorta babe
usort($sorta, $sortf);
// rearrange original array
$arr2 = array();
if ($this->_skiprow1) $arr2[] = $projarray[0];
foreach($sorta as $v) {
$arr2[] = $projarray[$v[1]];
}
$this->_rezarray = $arr2;
return $this;
}
/* Returns: the last error message from previous database operation */
function ErrorMsg()
{
return '';
}
/* Returns: the last error number from previous database operation */
function ErrorNo()
{
return 0;
}
// returns true or false
function _close()
{
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_text extends ADORecordSet_array
{
var $databaseType = "text";
function __construct( $conn,$mode=false)
{
parent::__construct();
$this->InitArray($conn->_rezarray,$conn->_reztypes,$conn->_reznames);
$conn->_rezarray = false;
}
} // class ADORecordSet_text
} // defined

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
*/
@ -17,7 +17,7 @@ Set tabs to 4 for best viewing.
if (!defined('ADODB_DIR')) die();
if (!defined('_ADODB_ODBC_LAYER')) {
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php");
}
if (!defined('ADODB_VFP')){
define('ADODB_VFP',1);
@ -69,11 +69,6 @@ class ADORecordSet_vfp extends ADORecordSet_odbc {
var $databaseType = "vfp";
function __construct($id,$mode=false)
{
return parent::__construct($id,$mode);
}
function MetaType($t, $len = -1, $fieldobj = false)
{
if (is_object($t)) {
@ -95,7 +90,7 @@ class ADORecordSet_vfp extends ADORecordSet_odbc {
case 'I': return 'I';
default: return 'N';
default: return ADODB_DEFAULT_METATYPE;
}
}
}

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Library for basic performance monitoring and tuning

View file

@ -1,6 +1,6 @@
<?php
/*
@version v5.20.16 12-Jan-2020
@version v5.21.0 2021-02-27
@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
Released under both BSD license and Lesser GPL library license.
@ -8,7 +8,7 @@
the BSD license will take precedence. See License.txt.
Set tabs to 4 for best viewing.
Latest version is available at http://adodb.org/
Latest version is available at https://adodb.org/
Library for basic performance monitoring and tuning

Some files were not shown because too many files have changed in this diff Show more