MDL-74095 lib: Upgrade ADODB to 5.22.2

Signed-off-by: Daniel Ziegenberg <[email protected]>
This commit is contained in:
Daniel Ziegenberg
2022-06-08 18:18:47 +02:00
parent 5500d143f4
commit bfe70c09f9
54 changed files with 4529 additions and 4012 deletions
+3 -2
View File
@@ -1,8 +1,9 @@
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)
[![Download ADOdb](https://img.shields.io/sourceforge/dm/adodb.svg)](https://sourceforge.net/projects/adodb/files/latest/download)
[![Join chat on Gitter](https://img.shields.io/gitter/room/adodb/adodb?logo=gitter)](https://gitter.im/adodb/adodb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![SourceForge Downloads Shield](https://img.shields.io/sourceforge/dm/adodb?label=SourceForge&logo=sourceforge&color=informational)](https://sourceforge.net/projects/adodb/files/latest/download)
[![Packagist Downloads Shield](https://img.shields.io/packagist/dm/ADOdb/ADOdb-php?label=Packagist&logo=packagist&logoColor=white&color=informational)](https://packagist.org/packages/adodb/adodb-php)
(c) 2000-2013 John Lim (jlim@natsoft.com)
(c) 2014 Damien Regad, Mark Newnham and the
+45
View File
@@ -0,0 +1,45 @@
# ADOdb Security Policy
## Supported Versions
The following releases of the library are currently being supported with
security updates. Please refer to the [project's home page](https://adodb.org)
for actual version numbers.
- Stable
- Legacy
- Development (Git *master* branch)
Older releases are no longer supported.
## Reporting a Vulnerability
If you discover a vulnerability in ADOdb, please contact
the [project's maintainer](https://github.com/dregad)
- by e-mail (look for it in the Git history)
- via private chat on [Gitter](https://gitter.im/dregad)
Kindly provide the following information in your report:
- Affected ADOdb version(s) or Git revision
- A clear and detailed description of the issue, including if possible a code
snippet to demonstrate or reproduce the vulnerability
- A patch for the issue if you have one, preferably in *Git diff* format
### CVE handling
To ensure a comprehensive and detailed declaration of the issue, we generally
prefer requesting CVE IDs ourselves, which usually happens after our analysis
confirms the vulnerability.
In case you have already obtained a CVE ID, do not forget to reference it in
your report.
### Credits
Let us know if and how you wish to be credited for the finding.
Your name, e-mail, company, etc. will be included as specified in the CVE
report, as well as in the Git commit message patching the issue.
+2 -2
View File
@@ -281,7 +281,7 @@ class ADODB_Active_Record {
static function TableBelongsTo($table, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
$ar = new ADOdb_Active_Record($table);
$ar = new ADODB_Active_Record($table);
$ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
}
@@ -290,7 +290,7 @@ class ADODB_Active_Record {
if (!is_array($tablePKey)) {
$tablePKey = array($tablePKey);
}
$ar = new ADOdb_Active_Record($table, $tablePKey);
$ar = new ADODB_Active_Record($table, $tablePKey);
$ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
}
+19 -17
View File
@@ -29,11 +29,13 @@ global $ADODB_INCLUDED_CSV;
$ADODB_INCLUDED_CSV = 1;
/**
* convert a recordset into special format
* Convert a recordset into special format
*
* @param rs the recordset
* @param ADORecordSet $rs the recordset
* @param ADOConnection $conn
* @param string $sql
*
* @return the CSV formatted data
* @return string the CSV formatted data
*/
function _rs2serialize(&$rs,$conn=false,$sql='')
{
@@ -74,7 +76,7 @@ $ADODB_INCLUDED_CSV = 1;
$savefetch = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode;
$class = $rs->connection->arrayClass;
$rs2 = new $class();
$rs2 = new $class(-1); // Dummy query Id
$rs2->timeCreated = $rs->timeCreated; # memcache fix
$rs2->sql = $rs->sql;
$rs2->oldProvider = $rs->dataProvider;
@@ -83,19 +85,19 @@ $ADODB_INCLUDED_CSV = 1;
return $line.serialize($rs2);
}
/**
* Open CSV file and convert it into Data.
*
* @param url file/ftp/http url
* @param err returns the error message
* @param timeout dispose if recordset has been alive for $timeout secs
*
* @return recordset, or false if error occurred. If no
* error occurred in sql INSERT/UPDATE/DELETE,
* empty recordset is returned
*/
function csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
/**
* Open CSV file and convert it into Data.
*
* @param string $url file/ftp/http url
* @param string &$err returns the error message
* @param int $timeout dispose if recordset has been alive for $timeout secs
* @param string $rsclass RecordSet class to return
*
* @return ADORecordSet|false recordset, or false if error occurred.
* If no error occurred in sql INSERT/UPDATE/DELETE,
* empty recordset is returned.
*/
function csv2rs($url, &$err, $timeout=0, $rsclass='ADORecordSet_array')
{
$false = false;
$err = false;
+29 -11
View File
@@ -353,7 +353,7 @@ class ADODB_DataDict {
function nameQuote($name = NULL,$allowBrackets=false)
{
if (!is_string($name)) {
return FALSE;
return false;
}
$name = trim($name);
@@ -427,6 +427,15 @@ class ADODB_DataDict {
function actualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
return $meta;
}
@@ -498,7 +507,7 @@ class ADODB_DataDict {
* @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 ''
* @param array|string $tableoptions='' options for the new table see createTableSQL, default ''
* @return array with SQL strings
*/
function alterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
@@ -553,7 +562,7 @@ class ADODB_DataDict {
* @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 ''
* @param array|string $tableoptions='' options for the new table see createTableSQL, default ''
* @return array with SQL strings
*/
function dropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
@@ -695,16 +704,25 @@ class ADODB_DataDict {
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,',');
if ($dotat === false) $fsize = $v;
else {
$fsize = substr($v,0,$dotat);
$fprec = substr($v,$dotat+1);
}
break;
$dotat = strpos($v,'.');
if ($dotat === false)
$dotat = strpos($v,',');
if ($dotat === false)
$fsize = $v;
else {
$fsize = substr($v,0,$dotat);
$fprec = substr($v,$dotat+1);
}
break;
case 'UNSIGNED': $funsigned = true; break;
case 'AUTOINCREMENT':
case 'AUTO': $fautoinc = true; $fnotnull = true; break;
+3
View File
@@ -45,6 +45,9 @@ var $database = '';
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)";
break;
default:
//Prevent PHP warning if $p1 or $p2 are arrays.
$p1 = ( is_array($p1) ) ? 'Array' : $p1;
$p2 = ( is_array($p2) ) ? 'Array' : $p2;
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)";
break;
}
+46 -6
View File
@@ -174,7 +174,7 @@ class ADOdbLoadBalancer
* @param string $type Type of database connection, either: 'write' capable or 'readonly'
* @return bool|int|string
*/
private function getConnectionByWeight($type)
public function getConnectionByWeight($type)
{
if ($type == 'readonly') {
$total_weight = $this->total_connection_weights['all'];
@@ -233,7 +233,7 @@ class ADOdbLoadBalancer
* @return bool|ADOConnection
* @throws Exception
*/
private function _getConnection($connection_id)
public function getConnectionById($connection_id)
{
if (isset($this->connections[$connection_id])) {
$connection_obj = $this->connections[$connection_id];
@@ -261,6 +261,15 @@ class ADOdbLoadBalancer
throw $e; // No connections left, reThrow exception so application can catch it.
}
// Check to see if a connection test callback was defined, and if so execute it.
// This is useful for testing replication lag and such to ensure the connection is suitable to be used.
$test_connection_callback = $connection_obj->getConnectionTestCallback();
if (is_callable($test_connection_callback)
&& $test_connection_callback($connection_obj, $adodb_obj) !== TRUE
) {
return false;
}
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);
@@ -298,9 +307,12 @@ class ADOdbLoadBalancer
if ($connection_id !== false) {
try {
$adodb_obj = $this->_getConnection($connection_id);
// $connection_obj = $this->connections[$connection_id];
break;
$adodb_obj = $this->getConnectionById($connection_id);
if (is_object($adodb_obj)) {
break; //Found valid connection, continue with it.
} else {
throw new Exception('ADODB Connection Object does not exist. Perhaps LoadBalancer Database Connection Test Failed?');
}
} catch (Exception $e) {
// Connection error, see if there are other connections to try still.
$this->removeConnection($connection_id);
@@ -315,6 +327,10 @@ class ADOdbLoadBalancer
}
}
if (!isset($connection_id)) {
throw new Exception('No connection available to use at this time! Type: ' . $type);
}
$this->last_connection_id[$type] = $connection_id;
if ($pin_connection === true) {
@@ -432,7 +448,7 @@ class ADOdbLoadBalancer
&& $connection_obj->getADOdbObject()->_connectionID !== false
)
) {
$adodb_obj = $this->_getConnection($key);
$adodb_obj = $this->getConnectionById($key);
if (is_object($adodb_obj)) {
$result_arr[] = $adodb_obj->Execute($sql, $inputarr);
}
@@ -595,6 +611,7 @@ class ADOdbLoadBalancer
case 'binddate':
case 'bindtimestamp':
case 'setfetchmode':
case 'setcustommetatype':
$type = false; // No connection necessary.
break;
@@ -686,6 +703,11 @@ class ADOdbLoadBalancerConnection
*/
protected $adodb_obj = false;
/**
* @var callable Closure
*/
protected $connection_test_callback = NULL;
/**
* @var string Type of connection, either 'write' capable or 'readonly'
*/
@@ -761,6 +783,24 @@ class ADOdbLoadBalancerConnection
return true;
}
/**
* Anonymous function that is called and must return TRUE for the connection to be usable.*
* The first argument is the type of connection to test.
* Useful to check things like replication lag.
* @param callable $callback
* @return void
*/
function setConnectionTestCallback($callback) {
$this->connection_test_callback = $callback;
}
/**
* @return callable|null
*/
function getConnectionTestCallback() {
return $this->connection_test_callback;
}
/**
* Returns the ADODB object for this connection.
*
+365 -153
View File
@@ -17,6 +17,8 @@
*
* @copyright 2000-2013 John Lim
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*
* @noinspection PhpUnused
*/
// security - hide paths
@@ -26,183 +28,393 @@ global $ADODB_INCLUDED_MEMCACHE;
$ADODB_INCLUDED_MEMCACHE = 1;
global $ADODB_INCLUDED_CSV;
if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
if (empty($ADODB_INCLUDED_CSV)) {
include_once(ADODB_DIR . '/adodb-csvlib.inc.php');
}
class ADODB_Cache_MemCache {
var $createdir = false; // create caching directory structure?
class ADODB_Cache_MemCache
{
/**
* @var bool Prevents parent class calling non-existant function
*/
public $createdir = false;
// $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;
/**
* @var array of hosts
*/
private $hosts;
//-----------------------------
// memcache specific variables
/**
* @var int Connection Port, uses default
*/
private $port;
var $hosts; // array of hosts
var $port = 11211;
var $compress = false; // memcache compression with zlib
/**
* @var bool memcache compression with zlib
*/
private $compress;
var $_connected = false;
var $_memcache = false;
/**
* @var array of options for memcached only
*/
private $options;
function __construct(&$obj)
{
$this->hosts = $obj->memCacheHost;
$this->port = $obj->memCachePort;
$this->compress = $obj->memCacheCompress;
/**
* @var bool Internal flag indicating successful connection
*/
private $isConnected = false;
/**
* @var Memcache|Memcached Handle for the Memcache library
*
* Populated with the proper library on connect, used later when
* there are differences in specific calls between memcache and memcached
*/
private $memcacheLibrary = false;
/**
* @var array New server feature controller lists available servers
*/
private $serverControllers = array();
/**
* @var array New server feature template uses granular server controller
*/
private $serverControllerTemplate = array(
'host' => '',
'port' => 11211,
'weight' => 0,
);
/**
* An integer index into the libraries
* @see $libraries
*/
const MCLIB = 1;
const MCLIBD = 2;
/**
* @var array Xrefs the library flag to the actual class name
*/
private $libraries = array(
self::MCLIB => 'Memcache',
self::MCLIBD => 'Memcached'
);
/**
* @var int An indicator of which library we are using
*/
private $libraryFlag;
/**
* Class Constructor.
*
* @param ADOConnection $db
*/
public function __construct($db)
{
$this->hosts = $db->memCacheHost;
$this->port = $this->serverControllerTemplate['port'] = $db->memCachePort;
$this->compress = $db->memCacheCompress;
$this->options = $db->memCacheOptions;
}
/**
* Return true if the current library is Memcached.
* @return bool
*/
public function isLibMemcached(): bool
{
return $this->libraryFlag == self::MCLIBD;
}
/**
* Lazy connection.
*
* The connection only occurs on CacheExecute call.
*
* @param string $err
*
* @return bool success of connecting to a server
*/
public function connect(&$err)
{
// do we have memcache or memcached? see the note at adodb.org on memcache
if (class_exists('Memcache')) {
$this->libraryFlag = self::MCLIB;
} elseif (class_exists('Memcached')) {
$this->libraryFlag = self::MCLIBD;
} else {
$err = 'Neither the Memcache nor Memcached PECL extensions were found!';
return false;
}
// implement as lazy connection. The connection only occurs on CacheExecute call
function connect(&$err)
{
// 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!';
$usedLibrary = $this->libraries[$this->libraryFlag];
/** @var Memcache|Memcached $memCache */
$memCache = new $usedLibrary;
if (!$memCache) {
$err = 'Memcache library failed to initialize';
return false;
}
// Convert simple compression flag for memcached
if ($this->isLibMemcached()) {
$this->options[Memcached::OPT_COMPRESSION] = $this->compress;
}
// Are there any options available for memcached
if ($this->isLibMemcached() && count($this->options) > 0) {
$optionSuccess = $memCache->setOptions($this->options);
if (!$optionSuccess) {
$err = 'Invalid option parameters passed to Memcached';
return false;
}
}
if (!is_array($this->hosts)) $this->hosts = array($this->hosts);
// Have we passed a controller array
if (!is_array($this->hosts)) {
$this->hosts = array($this->hosts);
}
$failcnt = 0;
foreach($this->hosts as $host) {
if (!@$memcache->addServer($host,$this->port)) {
$failcnt += 1;
if (!is_array($this->hosts[0])) {
// Old way, convert to controller
foreach ($this->hosts as $ipAddress) {
$connector = $this->serverControllerTemplate;
$connector['host'] = $ipAddress;
$connector['port'] = $this->port;
$this->serverControllers[] = $connector;
}
} else {
// New way, must validate port, etc
foreach ($this->hosts as $controller) {
$connector = array_merge($this->serverControllerTemplate, $controller);
if ($this->isLibMemcached()) {
$connector['weight'] = (int)$connector['weight'];
} else {
// Cannot use weight in memcache, simply discard
$connector['weight'] = 0;
}
$this->serverControllers[] = $connector;
}
if ($failcnt == sizeof($this->hosts)) {
$err = 'Can\'t connect to any memcache server';
return false;
}
$this->_connected = true;
$this->_memcache = $memcache;
}
// Checks for existing connections ( but only for memcached )
if ($this->isLibMemcached() && !empty($memCache->getServerList())) {
// Use the existing configuration
$this->isConnected = true;
$this->memcacheLibrary = $memCache;
return true;
}
// returns true or false. true if successful save
function writecache($filename, $contents, $debug, $secs2cache)
{
if (!$this->_connected) {
$err = '';
if (!$this->connect($err) && $debug) ADOConnection::outp($err);
$failcnt = 0;
foreach ($this->serverControllers as $controller) {
if ($this->isLibMemcached()) {
if (!@$memCache->addServer($controller['host'], $controller['port'], $controller['weight'])) {
$failcnt++;
}
} else {
if (!@$memCache->addServer($controller['host'], $controller['port'])) {
$failcnt++;
}
}
if (!$this->_memcache) return false;
}
if ($failcnt == sizeof($this->serverControllers)) {
$err = 'Can\'t connect to any memcache server';
return false;
}
$failed=false;
switch ($this->library) {
case 'Memcache':
if (!$this->_memcache->set($filename, $contents, $this->compress ? MEMCACHE_COMPRESSED : 0, $secs2cache)) {
$failed=true;
$this->memcacheLibrary = $memCache;
// A valid memcache connection is available
$this->isConnected = true;
return true;
}
/**
* Writes a cached query to the server
*
* @param string $filename The MD5 of the query to cache
* @param string $contents The query results
* @param bool $debug
* @param int $secs2cache
*
* @return bool true or false. true if successful save
*/
public function writeCache($filename, $contents, $debug, $secs2cache)
{
$err = '';
if (!$this->isConnected && $debug) {
// Call to writeCache() before connect(), try to connect
if (!$this->connect($err)) {
ADOConnection::outp($err);
}
} else {
if (!$this->isConnected) {
$this->connect($err);
}
}
if (!$this->memcacheLibrary) {
return false;
}
$failed = false;
switch ($this->libraryFlag) {
case self::MCLIB:
if (!$this->memcacheLibrary->set($filename, $contents, $this->compress ? MEMCACHE_COMPRESSED : 0,
$secs2cache)) {
$failed = true;
}
break;
case self::MCLIBD:
if (!$this->memcacheLibrary->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;
}
return true;
}
/**
* Reads a cached query from the server.
*
* @param string $filename The MD5 of the query to read
* @param string $err The query results
* @param int $secs2cache
* @param object $rsClass **UNUSED**
*
* @return object|bool record or false.
*
* @noinspection PhpUnusedParameterInspection
*/
public function readCache($filename, &$err, $secs2cache, $rsClass)
{
if (!$this->isConnected) {
$this->connect($err);
}
if (!$this->memcacheLibrary) {
return false;
}
$rs = $this->memcacheLibrary->get($filename);
if (!$rs) {
$err = 'Item with such key doesn\'t exist on the memcache server.';
return false;
}
// hack, should actually use _csv2rs
$rs = explode("\n", $rs);
unset($rs[0]);
$rs = join("\n", $rs);
$rs = unserialize($rs);
if (!is_object($rs)) {
$err = 'Unable to unserialize $rs';
return false;
}
if ($rs->timeCreated == 0) {
return $rs;
} // apparently have been reports that timeCreated was set to 0 somewhere
$tdiff = intval($rs->timeCreated + $secs2cache - time());
if ($tdiff <= 2) {
switch ($tdiff) {
case 2:
if ((rand() & 15) == 0) {
$err = "Timeout 2";
return false;
}
break;
case 'Memcached':
if (!$this->_memcache->set($filename, $contents, $secs2cache)) {
$failed=true;
case 1:
if ((rand() & 3) == 0) {
$err = "Timeout 1";
return false;
}
break;
default:
$failed=true;
break;
$err = "Timeout 0";
return false;
}
if($failed) {
if ($debug) ADOConnection::outp(" Failed to save data at the memcache server!<br>\n");
return false;
}
return true;
}
// returns a recordset
function readcache($filename, &$err, $secs2cache, $rsClass)
{
$false = false;
if (!$this->_connected) $this->connect($err);
if (!$this->_memcache) return $false;
$rs = $this->_memcache->get($filename);
if (!$rs) {
$err = 'Item with such key doesn\'t exist on the memcache server.';
return $false;
}
// hack, should actually use _csv2rs
$rs = explode("\n", $rs);
unset($rs[0]);
$rs = join("\n", $rs);
$rs = unserialize($rs);
if (! is_object($rs)) {
$err = 'Unable to unserialize $rs';
return $false;
}
if ($rs->timeCreated == 0) return $rs; // apparently have been reports that timeCreated was set to 0 somewhere
$tdiff = intval($rs->timeCreated+$secs2cache - time());
if ($tdiff <= 2) {
switch($tdiff) {
case 2:
if ((rand() & 15) == 0) {
$err = "Timeout 2";
return $false;
}
break;
case 1:
if ((rand() & 3) == 0) {
$err = "Timeout 1";
return $false;
}
break;
default:
$err = "Timeout 0";
return $false;
}
}
return $rs;
}
function flushall($debug=false)
{
if (!$this->_connected) {
$err = '';
if (!$this->connect($err) && $debug) ADOConnection::outp($err);
}
if (!$this->_memcache) return false;
$del = $this->_memcache->flush();
if ($debug)
if (!$del) ADOConnection::outp("flushall: failed!<br>\n");
else ADOConnection::outp("flushall: succeeded!<br>\n");
return $del;
}
function flushcache($filename, $debug=false)
{
if (!$this->_connected) {
$err = '';
if (!$this->connect($err) && $debug) ADOConnection::outp($err);
}
if (!$this->_memcache) return false;
$del = $this->_memcache->delete($filename);
if ($debug)
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;
}
// not used for memcache
function createdir($dir, $hash)
{
return true;
}
return $rs;
}
/**
* Flushes all of the stored memcache data
*
* @param bool $debug
*
* @return bool The response from the memcache server
*/
public function flushAll($debug = false)
{
if (!$this->isConnected) {
$err = '';
if (!$this->connect($err) && $debug) {
ADOConnection::outp($err);
}
}
if (!$this->memcacheLibrary) {
return false;
}
$del = $this->memcacheLibrary->flush();
if ($debug) {
if (!$del) {
ADOConnection::outp("flushall: failed!<br>\n");
} else {
ADOConnection::outp("flushall: succeeded!<br>\n");
}
}
return $del;
}
/**
* Flushes the contents of a specified query
*
* @param string $filename The MD5 of the query to flush
* @param bool $debug
*
* @return bool The response from the memcache server
*/
public function flushCache($filename, $debug = false)
{
if (!$this->isConnected) {
$err = '';
if (!$this->connect($err) && $debug) {
ADOConnection::outp($err);
}
}
if (!$this->memcacheLibrary) {
return false;
}
$del = $this->memcacheLibrary->delete($filename);
if ($debug) {
if (!$del) {
ADOConnection::outp("flushcache: $filename entry doesn't exist on memcache server!<br>\n");
} else {
ADOConnection::outp("flushcache: $filename entry flushed from memcache server!<br>\n");
}
}
return $del;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+668 -408
View File
File diff suppressed because it is too large Load Diff
+15 -5
View File
@@ -30,6 +30,15 @@ class ADODB2_access extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch($meta) {
case 'C': return 'TEXT';
case 'XL':
@@ -41,18 +50,19 @@ class ADODB2_access extends ADODB_DataDict {
case 'B': return 'BINARY';
case 'TS':
case 'D': return 'DATETIME';
case 'D':
return 'DATETIME';
case 'T': return 'DATETIME';
case 'L': return 'BYTE';
case 'I': return 'INTEGER';
case 'L': return 'BYTE';
case 'I': return 'INTEGER';
case 'I1': return 'BYTE';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'INTEGER';
case 'F': return 'DOUBLE';
case 'N': return 'NUMERIC';
case 'F': return 'DOUBLE';
case 'N': return 'NUMERIC';
default:
return $meta;
}
+9
View File
@@ -34,6 +34,15 @@ class ADODB2_db2 extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL': return 'CLOB';
+143 -93
View File
@@ -22,8 +22,8 @@
// security - hide paths
if (!defined('ADODB_DIR')) die();
class ADODB2_firebird extends ADODB_DataDict {
class ADODB2_firebird extends ADODB_DataDict
{
var $databaseType = 'firebird';
var $seqField = false;
var $seqPrefix = 's_';
@@ -32,69 +32,92 @@ class ADODB2_firebird extends ADODB_DataDict {
var $alterCol = ' ALTER';
var $dropCol = ' DROP';
function ActualType($meta)
function actualType($meta)
{
$meta = strtoupper($meta);
// Add support for custom meta types.
// We do this first, that allows us to override existing types
if (isset($this->connection->customMetaTypes[$meta])) {
return $this->connection->customMetaTypes[$meta]['actual'];
}
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL':
case 'X': return 'BLOB SUB_TYPE TEXT';
case 'C':
return 'VARCHAR';
case 'XL':
return 'BLOB SUB_TYPE BINARY';
case 'X':
return 'BLOB SUB_TYPE TEXT';
case 'C2': return 'VARCHAR(32765)'; // up to 32K
case 'X2': return 'VARCHAR(4096)';
case 'C2':
return 'VARCHAR(32765)'; // up to 32K
case 'X2':
return 'VARCHAR(4096)';
case 'V': return 'CHAR';
case 'C1': return 'CHAR(1)';
case 'V':
return 'CHAR';
case 'C1':
return 'CHAR(1)';
case 'B': return 'BLOB';
case 'B':
return 'BLOB';
case 'D': return 'DATE';
case 'TS':
case 'T': return 'TIMESTAMP';
case 'D':
return 'DATE';
case 'TS':
case 'T':
return 'TIMESTAMP';
case 'L': return 'SMALLINT';
case 'I': return 'INTEGER';
case 'I1': return 'SMALLINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INTEGER';
case 'I8': return 'BIGINT';
case 'L':
case 'I1':
case 'I2':
return 'SMALLINT';
case 'I':
case 'I4':
return 'INTEGER';
case 'I8':
return 'BIGINT';
case 'F': return 'DOUBLE PRECISION';
case 'N': return 'DECIMAL';
default:
return $meta;
case 'F':
return 'DOUBLE PRECISION';
case 'N':
return 'DECIMAL';
default:
return $meta;
}
}
function NameQuote($name = NULL,$allowBrackets=false)
function nameQuote($name = null, $allowBrackets = false)
{
if (!is_string($name)) {
return FALSE;
return false;
}
$name = trim($name);
if ( !is_object($this->connection) ) {
if (!is_object($this->connection)) {
return $name;
}
$quote = $this->connection->nameQuote;
// if name is of the form `name`, quote it
if ( preg_match('/^`(.+)`$/', $name, $matches) ) {
if (preg_match('/^`(.+)`$/', $name, $matches)) {
return $quote . $matches[1] . $quote;
}
// if name contains special characters, quote it
if ( !preg_match('/^[' . $this->nameRegex . ']+$/', $name) ) {
if (!preg_match('/^[' . $this->nameRegex . ']+$/', $name)) {
return $quote . $name . $quote;
}
return $quote . $name . $quote;
}
function CreateDatabase($dbname, $options=false)
function createDatabase($dbname, $options = false)
{
$options = $this->_Options($options);
$sql = array();
$sql[] = "DECLARE EXTERNAL FUNCTION LOWER CSTRING(80) RETURNS CSTRING(80) FREE_IT ENTRY_POINT 'IB_UDF_lower' MODULE_NAME 'ib_udf'";
@@ -102,50 +125,62 @@ class ADODB2_firebird extends ADODB_DataDict {
return $sql;
}
function _DropAutoIncrement($t)
function _dropAutoIncrement($tabname)
{
if (strpos($t,'.') !== false) {
$tarr = explode('.',$t);
return 'DROP GENERATOR '.$tarr[0].'."s_'.$tarr[1].'"';
if (strpos($tabname, '.') !== false) {
$tarr = explode('.', $tabname);
return 'DROP SEQUENCE ' . $tarr[0] . '."s_' . $tarr[1] . '"';
}
return 'DROP GENERATOR s_'.$t;
return 'DROP SEQUENCE s_' . $tabname;
}
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";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fautoinc) $this->seqField = $fname;
if (strlen($fdefault)) {
$suffix .= " DEFAULT $fdefault";
}
if ($fnotnull) {
$suffix .= ' NOT NULL';
}
if ($fautoinc) {
$this->seqField = $fname;
}
$fconstraint = preg_replace("/``/", "\"", $fconstraint);
if ($fconstraint) $suffix .= ' '.$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())
* 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);
list($lines, $pkey, $idxs) = $this->_GenFields($flds, true);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
if ($lines == null) {
$lines = array();
}
$taboptions = $this->_Options($tableoptions);
$tabname = $this->TableName ($tabname);
$sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
$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 ($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']);
foreach ($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
@@ -154,44 +189,47 @@ class ADODB2_firebird extends ADODB_DataDict {
}
/*
CREATE or replace TRIGGER jaddress_insert
before insert on jaddress
for each row
begin
IF ( NEW."seqField" IS NULL OR NEW."seqField" = 0 ) THEN
NEW."seqField" = GEN_ID("GEN_tabname", 1);
end;
*/
function _Triggers($tabname,$tableoptions)
/*
CREATE or replace TRIGGER jaddress_insert
before insert on jaddress
for each row
begin
IF ( NEW."seqField" IS NULL OR NEW."seqField" = 0 ) THEN
NEW."seqField" = GEN_ID("GEN_tabname", 1);
end;
*/
function _triggers($tabname, $taboptions)
{
if (!$this->seqField) return array();
if (!$this->seqField) {
return array();
}
$tab1 = preg_replace( '/"/', '', $tabname );
$tab1 = preg_replace('/"/', '', $tabname);
if ($this->schema) {
$t = strpos($tab1,'.');
if ($t !== false) $tab = substr($tab1,$t+1);
else $tab = $tab1;
$t = strpos($tab1, '.');
if ($t !== false) {
$tab = substr($tab1, $t + 1);
} else {
$tab = $tab1;
}
$seqField = $this->seqField;
$seqname = $this->schema.'.'.$this->seqPrefix.$tab;
$trigname = $this->schema.'.t_'.$this->seqPrefix.$tab;
$seqname = $this->schema . '.' . $this->seqPrefix . $tab;
$trigname = $this->schema . '.t_' . $this->seqPrefix . $tab;
} else {
$seqField = $this->seqField;
$seqname = $this->seqPrefix.$tab1;
$trigname = 't_'.$seqname;
$seqname = $this->seqPrefix . $tab1;
$trigname = 't_' . $seqname;
}
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";
if (isset($taboptions['DROP'])) {
$sql[] = "DROP SEQUENCE $seqname";
} elseif (isset($taboptions['REPLACE'])) {
$sql[] = "DROP SEQUENCE \"$seqname\"";
$sql[] = "CREATE SEQUENCE \"$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 SEQUENCE $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;
@@ -201,27 +239,39 @@ end;
/**
* 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 ''
* @param string $tableflds Unused
* @param array|string $tableoptions Unused
*
* @return array with SQL strings
*/
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
public 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, , $idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
if ($lines == null) {
$lines = array();
}
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
foreach($lines as $v) {
foreach ($lines as $v) {
/*
* The type must be preceded by the keyword 'TYPE'
*/
$vExplode = explode(' ', $v);
$vExplode = array_filter($vExplode);
array_splice($vExplode, 1, 0, array('TYPE'));
$v = implode(' ', $vExplode);
$sql[] = $alter . $v;
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
foreach ($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
@@ -28,8 +28,19 @@ class ADODB2_generic extends ADODB_DataDict {
var $seqField = false;
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL':
@@ -30,6 +30,15 @@ class ADODB2_ibase extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL':
@@ -30,6 +30,15 @@ class ADODB2_informix extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch($meta) {
case 'C': return 'VARCHAR';// 255
case 'XL':
+16 -1
View File
@@ -68,9 +68,14 @@ class ADODB2_mssql extends ADODB_DataDict {
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
switch ($t) {
case 'R':
case 'INT':
case 'INTEGER': return 'I';
@@ -87,6 +92,16 @@ class ADODB2_mssql extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR';
@@ -71,7 +71,13 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
$fieldobj = $t;
$t = $fieldobj->type;
}
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
$_typeConversion = array(
-155 => 'D',
93 => 'D',
@@ -115,7 +121,15 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
function ActualType($meta)
{
$DATE_TYPE = 'DATETIME';
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR';
+27 -4
View File
@@ -33,7 +33,7 @@ class ADODB2_mysql extends ADODB_DataDict {
public $blobAllowsNotNull = true;
function MetaType($t,$len=-1,$fieldobj=false)
function metaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
@@ -44,7 +44,14 @@ class ADODB2_mysql extends ADODB_DataDict {
$is_serial = is_object($fieldobj) && $fieldobj->primary_key && $fieldobj->auto_increment;
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
switch ($t) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
@@ -84,13 +91,27 @@ 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 ADODB_DEFAULT_METATYPE;
default:
return ADODB_DEFAULT_METATYPE;
}
}
function ActualType($meta)
{
switch(strtoupper($meta)) {
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch($meta)
{
case 'C': return 'VARCHAR';
case 'XL':return 'LONGTEXT';
case 'X': return 'TEXT';
@@ -114,7 +135,9 @@ class ADODB2_mysql extends ADODB_DataDict {
case 'F': return 'DOUBLE';
case 'N': return 'NUMERIC';
default:
return $meta;
}
}
+16 -1
View File
@@ -50,7 +50,13 @@ class ADODB2_oci8 extends ADODB_DataDict {
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
switch ($t) {
case 'VARCHAR':
case 'VARCHAR2':
case 'CHAR':
@@ -92,6 +98,15 @@ class ADODB2_oci8 extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch($meta) {
case 'C': return 'VARCHAR';
case 'X': return $this->typeX;
+46 -27
View File
@@ -34,7 +34,7 @@ class ADODB2_postgres extends ADODB_DataDict
public $blobAllowsDefaultValue = true;
public $blobAllowsNotNull = true;
function metaType($t, $len=-1, $fieldobj=false)
{
if (is_object($t)) {
@@ -42,16 +42,23 @@ class ADODB2_postgres extends ADODB_DataDict
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
$is_serial = is_object($fieldobj) && !empty($fieldobj->primary_key) && !empty($fieldobj->unique) &&
!empty($fieldobj->has_default) && substr($fieldobj->default_value,0,8) == 'nextval(';
switch (strtoupper($t)) {
switch ($t) {
case 'INTERVAL':
case 'CHAR':
case 'CHARACTER':
case 'VARCHAR':
case 'NAME':
case 'BPCHAR':
case 'BPCHAR':
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
@@ -94,13 +101,22 @@ class ADODB2_postgres extends ADODB_DataDict
case 'REAL':
return 'F';
default:
return ADODB_DEFAULT_METATYPE;
default:
return ADODB_DEFAULT_METATYPE;
}
}
function actualType($meta)
function actualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch ($meta) {
case 'C': return 'VARCHAR';
case 'XL':
@@ -152,7 +168,7 @@ class ADODB2_postgres extends ADODB_DataDict
if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
list(,$colname,$default) = $matches;
$sql[] = $alter . str_replace('DEFAULT '.$default,'',$v);
$sql[] = 'UPDATE '.$tabname.' SET '.$colname.'='.$default;
$sql[] = 'UPDATE '.$tabname.' SET '.$colname.'='.$default.' WHERE '.$colname.' IS NULL ';
$sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET DEFAULT ' . $default;
} else {
$sql[] = $alter . $v;
@@ -168,18 +184,21 @@ class ADODB2_postgres extends ADODB_DataDict
function dropIndexSQL($idxname, $tabname = NULL)
{
return array(sprintf($this->dropIndex, $this->tableName($idxname), $this->tableName($tabname)));
return array(sprintf($this->dropIndex, $this->tableName($idxname), $this->tableName($tabname)));
}
/**
* Change the definition of one column
*
* 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 definition of the new table, eg. for postgres, default ''
* @param array/ $tableoptions options for the new table see CreateTableSQL, default ''
* Postgres can't do that on its 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, e.g. for postgres, default ''
* @param array $tableoptions options for the new table {@see CreateTableSQL()}, default ''
*
* @return array with SQL strings
*/
function alterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
@@ -197,9 +216,9 @@ class ADODB2_postgres extends ADODB_DataDict
if ($not_null = preg_match('/NOT NULL/i',$v)) {
$v = preg_replace('/NOT NULL/i','',$v);
}
// 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)) {
// this next block doesn't work - there is no way that I can see to
// explicitly ask a column to be null using $flds
elseif ($set_null = preg_match('/NULL/i',$v)) {
// 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
@@ -278,7 +297,7 @@ class ADODB2_postgres extends ADODB_DataDict
* @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/ $tableoptions options for the new table see CreateTableSQL, default ''
* @param array $tableoptions options for the new table {@see CreateTableSQL}, default []
* @return array with SQL strings
*/
function dropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
@@ -305,7 +324,7 @@ class ADODB2_postgres extends ADODB_DataDict
* @param string $tabname table-name
* @param string $dropflds column-names to drop
* @param string $tableflds complete definition of the new table, eg. for postgres
* @param array/string $tableoptions options for the new table see CreateTableSQL, default ''
* @param array|string $tableoptions options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
function _recreate_copy_table($tabname, $dropflds, $tableflds, $tableoptions='')
@@ -477,11 +496,11 @@ CREATE [ UNIQUE ] INDEX index_name ON table
if (isset($idxoptions['HASH'])) {
$s .= 'USING HASH ';
}
if (isset($idxoptions[$this->upperName])) {
$s .= $idxoptions[$this->upperName];
}
if (is_array($flds)) {
$flds = implode(', ', $flds);
}
@@ -514,7 +533,7 @@ CREATE [ UNIQUE ] INDEX index_name ON table
}
return $ftype;
}
function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false)
{
global $ADODB_FETCH_MODE;
@@ -524,18 +543,18 @@ CREATE [ UNIQUE ] INDEX index_name ON table
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);
@@ -543,7 +562,7 @@ CREATE [ UNIQUE ] INDEX index_name ON table
$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);
@@ -558,7 +577,7 @@ CREATE [ UNIQUE ] INDEX index_name ON table
}
}
}
}
return $sqlResult;
}
+15
View File
@@ -30,6 +30,15 @@ class ADODB2_sapdb extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch($meta) {
case 'C': return 'VARCHAR';
case 'XL':
@@ -65,6 +74,12 @@ class ADODB2_sapdb extends ADODB_DataDict {
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
static $maxdb_type2adodb = array(
'VARCHAR' => 'C',
'CHARACTER' => 'C',
@@ -35,6 +35,16 @@ class ADODB2_sqlite extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR'; // TEXT , TEXT affinity
case 'XL':return 'LONGTEXT'; // TEXT , TEXT affinity
+17 -1
View File
@@ -35,8 +35,15 @@ class ADODB2_sybase extends ADODB_DataDict {
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
switch ($t) {
case 'INT':
case 'INTEGER': return 'I';
@@ -53,6 +60,15 @@ class ADODB2_sybase extends ADODB_DataDict {
function ActualType($meta)
{
$meta = strtoupper($meta);
/*
* Add support for custom meta types. We do this
* first, that allows us to override existing types
*/
if (isset($this->connection->customMetaTypes[$meta]))
return $this->connection->customMetaTypes[$meta]['actual'];
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR';
case 'XL':
+3
View File
@@ -504,6 +504,9 @@ class ADORecordSet_ado extends ADORecordSet {
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
if (!is_numeric($t)) return $t;
+7 -1
View File
@@ -545,8 +545,14 @@ class ADORecordSet_ado extends ADORecordSet {
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
if (!is_numeric($t)) return $t;
if (!is_numeric($t))
return $t;
switch ($t) {
case 0:
+20 -14
View File
@@ -113,7 +113,7 @@ class ADODB_db2 extends ADOConnection {
private function doDB2Connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persistent=false)
{
if (!function_exists('db2_connect')) {
ADOConnection::outp("DB2 extension not installed.");
return null;
@@ -184,6 +184,7 @@ class ADODB_db2 extends ADOConnection {
null,
$db2Options);
$this->_errorMsg = @db2_conn_errormsg();
if ($this->_connectionID && $this->connectStmt)
@@ -206,6 +207,7 @@ class ADODB_db2 extends ADOConnection {
private function unpackParameters($argDSN, $argUsername, $argPassword, $argDatabasename)
{
$connectionParameters = array('dsn'=>'',
'uid'=>'',
'pwd'=>'',
@@ -255,6 +257,7 @@ class ADODB_db2 extends ADOConnection {
$errorMessage = 'Supply uncatalogued connection parameters ';
$errorMessage.= 'in either the database or DSN arguments, ';
$errorMessage.= 'but not both';
if ($this->debug)
ADOConnection::outp($errorMessage);
return null;
@@ -279,6 +282,7 @@ class ADODB_db2 extends ADOConnection {
{
$errorMessage = 'For uncatalogued connections, provide ';
$errorMessage.= 'both UID and PWD in the connection string';
if ($this->debug)
ADOConnection::outp($errorMessage);
return null;
@@ -313,6 +317,7 @@ class ADODB_db2 extends ADOConnection {
{
$errorMessage = 'Uncatalogued connection parameters ';
$errorMessage.= 'must contain a database= argument';
if ($this->debug)
ADOConnection::outp($errorMessage);
return null;
@@ -676,16 +681,17 @@ class ADODB_db2 extends ADOConnection {
}
/**
* returns assoc array where keys are tables, and values are foreign keys
* Returns a list of Foreign Keys associated with a specific table.
*
* @param string $table
* @param string $owner [optional][discarded]
* @param bool $upper [optional][discarded]
* @param bool $associative[optional][discarded]
* @param string $table
* @param string $owner discarded
* @param bool $upper discarded
* @param bool $associative discarded
*
* @return mixed[] Array of foreign key information
* @return string[]|false An array where keys are tables, and values are foreign keys;
* false if no foreign keys could be found.
*/
public function metaForeignKeys($table, $owner = FALSE, $upper = FALSE, $asociative = FALSE )
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
global $ADODB_FETCH_MODE;
@@ -1610,12 +1616,12 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
if ($stmtid == false)
{
$this->_errorMsg = @db2_stmt_errormsg();
$this->_errorCode = @db2_stmt_error();
if ($this->debug)
ADOConnection::outp($this->_errorMsg);
$this->_errorMsg = @db2_stmt_errormsg();
$this->_errorCode = @db2_stmt_error();
if ($this->debug)
ADOConnection::outp($this->_errorMsg);
return false;
}
}
+8 -1
View File
@@ -232,8 +232,15 @@ class ADORecordSet_fbsql extends ADORecordSet{
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
$len = -1; // fbsql max_length is not accurate
switch (strtoupper($t)) {
switch ($t) {
case 'CHARACTER':
case 'CHARACTER VARYING':
case 'BLOB':
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -860,7 +860,14 @@ class ADORecordset_ibase extends ADORecordSet
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
switch ($t) {
case 'CHAR':
return 'C';
+4 -4
View File
@@ -253,12 +253,12 @@ class ADODB_informix72 extends ADOConnection {
return $false;
}
function xMetaColumns($table)
{
function xMetaColumns($table)
{
return ADOConnection::MetaColumns($table,false);
}
}
function MetaForeignKeys($table, $owner=false, $upper=false) //!Eos
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
$sql = "
select tr.tabname,updrule,delrule,
+1 -1
View File
@@ -429,7 +429,7 @@ class ADODB_mssql extends ADOConnection {
return $indexes;
}
function MetaForeignKeys($table, $owner=false, $upper=false)
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
global $ADODB_FETCH_MODE;
+34 -1
View File
@@ -151,6 +151,8 @@ class ADODB_mssqlnative extends ADOConnection {
$arrServerInfo = sqlsrv_server_info($this->_connectionID);
$ADODB_FETCH_MODE = $savem;
$arr = array();
$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
$arr['version'] = $arrServerInfo['SQLServerVersion'];//ADOConnection::_findvers($arr['description']);
return $arr;
@@ -719,7 +721,7 @@ class ADODB_mssqlnative extends ADOConnection {
return $indexes;
}
function MetaForeignKeys($table, $owner=false, $upper=false)
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
global $ADODB_FETCH_MODE;
@@ -1009,6 +1011,37 @@ class ADODB_mssqlnative extends ADOConnection {
return $metaProcedures;
}
/**
* An SQL Statement that adds a specific number of
* days or part to local datetime
*
* @param float $dayFraction
* @param string $date
*
* @return string
*/
public function offsetDate($dayFraction, $date = false)
{
if (!$date)
/*
* Use GETDATE() via systTimestamp;
*/
$date = $this->sysTimeStamp;
/*
* seconds, number of seconds, date base
*/
$dateFormat = "DATEADD(s, %s, %s)";
/*
* Adjust the offset back to seconds
*/
$fraction = $dayFraction * 24 * 3600;
return sprintf($dateFormat,$fraction,$date);
}
}
/*--------------------------------------------------------------------------------------
-932
View File
@@ -1,932 +0,0 @@
<?php
/**
* MySQL driver
*
* @deprecated
*
* This driver only supports the original non-transactional MySQL driver,
* which was 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.
*
* This file is part of ADOdb, a Database Abstraction Layer library for PHP.
*
* @package ADOdb
* @link https://adodb.org Project's web site and documentation
* @link https://github.com/ADOdb/ADOdb Source code and issue tracker
*
* The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
* and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
* any later version. This means you can use it in proprietary products.
* See the LICENSE.md file distributed with this source code for details.
* @license BSD-3-Clause
* @license LGPL-2.1-or-later
*
* @copyright 2000-2013 John Lim
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
if (! defined("_ADODB_MYSQL_LAYER")) {
define("_ADODB_MYSQL_LAYER", 1 );
class ADODB_mysql extends ADOConnection {
var $databaseType = 'mysql';
var $dataProvider = 'mysql';
var $hasInsertID = true;
var $hasAffectedRows = true;
var $metaTablesSQL = "SELECT
TABLE_NAME,
CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA=";
var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $hasLimit = true;
var $hasMoveFirst = true;
var $hasGenID = true;
var $isoDates = true; // accepts dates in ISO format
var $sysDate = 'CURDATE()';
var $sysTimeStamp = 'NOW()';
var $hasTransactions = false;
var $forceNewConnect = false;
var $poorAffectedRows = true;
var $clientFlags = 0;
var $charSet = '';
var $substr = "substring";
var $nameQuote = '`'; /// string to use to quote identifiers and names
var $compat323 = false; // true if compat with mysql 3.23
/**
* 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
}
}
}
function setCharSet($charset)
{
if (!function_exists('mysql_set_charset')) {
return false;
}
if ($this->charSet !== $charset) {
$ok = @mysql_set_charset($charset,$this->_connectionID);
if ($ok) {
$this->charSet = $charset;
return true;
}
return false;
}
return true;
}
function serverInfo()
{
$arr['description'] = ADOConnection::GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
function ifNull( $field, $ifNull )
{
return " IFNULL($field, $ifNull) "; // if MySQL
}
function metaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
{
// 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);
}
$procedures = array ();
// get index details
$likepattern = '';
if ($NamePattern) {
$likepattern = " LIKE '".$NamePattern."'";
}
$rs = $this->Execute('SHOW PROCEDURE STATUS'.$likepattern);
if (is_object($rs)) {
// parse index data into array
while ($row = $rs->FetchRow()) {
$procedures[$row[1]] = array(
'type' => 'PROCEDURE',
'catalog' => '',
'schema' => '',
'remarks' => $row[7],
);
}
}
$rs = $this->Execute('SHOW FUNCTION STATUS'.$likepattern);
if (is_object($rs)) {
// parse index data into array
while ($row = $rs->FetchRow()) {
$procedures[$row[1]] = array(
'type' => 'FUNCTION',
'catalog' => '',
'schema' => '',
'remarks' => $row[7]
);
}
}
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
return $procedures;
}
/**
* Retrieves a list of tables based on given criteria
*
* @param string $ttype Table type = 'TABLE', 'VIEW' or false=both (default)
* @param string $showSchema schema name, false = current schema (default)
* @param string $mask filters the table by name
*
* @return array list of tables
*/
function metaTables($ttype=false,$showSchema=false,$mask=false)
{
$save = $this->metaTablesSQL;
if ($showSchema && is_string($showSchema)) {
$this->metaTablesSQL .= $this->qstr($showSchema);
} else {
$this->metaTablesSQL .= "schema()";
}
if ($mask) {
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " AND table_name LIKE $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
$this->metaTablesSQL = $save;
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);
}
// get index details
$rs = $this->Execute(sprintf('SHOW INDEX FROM %s',$table));
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return $false;
}
$indexes = array ();
// parse index data into array
while ($row = $rs->FetchRow()) {
if ($primary == FALSE AND $row[2] == 'PRIMARY') {
continue;
}
if (!isset($indexes[$row[2]])) {
$indexes[$row[2]] = array(
'unique' => ($row[1] == 0),
'columns' => array()
);
}
$indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
}
// sort columns by order in the index
foreach ( array_keys ($indexes) as $index )
{
ksort ($indexes[$index]['columns']);
}
return $indexes;
}
/**
* 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 (is_resource($this->_connectionID)) {
return "'" . mysql_real_escape_string($s, $this->_connectionID) . "'";
}
if ($this->replaceQuote[0] == '\\') {
$s = str_replace(array('\\', "\0"), array('\\\\', "\\\0"), $s);
}
return "'" . str_replace("'", $this->replaceQuote, $s) . "'";
}
protected function _insertID($table = '', $column = '')
{
return ADOConnection::GetOne('SELECT LAST_INSERT_ID()');
//return mysql_insert_id($this->_connectionID);
}
function getOne($sql,$inputarr=false)
{
global $ADODB_GETONE_EOF;
if ($this->compat323 == false && strncasecmp($sql,'sele',4) == 0) {
$rs = $this->SelectLimit($sql,1,-1,$inputarr);
if ($rs) {
$rs->Close();
if ($rs->EOF) return $ADODB_GETONE_EOF;
return reset($rs->fields);
}
} else {
return ADOConnection::GetOne($sql,$inputarr);
}
return false;
}
function beginTrans()
{
if ($this->debug) ADOConnection::outp("Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver");
}
function _affectedrows()
{
return mysql_affected_rows($this->_connectionID);
}
// See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
// Reference on Last_Insert_ID on the recommended way to simulate sequences
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 if exists %s";
function createSequence($seqname='adodbseq',$startID=1)
{
if (empty($this->_genSeqSQL)) return false;
$u = strtoupper($seqname);
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
if (!$ok) return false;
return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
}
function genID($seqname='adodbseq',$startID=1)
{
// post-nuke sets hasGenID to false
if (!$this->hasGenID) return false;
$savelog = $this->_logsql;
$this->_logsql = false;
$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
$u = strtoupper($seqname);
$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 = mysql_insert_id($this->_connectionID);
$rs->Close();
} else
$this->genID = 0;
$this->_logsql = $savelog;
return $this->genID;
}
function metaDatabases()
{
$qid = mysql_list_dbs($this->_connectionID);
$arr = array();
$i = 0;
$max = mysql_num_rows($qid);
while ($i < $max) {
$db = mysql_tablename($qid,$i);
if ($db != 'mysql') $arr[] = $db;
$i += 1;
}
return $arr;
}
// Format date column in sql string given an input format that understands Y M D
function sqlDate($fmt, $col=false)
{
if (!$col) $col = $this->sysTimeStamp;
$s = 'DATE_FORMAT('.$col.",'";
$concat = false;
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
$ch = $fmt[$i];
switch($ch) {
default:
if ($ch == '\\') {
$i++;
$ch = substr($fmt,$i,1);
}
/** FALL THROUGH */
case '-':
case '/':
$s .= $ch;
break;
case 'Y':
case 'y':
$s .= '%Y';
break;
case 'M':
$s .= '%b';
break;
case 'm':
$s .= '%m';
break;
case 'D':
case 'd':
$s .= '%d';
break;
case 'Q':
case 'q':
$s .= "'),Quarter($col)";
if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
else $s .= ",('";
$concat = true;
break;
case 'H':
$s .= '%H';
break;
case 'h':
$s .= '%I';
break;
case 'i':
$s .= '%i';
break;
case 's':
$s .= '%s';
break;
case 'a':
case 'A':
$s .= '%p';
break;
case 'w':
$s .= '%w';
break;
case 'W':
$s .= '%U';
break;
case 'l':
$s .= '%W';
break;
}
}
$s.="')";
if ($concat) $s = "CONCAT($s)";
return $s;
}
// returns concatenated string
// much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
function concat()
{
$s = "";
$arr = func_get_args();
// suggestion by [email protected]
$s = implode(',',$arr);
if (strlen($s) > 0) return "CONCAT($s)";
else return '';
}
function offsetDate($dayFraction,$date=false)
{
if (!$date) $date = $this->sysDate;
$fraction = $dayFraction * 24 * 3600;
return '('. $date . ' + INTERVAL ' . $fraction.' SECOND)';
// return "from_unixtime(unix_timestamp($date)+$fraction)";
}
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!empty($this->port))
$argHostname .= ":".$this->port;
$this->_connectionID =
mysql_connect($argHostname,
$argUsername,
$argPassword,
$this->forceNewConnect,
$this->clientFlags
);
if ($this->_connectionID === false)
return false;
if ($argDatabasename)
return $this->SelectDB($argDatabasename);
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!empty($this->port)) $argHostname .= ":".$this->port;
$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;
}
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
$this->forceNewConnect = true;
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
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];
$type = $rs->fields[1];
// split type into type(length):
$fld->scale = null;
if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
$fld->type = $query_array[1];
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
$fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
} elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
$fld->type = $query_array[1];
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
} elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) {
$fld->type = $query_array[1];
$arr = explode(",",$query_array[2]);
$fld->enums = $arr;
$zlen = max(array_map("strlen",$arr)) - 2; // PHP >= 4.0.6
$fld->max_length = ($zlen > 0) ? $zlen : 1;
} else {
$fld->type = $type;
$fld->max_length = -1;
}
$fld->not_null = ($rs->fields[2] != 'YES');
$fld->primary_key = ($rs->fields[3] == 'PRI');
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
$fld->binary = (strpos($type,'blob') !== false || strpos($type,'binary') !== false);
$fld->unsigned = (strpos($type,'unsigned') !== false);
$fld->zerofill = (strpos($type,'zerofill') !== false);
if (!$fld->binary) {
$d = $rs->fields[4];
if ($d != '' && $d != 'NULL') {
$fld->has_default = true;
$fld->default_value = $d;
} else {
$fld->has_default = false;
}
}
if ($save == ADODB_FETCH_NUM) {
$retarr[] = $fld;
} else {
$retarr[strtoupper($fld->name)] = $fld;
}
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
// returns true or false
function selectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {
return @mysql_select_db($dbName,$this->_connectionID);
}
else return false;
}
// parameters use PostgreSQL convention, not MySQL
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 PHPLens Issue No: 9220
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
$rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
else
$rs = $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
return $rs;
}
// returns queryID or false
function _query($sql,$inputarr=false)
{
return mysql_query($sql,$this->_connectionID);
/*
global $ADODB_COUNTRECS;
if($ADODB_COUNTRECS)
return mysql_query($sql,$this->_connectionID);
else
return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
*/
}
/* Returns: the last error message from previous database operation */
function errorMsg()
{
if ($this->_logsql) return $this->_errorMsg;
if (empty($this->_connectionID)) $this->_errorMsg = @mysql_error();
else $this->_errorMsg = @mysql_error($this->_connectionID);
return $this->_errorMsg;
}
/* Returns: the last error number from previous database operation */
function errorNo()
{
if ($this->_logsql) return $this->_errorCode;
if (empty($this->_connectionID)) return @mysql_errno();
else return @mysql_errno($this->_connectionID);
}
// returns true or false
function _close()
{
@mysql_close($this->_connectionID);
$this->charSet = '';
$this->_connectionID = false;
}
/*
* Maximum size of C field
*/
function charMax()
{
return 255;
}
/*
* Maximum size of X field
*/
function textMax()
{
return 4294967295;
}
// "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
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;
if ( !empty($owner) ) {
$table = "$owner.$table";
}
$a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
if ($associative) {
$create_sql = isset($a_create_table["Create Table"]) ? $a_create_table["Create Table"] : $a_create_table["Create View"];
} else {
$create_sql = $a_create_table[1];
}
$matches = array();
if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
$foreign_keys = array();
$num_keys = count($matches[0]);
for ( $i = 0; $i < $num_keys; $i ++ ) {
$my_field = explode('`, `', $matches[1][$i]);
$ref_table = $matches[2][$i];
$ref_field = explode('`, `', $matches[3][$i]);
if ( $upper ) {
$ref_table = strtoupper($ref_table);
}
// see https://sourceforge.net/p/adodb/bugs/100/
if (!isset($foreign_keys[$ref_table])) {
$foreign_keys[$ref_table] = array();
}
$num_fields = count($my_field);
for ( $j = 0; $j < $num_fields; $j ++ ) {
if ( $associative ) {
$foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
} else {
$foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
}
}
}
return $foreign_keys;
}
}
/*--------------------------------------------------------------------------------------
Class Name: Recordset
--------------------------------------------------------------------------------------*/
class ADORecordSet_mysql extends ADORecordSet{
var $databaseType = "mysql";
var $canSeek = true;
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default:
$this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
parent::__construct($queryID);
}
function _initrs()
{
//GLOBAL $ADODB_COUNTRECS;
// $this->_numOfRows = ($ADODB_COUNTRECS) ? @mysql_num_rows($this->_queryID):-1;
$this->_numOfRows = @mysql_num_rows($this->_queryID);
$this->_numOfFields = @mysql_num_fields($this->_queryID);
}
function fetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$o = @mysql_fetch_field($this->_queryID, $fieldOffset);
$f = @mysql_field_flags($this->_queryID,$fieldOffset);
if ($o) $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich#att.com)
//$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
if ($o) $o->binary = (strpos($f,'binary')!== false);
}
else { /* The $fieldOffset argument is not provided thus its -1 */
$o = @mysql_fetch_field($this->_queryID);
//if ($o) $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com)
$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
}
return $o;
}
function getRowAssoc($upper = ADODB_ASSOC_CASE)
{
if ($this->fetchMode == MYSQL_ASSOC && $upper == ADODB_ASSOC_CASE_LOWER) {
$row = $this->fields;
}
else {
$row = ADORecordSet::GetRowAssoc($upper);
}
return $row;
}
/* Use associative array to get fields array */
function fields($colname)
{
// added @ by "Michael William Miller" <[email protected]>
if ($this->fetchMode != MYSQL_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)]];
}
function _seek($row)
{
if ($this->_numOfRows == 0) return false;
return @mysql_data_seek($this->_queryID,$row);
}
function moveNext()
{
if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
$this->_updatefields();
$this->_currentRow += 1;
return true;
}
if (!$this->EOF) {
$this->_currentRow += 1;
$this->EOF = true;
}
return false;
}
function _fetch()
{
$this->fields = @mysql_fetch_array($this->_queryID,$this->fetchMode);
$this->_updatefields();
return is_array($this->fields);
}
function _close() {
@mysql_free_result($this->_queryID);
$this->_queryID = false;
}
function metaType($t,$len=-1,$fieldobj=false)
{
if (is_object($t)) {
$fieldobj = $t;
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
case 'TINYBLOB':
case 'TINYTEXT':
case 'ENUM':
case 'SET':
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
case 'LONGTEXT':
case 'MEDIUMTEXT':
return 'X';
// php_mysql extension always returns 'blob' even if 'text'
// so we have to check whether binary...
case 'IMAGE':
case 'LONGBLOB':
case 'BLOB':
case 'MEDIUMBLOB':
case 'BINARY':
return !empty($fieldobj->binary) ? 'B' : 'X';
case 'YEAR':
case 'DATE': return 'D';
case 'TIME':
case 'DATETIME':
case 'TIMESTAMP': return 'T';
case 'INT':
case 'INTEGER':
case 'BIGINT':
case 'TINYINT':
case 'MEDIUMINT':
case 'SMALLINT':
if (!empty($fieldobj->primary_key)) return 'R';
else return 'I';
default: return ADODB_DEFAULT_METATYPE;
}
}
}
/**
* Class ADORecordSet_ext_mysql
*/
class ADORecordSet_ext_mysql extends ADORecordSet_mysql {
function moveNext()
{
return @adodb_movenext($this);
}
}
}
+277 -52
View File
@@ -75,12 +75,17 @@ class ADODB_mysqli extends ADOConnection {
var $ssl_capath = null;
var $ssl_cipher = null;
/** @var mysqli Identifier for the native database connection */
var $_connectionID = false;
/**
* Tells the insert_id method how to obtain the last value, depending on whether
* we are using a stored procedure or not
*/
private $usePreparedStatement = false;
private $useLastInsertStatement = false;
private $usingBoundVariables = false;
private $statementAffectedRows = -1;
/**
* @var bool True if the last executed statement is a SELECT {@see _query()}
@@ -123,13 +128,12 @@ class ADODB_mysqli extends ADOConnection {
/**
* Adds a parameter to the connection string.
*
* Parameter must be one of the the constants listed in mysqli_options().
* Parameter must be one of the constants listed in mysqli_options().
* @see https://www.php.net/manual/en/mysqli.options.php
*
* @param int $parameter The parameter to set
* @param string $value The value of the parameter
* @param int $parameter The parameter to set
* @param string $value The value of the parameter
*
* @example, for mssqlnative driver ('CharacterSet','UTF-8')
* @return bool
*/
public function setConnectionParameter($parameter, $value) {
@@ -137,8 +141,7 @@ class ADODB_mysqli extends ADOConnection {
$this->outp_throw("Invalid connection parameter '$parameter'", __METHOD__);
return false;
}
$this->connectionParameters[$parameter] = $value;
return true;
return parent::setConnectionParameter($parameter, $value);
}
/**
@@ -184,13 +187,15 @@ class ADODB_mysqli extends ADOConnection {
}
// Now merge in the standard connection parameters setting
foreach ($this->connectionParameters as $parameter => $value) {
// Make sure parameter is numeric before calling mysqli_options()
// that to avoid Warning (or TypeError exception on PHP 8).
if (!is_numeric($parameter)
|| !mysqli_options($this->_connectionID, $parameter, $value)
) {
$this->outp_throw("Invalid connection parameter '$parameter'", __METHOD__);
foreach ($this->connectionParameters as $options) {
foreach ($options as $parameter => $value) {
// Make sure parameter is numeric before calling mysqli_options()
// to avoid Warning (or TypeError exception on PHP 8).
if (!is_numeric($parameter)
|| !mysqli_options($this->_connectionID, $parameter, $value)
) {
$this->outp_throw("Invalid connection parameter '$parameter'", __METHOD__);
}
}
}
@@ -202,9 +207,12 @@ class ADODB_mysqli extends ADOConnection {
// SSL Connections for MySQLI
if ($this->ssl_key || $this->ssl_cert || $this->ssl_ca || $this->ssl_capath || $this->ssl_cipher) {
mysqli_ssl_set($this->_connectionID, $this->ssl_key, $this->ssl_cert, $this->ssl_ca, $this->ssl_capath, $this->ssl_cipher);
$this->socket = MYSQLI_CLIENT_SSL;
$this->clientFlags = MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT;
}
#if (!empty($this->port)) $argHostname .= ":".$this->port;
/** @noinspection PhpCastIsUnnecessaryInspection */
$ok = @mysqli_real_connect($this->_connectionID,
$argHostname,
$argUsername,
@@ -252,15 +260,15 @@ class ADODB_mysqli extends ADOConnection {
* @param string|null $argHostname The host to connect to.
* @param string|null $argUsername The username to connect as.
* @param string|null $argPassword The password to connect with.
* @param string|null $argDatabasename The name of the database to start in when connected.
* @param string|null $argDatabaseName The name of the database to start in when connected.
*
* @return bool|null True if connected successfully, false if connection failed, or null if the mysqli extension
* isn't currently loaded.
*/
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName)
{
$this->forceNewConnect = true;
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName);
}
/**
@@ -376,17 +384,17 @@ class ADODB_mysqli extends ADOConnection {
*
* @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:rowlock
*
* @param string $tables The table(s) to lock rows for.
* @param string $table The table(s) to lock rows for.
* @param string $where (Optional) The WHERE clause to use to determine which rows to lock.
* @param string $col (Optional) The columns to select.
*
* @return bool True if the locking SQL statement executed successfully, otherwise false.
*/
function RowLock($tables, $where = '', $col = '1 as adodbignore')
function RowLock($table, $where = '', $col = '1 as adodbignore')
{
if ($this->transCnt==0) $this->beginTrans();
if ($where) $where = ' where '.$where;
$rs = $this->execute("select $col from $tables $where for update");
$rs = $this->execute("select $col from $table $where for update");
return !empty($rs);
}
@@ -457,10 +465,17 @@ class ADODB_mysqli extends ADOConnection {
// the rowcount, but ADOdb does not do that.
return false;
}
$result = @mysqli_affected_rows($this->_connectionID);
if ($result == -1) {
if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->errorMsg());
else if ($this->statementAffectedRows >= 0)
{
$result = $this->statementAffectedRows;
$this->statementAffectedRows = -1;
}
else
{
$result = @mysqli_affected_rows($this->_connectionID);
if ($result == -1) {
if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->errorMsg());
}
}
return $result;
}
@@ -566,7 +581,6 @@ class ADODB_mysqli extends ADOConnection {
// save old fetch mode
global $ADODB_FETCH_MODE;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== FALSE) {
@@ -574,7 +588,7 @@ class ADODB_mysqli extends ADOConnection {
}
// get index details
$rs = $this->execute(sprintf('SHOW INDEXES FROM %s',$table));
$rs = $this->Execute(sprintf('SHOW INDEXES FROM `%s`',$table));
// restore fetchmode
if (isset($savem)) {
@@ -583,7 +597,7 @@ class ADODB_mysqli extends ADOConnection {
$ADODB_FETCH_MODE = $save;
if (!is_object($rs)) {
return $false;
return false;
}
$indexes = array ();
@@ -621,7 +635,7 @@ class ADODB_mysqli extends ADOConnection {
* @param string $fmt The date format to use.
* @param string|bool $col (Optional) The table column to date format, or if false, use NOW().
*
* @return bool|string The SQL DATE_FORMAT() string, or false if the provided date format was empty.
* @return string The SQL DATE_FORMAT() string, or false if the provided date format was empty.
*/
function SQLDate($fmt, $col = false)
{
@@ -740,13 +754,13 @@ class ADODB_mysqli extends ADOConnection {
/**
* Returns information about stored procedures and stored functions.
*
* @param string|bool $NamePattern (Optional) Only look for procedures/functions with a name matching this pattern.
* @param string|bool $procedureNamePattern (Optional) Only look for procedures/functions with a name matching this pattern.
* @param null $catalog (Optional) Unused.
* @param null $schemaPattern (Optional) Unused.
*
* @return array
*/
function MetaProcedures($NamePattern = false, $catalog = null, $schemaPattern = null)
function MetaProcedures($procedureNamePattern = false, $catalog = null, $schemaPattern = null)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
@@ -763,8 +777,8 @@ class ADODB_mysqli extends ADOConnection {
// get index details
$likepattern = '';
if ($NamePattern) {
$likepattern = " LIKE '".$NamePattern."'";
if ($procedureNamePattern) {
$likepattern = " LIKE '".$procedureNamePattern."'";
}
$rs = $this->execute('SHOW PROCEDURE STATUS'.$likepattern);
if (is_object($rs)) {
@@ -840,9 +854,8 @@ class ADODB_mysqli extends ADOConnection {
*
* @return array|bool An array of foreign keys, or false no foreign keys could be found.
*/
function MetaForeignKeys($table, $owner = false, $upper = false, $associative = false)
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
global $ADODB_FETCH_MODE;
if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC
@@ -856,7 +869,7 @@ class ADODB_mysqli extends ADOConnection {
$table = "$owner.$table";
}
$a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
$a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE `%s`', $table));
$this->setFetchMode($savem);
@@ -935,7 +948,6 @@ class ADODB_mysqli extends ADOConnection {
while (!$rs->EOF) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$type = $rs->fields[1];
/*
* Type from information_schema returns
@@ -1027,7 +1039,7 @@ class ADODB_mysqli extends ADOConnection {
* @param int $nrows (Optional) The limit for the number of records you want returned. By default, all results.
* @param int $offset (Optional) The offset to use when selecting the results. By default, no offset.
* @param array|bool $inputarr (Optional) Any parameter values required by the SQL statement, or false if none.
* @param int $secs (Optional) If greater than 0, perform a cached execute. By default, normal execution.
* @param int $secs2cache (Optional) If greater than 0, perform a cached execute. By default, normal execution.
*
* @return ADORecordSet|false The query results, or false if the query failed to execute.
*/
@@ -1035,15 +1047,15 @@ class ADODB_mysqli extends ADOConnection {
$nrows = -1,
$offset = -1,
$inputarr = false,
$secs = 0)
$secs2cache = 0)
{
$nrows = (int) $nrows;
$offset = (int) $offset;
$offsetStr = ($offset >= 0) ? "$offset," : '';
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
$rs = $this->cacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr );
if ($secs2cache)
$rs = $this->cacheExecute($secs2cache, $sql . " LIMIT $offsetStr$nrows" , $inputarr );
else
$rs = $this->execute($sql . " LIMIT $offsetStr$nrows" , $inputarr );
@@ -1052,6 +1064,7 @@ class ADODB_mysqli extends ADOConnection {
/**
* Prepares an SQL statement and returns a handle to use.
* This is not used by bound parameters anymore
*
* @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:prepare
* @todo update this function to handle prepared statements correctly
@@ -1080,13 +1093,106 @@ class ADODB_mysqli extends ADOConnection {
}
/**
* Return the query id.
* Execute SQL
*
* @param string|array $sql
* @param array $inputarr
* @param string $sql SQL statement to execute, or possibly an array
* holding prepared statement ($sql[0] will hold sql text)
* @param array|bool $inputarr holds the input data to bind to.
* Null elements will be set to null.
*
* @return bool|mysqli_result
* @return ADORecordSet|bool
*/
public function execute($sql, $inputarr = false)
{
if ($this->fnExecute) {
$fn = $this->fnExecute;
$ret = $fn($this, $sql, $inputarr);
if (isset($ret)) {
return $ret;
}
}
if ($inputarr === false || $inputarr === []) {
return $this->_execute($sql);
}
if (!is_array($inputarr)) {
$inputarr = array($inputarr);
}
if (!is_array($sql)) {
// Check if we are bulkbinding. If so, $inputarr is a 2d array,
// and we make a gross assumption that all rows have the same number
// of columns of the same type, and use the elements of the first row
// to determine the MySQL bind param types.
if (is_array($inputarr[0])) {
if (!$this->bulkBind) {
$this->outp_throw(
"2D Array of values sent to execute and 'ADOdb_mysqli::bulkBind' not set",
'Execute'
);
return false;
}
$bulkTypeArray = [];
foreach ($inputarr as $v) {
if (is_string($this->bulkBind)) {
$typeArray = array_merge((array)$this->bulkBind, $v);
} else {
$typeArray = $this->getBindParamWithType($v);
}
$bulkTypeArray[] = $typeArray;
}
$this->bulkBind = false;
$ret = $this->_execute($sql, $bulkTypeArray);
} else {
$typeArray = $this->getBindParamWithType($inputarr);
$ret = $this->_execute($sql, $typeArray);
}
} else {
$ret = $this->_execute($sql, $inputarr);
}
return $ret;
}
/**
* Inserts the bind param type string at the front of the parameter array.
*
* @see https://www.php.net/manual/en/mysqli-stmt.bind-param.php
*
* @param array $inputArr
* @return array
*/
private function getBindParamWithType($inputArr): array
{
$typeString = '';
foreach ($inputArr as $v) {
if (is_integer($v) || is_bool($v)) {
$typeString .= 'i';
} elseif (is_float($v)) {
$typeString .= 'd';
} elseif (is_object($v)) {
// Assume a blob
$typeString .= 'b';
} else {
$typeString .= 's';
}
}
// Place the field type list at the front of the parameter array.
// This is the mysql specific format
array_unshift($inputArr, $typeString);
return $inputArr;
}
/**
* Return the query id.
*
* @param string|array $sql
* @param array $inputarr
*
* @return bool|mysqli_result
*/
function _query($sql, $inputarr)
{
global $ADODB_COUNTRECS;
@@ -1104,7 +1210,7 @@ class ADODB_mysqli extends ADOConnection {
$stmt = $sql[1];
$a = '';
foreach($inputarr as $k => $v) {
foreach($inputarr as $v) {
if (is_string($v)) $a .= 's';
else if (is_integer($v)) $a .= 'i';
else $a .= 'd';
@@ -1118,8 +1224,105 @@ class ADODB_mysqli extends ADOConnection {
$fnarr = array_merge( array($stmt,$a) , $inputarr);
call_user_func_array('mysqli_stmt_bind_param',$fnarr);
$ret = mysqli_stmt_execute($stmt);
return $ret;
return mysqli_stmt_execute($stmt);
}
else if (is_string($sql) && is_array($inputarr))
{
/*
* This is support for true prepared queries
* with bound parameters
*
* set prepared statement flags
*/
$this->usePreparedStatement = true;
$this->usingBoundVariables = true;
$bulkBindArray = array();
if (is_array($inputarr[0]))
{
$bulkBindArray = $inputarr;
$inputArrayCount = count($inputarr[0]) - 1;
}
else
{
$bulkBindArray[] = $inputarr;
$inputArrayCount = count($inputarr) - 1;
}
/*
* Prepare the statement with the placeholders,
* prepare will fail if the statement is invalid
* so we trap and error if necessary. Note that we
* are calling MySQL prepare here, not ADOdb
*/
$stmt = $this->_connectionID->prepare($sql);
if ($stmt === false)
{
$this->outp_throw(
"SQL Statement failed on preparation: " . htmlspecialchars($sql) . "'",
'Execute'
);
return false;
}
/*
* Make sure the number of parameters provided in the input
* array matches what the query expects. We must discount
* the first parameter which contains the data types in
* our inbound parameters
*/
$nparams = $stmt->param_count;
if ($nparams != $inputArrayCount)
{
$this->outp_throw(
"Input array has " . $inputArrayCount .
" params, does not match query: '" . htmlspecialchars($sql) . "'",
'Execute'
);
return false;
}
foreach ($bulkBindArray as $inputarr)
{
/*
* Must pass references into call_user_func_array
*/
$paramsByReference = array();
foreach($inputarr as $key => $value) {
/** @noinspection PhpArrayAccessCanBeReplacedWithForeachValueInspection */
$paramsByReference[$key] = &$inputarr[$key];
}
/*
* Bind the params
*/
call_user_func_array(array($stmt, 'bind_param'), $paramsByReference);
/*
* Execute
*/
$ret = mysqli_stmt_execute($stmt);
/*
* Did we throw an error?
*/
if ($ret == false)
return false;
}
// Tells affected_rows to be compliant
$this->isSelectStatement = $stmt->affected_rows == -1;
if (!$this->isSelectStatement) {
$this->statementAffectedRows = $stmt->affected_rows;
return true;
}
// Turn the statement into a result set and return it
return $stmt->get_result();
}
else
{
@@ -1144,7 +1347,7 @@ class ADODB_mysqli extends ADOConnection {
$rs = mysqli_multi_query($this->_connectionID, $sql.';');
if ($rs) {
$rs = ($ADODB_COUNTRECS) ? @mysqli_store_result( $this->_connectionID ) : @mysqli_use_result( $this->_connectionID );
return $rs ? $rs : true; // mysqli_more_results( $this->_connectionID )
return $rs ?: true; // mysqli_more_results( $this->_connectionID )
}
} else {
$rs = mysqli_query($this->_connectionID, $sql, $ADODB_COUNTRECS ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT);
@@ -1262,6 +1465,12 @@ class ADORecordSet_mysqli extends ADORecordSet{
var $databaseType = "mysqli";
var $canSeek = true;
/** @var ADODB_mysqli The parent connection */
var $connection = false;
/** @var mysqli_result result link identifier */
var $_queryID;
function __construct($queryID, $mode = false)
{
if ($mode === false) {
@@ -1368,8 +1577,7 @@ class ADORecordSet_mysqli extends ADORecordSet{
if ($this->fetchMode == MYSQLI_ASSOC && $upper == ADODB_ASSOC_CASE_LOWER) {
return $this->fields;
}
$row = ADORecordSet::getRowAssoc($upper);
return $row;
return ADORecordSet::getRowAssoc($upper);
}
/**
@@ -1524,6 +1732,7 @@ class ADORecordSet_mysqli extends ADORecordSet{
12 = MYSQLI_TYPE_DATETIME
13 = MYSQLI_TYPE_YEAR
14 = MYSQLI_TYPE_NEWDATE
245 = MYSQLI_TYPE_JSON
247 = MYSQLI_TYPE_ENUM
248 = MYSQLI_TYPE_SET
249 = MYSQLI_TYPE_TINY_BLOB
@@ -1544,7 +1753,7 @@ class ADORecordSet_mysqli extends ADORecordSet{
*
* @return string The MetaType
*/
function MetaType($t, $len = -1, $fieldobj = false)
function metaType($t, $len = -1, $fieldobj = false)
{
if (is_object($t)) {
$fieldobj = $t;
@@ -1552,8 +1761,16 @@ class ADORecordSet_mysqli extends ADORecordSet{
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
/*
* Add support for custom actual types. We do this
* first, that allows us to override existing types
*/
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
switch ($t) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
@@ -1631,6 +1848,8 @@ class ADORecordSet_mysqli extends ADORecordSet{
case 'DEC':
case 'FIXED':
default:
//if (!is_numeric($t)) echo "<p>--- Error in type matching $t -----</p>";
return 'N';
}
@@ -1661,8 +1880,14 @@ class ADORecordSet_array_mysqli extends ADORecordSet_array
$len = $fieldobj->max_length;
}
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
$len = -1; // mysql max_length is not accurate
switch (strtoupper($t)) {
switch ($t) {
case 'STRING':
case 'CHAR':
case 'VARCHAR':
-124
View File
@@ -1,124 +0,0 @@
<?php
/**
* Portable MySQL driver
*
* @deprecated
*
* Extends the deprecated mysql driver, and was originally designed to be a
* portable driver in the same manner as oci8po and mssqlpo. Its functionality
* is exactly duplicated in the mysqlt driver, which is itself deprecated.
* This driver will be removed in ADOdb version 6.0.0.
*
* This file is part of ADOdb, a Database Abstraction Layer library for PHP.
*
* @package ADOdb
* @link https://adodb.org Project's web site and documentation
* @link https://github.com/ADOdb/ADOdb Source code and issue tracker
*
* The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
* and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
* any later version. This means you can use it in proprietary products.
* See the LICENSE.md file distributed with this source code for details.
* @license BSD-3-Clause
* @license LGPL-2.1-or-later
*
* @copyright 2000-2013 John Lim
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-mysql.inc.php");
class ADODB_mysqlt extends ADODB_mysql {
var $databaseType = 'mysqlt';
var $ansiOuter = true; // for Version 3.23.17 or later
var $hasTransactions = true;
var $autoRollback = true; // apparently mysql does not autorollback properly
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->Execute('SET AUTOCOMMIT=0');
$this->Execute('BEGIN');
return true;
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$this->Execute('COMMIT');
$this->Execute('SET AUTOCOMMIT=1');
return true;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$this->Execute('ROLLBACK');
$this->Execute('SET AUTOCOMMIT=1');
return true;
}
function RowLock($tables,$where='',$col='1 as adodbignore')
{
if ($this->transCnt==0) $this->BeginTrans();
if ($where) $where = ' where '.$where;
$rs = $this->Execute("select $col from $tables $where for update");
return !empty($rs);
}
}
class ADORecordSet_mysqlt extends ADORecordSet_mysql{
var $databaseType = "mysqlt";
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default: $this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
parent::__construct($queryID);
}
function MoveNext()
{
if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
$this->_currentRow += 1;
return true;
}
if (!$this->EOF) {
$this->_currentRow += 1;
$this->EOF = true;
}
return false;
}
}
class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
function MoveNext()
{
return adodb_movenext($this);
}
}
-141
View File
@@ -1,141 +0,0 @@
<?php
/**
* MySQL driver in transactional mode
*
* @deprecated
*
* This driver only supports the original MySQL driver in transactional mode. It
* 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
*
* This file is part of ADOdb, a Database Abstraction Layer library for PHP.
*
* @package ADOdb
* @link https://adodb.org Project's web site and documentation
* @link https://github.com/ADOdb/ADOdb Source code and issue tracker
*
* The ADOdb Library is dual-licensed, released under both the BSD 3-Clause
* and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option,
* any later version. This means you can use it in proprietary products.
* See the LICENSE.md file distributed with this source code for details.
* @license BSD-3-Clause
* @license LGPL-2.1-or-later
*
* @copyright 2000-2013 John Lim
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
include_once(ADODB_DIR."/drivers/adodb-mysql.inc.php");
class ADODB_mysqlt extends ADODB_mysql {
var $databaseType = 'mysqlt';
var $ansiOuter = true; // for Version 3.23.17 or later
var $hasTransactions = true;
var $autoRollback = true; // apparently mysql does not autorollback properly
/* set transaction mode
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
*/
function SetTransactionMode( $transaction_mode )
{
$this->_transmode = $transaction_mode;
if (empty($transaction_mode)) {
$this->Execute('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ');
return;
}
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
}
function BeginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->Execute('SET AUTOCOMMIT=0');
$this->Execute('BEGIN');
return true;
}
function CommitTrans($ok=true)
{
if ($this->transOff) return true;
if (!$ok) return $this->RollbackTrans();
if ($this->transCnt) $this->transCnt -= 1;
$ok = $this->Execute('COMMIT');
$this->Execute('SET AUTOCOMMIT=1');
return $ok ? true : false;
}
function RollbackTrans()
{
if ($this->transOff) return true;
if ($this->transCnt) $this->transCnt -= 1;
$ok = $this->Execute('ROLLBACK');
$this->Execute('SET AUTOCOMMIT=1');
return $ok ? true : false;
}
function RowLock($tables,$where='',$col='1 as adodbignore')
{
if ($this->transCnt==0) $this->BeginTrans();
if ($where) $where = ' where '.$where;
$rs = $this->Execute("select $col from $tables $where for update");
return !empty($rs);
}
}
class ADORecordSet_mysqlt extends ADORecordSet_mysql{
var $databaseType = "mysqlt";
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
}
switch ($mode)
{
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
case ADODB_FETCH_DEFAULT:
case ADODB_FETCH_BOTH:
default: $this->fetchMode = MYSQL_BOTH; break;
}
$this->adodbFetchMode = $mode;
parent::__construct($queryID);
}
function MoveNext()
{
if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
$this->_currentRow += 1;
return true;
}
if (!$this->EOF) {
$this->_currentRow += 1;
$this->EOF = true;
}
return false;
}
}
class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
function MoveNext()
{
return adodb_movenext($this);
}
}
+45 -15
View File
@@ -791,6 +791,11 @@ END;
$nrows += $offset;
}
$sql = "select * from (".$sql.") where rownum <= :adodb_offset";
// If non-bound statement, $inputarr is false
if (!$inputarr) {
$inputarr = array();
}
$inputarr['adodb_offset'] = $nrows;
$nrows = -1;
}
@@ -973,9 +978,12 @@ END;
/**
* Execute SQL
*
* @param sql SQL statement to execute, or possibly an array holding prepared statement ($sql[0] will hold sql text)
* @param [inputarr] holds the input data to bind to. Null elements will be set to null.
* @return RecordSet or false
* @param string|array $sql SQL statement to execute, or possibly an array holding
* prepared statement ($sql[0] will hold sql text).
* @param array|false $inputarr holds the input data to bind to.
* Null elements will be set to null.
*
* @return ADORecordSet|false
*/
function Execute($sql,$inputarr=false)
{
@@ -1094,6 +1102,22 @@ END;
return array($sql,$stmt,0,$BINDNUM);
}
function releaseStatement(&$stmt)
{
if (is_array($stmt)
&& isset($stmt[1])
&& is_resource($stmt[1])
&& oci_free_statement($stmt[1])
) {
// Clearing the resource to avoid it being of type Unknown
$stmt[1] = null;
return true;
}
// Not a valid prepared statement
return false;
}
/*
Call an oracle stored procedure and returns a cursor variable as a recordset.
Concept by Robert Tuttle [email protected]
@@ -1241,12 +1265,12 @@ END;
* $db->Parameter($stmt,$group,'group');
* $db->Execute($stmt);
*
* @param $stmt Statement returned by Prepare() or PrepareSP().
* @param $stmt Statement returned by {@see Prepare()} or {@see PrepareSP()}.
* @param $var PHP variable to bind to
* @param $name Name of stored procedure variable name to bind to.
* @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
* @param [$maxLen] Holds an maximum length of the variable.
* @param [$type] The data type of $var. Legal values depend on driver.
* @param bool $isOutput Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
* @param int $maxLen Holds an maximum length of the variable.
* @param mixed $type The data type of $var. Legal values depend on driver.
*
* @link http://php.net/oci_bind_by_name
*/
@@ -1484,16 +1508,17 @@ SELECT /*+ RULE */ distinct b.column_name
}
/**
* returns assoc array where keys are tables, and values are foreign keys
* Returns a list of Foreign Keys associated with a specific table.
*
* @param str $table
* @param str $owner [optional][default=NULL]
* @param bool $upper [optional][discarded]
* @return mixed[] Array of foreign key information
* @param string $table
* @param string $owner
* @param bool $upper discarded
* @param bool $associative discarded
*
* @link http://gis.mit.edu/classes/11.521/sqlnotes/referential_integrity.html
* @return string[]|false An array where keys are tables, and values are foreign keys;
* false if no foreign keys could be found.
*/
function MetaForeignKeys($table, $owner=false, $upper=false)
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
global $ADODB_FETCH_MODE;
@@ -1810,7 +1835,12 @@ class ADORecordset_oci8 extends ADORecordSet {
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
switch ($t) {
case 'VARCHAR':
case 'VARCHAR2':
case 'CHAR':
+1 -2
View File
@@ -81,8 +81,7 @@ class ADODB_odbc_mssql extends ADODB_odbc {
return $this->GetOne($this->identitySQL);
}
function MetaForeignKeys($table, $owner=false, $upper=false)
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
global $ADODB_FETCH_MODE;
+1 -1
View File
@@ -393,7 +393,7 @@ class ADODB_odbtp extends ADOConnection{
return $arr2;
}
function MetaForeignKeys($table, $owner='', $upper=false)
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
global $ADODB_FETCH_MODE;
+27 -6
View File
@@ -82,7 +82,6 @@ class ADODB_pdo extends ADOConnection {
var $_errormsg = false;
var $_errorno = false;
var $dsnType = '';
var $stmt = false;
var $_driver;
@@ -238,6 +237,26 @@ class ADODB_pdo extends ADOConnection {
return call_user_func_array('parent::Concat', $args);
}
/**
* Triggers a driver-specific request for a bind parameter
*
* @param string $name
* @param string $type
*
* @return string
*/
public function param($name,$type='C') {
$args = func_get_args();
if(method_exists($this->_driver, 'param')) {
// Return the driver specific entry, that mimics the native driver
return call_user_func_array(array($this->_driver, 'param'), $args);
}
// No driver specific method defined, use mysql format '?'
return call_user_func_array('parent::param', $args);
}
// returns true or false
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
@@ -294,18 +313,19 @@ class ADODB_pdo extends ADOConnection {
}
/**
* Returns a list of Foreign Keys for a specified table.
* Returns a list of Foreign Keys associated with a specific table.
*
* @param string $table
* @param bool $owner (optional) not used in this driver
* @param string $owner (optional) not used in this driver
* @param bool $upper
* @param bool $associative
*
* @return string[] where keys are tables, and values are foreign keys
* @return string[]|false An array where keys are tables, and values are foreign keys;
* false if no foreign keys could be found.
*/
public function metaForeignKeys($table, $owner=false, $upper=false,$associative=false) {
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false) {
if (method_exists($this->_driver,'metaForeignKeys'))
return $this->_driver->metaForeignKeys($table,$owner,$upper,$associative);
return $this->_driver->metaForeignKeys($table, $owner, $upper, $associative);
}
/**
@@ -565,6 +585,7 @@ class ADODB_pdo extends ADOConnection {
$this->_driver->debug = $this->debug;
}
if ($inputarr) {
/*
* inputarr must be numeric
*/
+27 -14
View File
@@ -75,15 +75,15 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
$retarr = array();
while (!$rs->EOF) { //print_r($rs->fields);
$fld = new ADOFieldObject();
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
$fld->name = $rs->fields[0];
$fld->type = $rs->fields[1];
$fld->max_length = $rs->fields[2];
$fld->scale = $rs->fields[3];
if ($rs->fields[1] == 'NUMBER' && $rs->fields[3] == 0) {
$fld->type ='INT';
$fld->max_length = $rs->fields[4];
}
$fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
$fld->max_length = $rs->fields[4];
}
$fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
$fld->binary = (strpos($fld->type,'BLOB') !== false);
$fld->default_value = $rs->fields[6];
@@ -98,12 +98,25 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
return $retarr;
}
/**
* @param bool $auto_commit
* @return void
*/
function SetAutoCommit($auto_commit)
{
$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT, $auto_commit);
}
/**
* @param bool $auto_commit
* @return void
*/
function SetAutoCommit($auto_commit)
{
$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT, $auto_commit);
}
/**
* Returns a driver-specific format for a bind parameter
*
* @param string $name
* @param string $type (ignored in driver)
*
* @return string
*/
public function param($name,$type='C')
{
return sprintf(':%s', $name);
}
}
+42 -19
View File
@@ -21,11 +21,11 @@
class ADODB_pdo_pgsql extends ADODB_pdo {
var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
union
select viewname,'V' from pg_views where viewname not like 'pg\_%'";
var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
union
select viewname,'V' from pg_views where viewname not like 'pg\_%'";
//"select tablename from pg_tables where tablename not like 'pg_%' order by 1";
var $isoDates = true; // accepts dates in ISO format
var $sysDate = "CURRENT_DATE";
@@ -34,15 +34,15 @@ class ADODB_pdo_pgsql extends ADODB_pdo {
var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
FROM pg_class c, pg_attribute a,pg_type t
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
// used when schema defined
var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
and c.relnamespace=n.oid and n.nspname='%s'
and a.attname not like '....%%' AND a.attnum > 0
AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
and c.relnamespace=n.oid and n.nspname='%s'
and a.attname not like '....%%' AND a.attnum > 0
AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
// get primary key etc -- from Freek Dijkstra
var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
@@ -97,23 +97,27 @@ WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
{
$info = $this->ServerInfo();
if ($info['version'] >= 7.3) {
$this->metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and schemaname not in ( 'pg_catalog','information_schema')
union
select viewname,'V' from pg_views where viewname not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema') ";
$this->metaTablesSQL = "
select tablename,'T' from pg_tables
where tablename not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema')
union
select viewname,'V' from pg_views
where viewname not like 'pg\_%' and schemaname not in ( 'pg_catalog','information_schema')";
}
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(strtolower($mask));
if ($info['version']>=7.3)
$this->metaTablesSQL = "
select tablename,'T' from pg_tables where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema')
union
select viewname,'V' from pg_views where viewname like $mask and schemaname not in ( 'pg_catalog','information_schema') ";
select tablename,'T' from pg_tables
where tablename like $mask and schemaname not in ( 'pg_catalog','information_schema')
union
select viewname,'V' from pg_views
where viewname like $mask and schemaname not in ( 'pg_catalog','information_schema')";
else
$this->metaTablesSQL = "
select tablename,'T' from pg_tables where tablename like $mask
union
union
select viewname,'V' from pg_views where viewname like $mask";
}
$ret = ADOConnection::MetaTables($ttype,$showSchema);
@@ -297,4 +301,23 @@ select viewname,'V' from pg_views where viewname like $mask";
if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode;
$this->_connectionID->query("SET TRANSACTION ".$transaction_mode);
}
/**
* Returns a driver-specific format for a bind parameter
*
* Unlike the native driver, we use :name parameters
* instead of offsets
*
* @param string $name
* @param string $type (ignored in driver)
*
* @return string
*/
public function param($name,$type='C') {
if (!$name) {
return '';
}
return sprintf(':%s', $name);
}
}
+56 -35
View File
@@ -34,7 +34,7 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
var $_genSeq2SQL = 'INSERT INTO %s VALUES(%s)';
var $_dropSeqSQL = 'DROP TABLE %s';
var $concat_operator = '||';
var $pdoDriver = false;
var $pdoDriver = false;
var $random='abs(random())';
function _init($parentDriver)
@@ -156,40 +156,48 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
// mark newnham
function MetaColumns($tab,$normalize=true)
{
global $ADODB_FETCH_MODE;
global $ADODB_FETCH_MODE;
$parent = $this->pdoDriver;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($parent->fetchMode !== false) $savem = $parent->SetFetchMode(false);
$rs = $parent->Execute("PRAGMA table_info('$tab')");
if (isset($savem)) $parent->SetFetchMode($savem);
if (!$rs) {
$ADODB_FETCH_MODE = $save;
return $false;
}
$arr = array();
while ($r = $rs->FetchRow()) {
$type = explode('(',$r['type']);
$size = '';
if (sizeof($type)==2)
$size = trim($type[1],')');
$fn = strtoupper($r['name']);
$fld = new ADOFieldObject;
$fld->name = $r['name'];
$fld->type = $type[0];
$fld->max_length = $size;
$fld->not_null = $r['notnull'];
$fld->primary_key = $r['pk'];
$fld->default_value = $r['dflt_value'];
$fld->scale = 0;
if ($save == ADODB_FETCH_NUM) $arr[] = $fld;
else $arr[strtoupper($fld->name)] = $fld;
}
$rs->Close();
$ADODB_FETCH_MODE = $save;
return $arr;
$parent = $this->pdoDriver;
$false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($parent->fetchMode !== false) {
$savem = $parent->SetFetchMode(false);
}
$rs = $parent->Execute("PRAGMA table_info('$tab')");
if (isset($savem)) {
$parent->SetFetchMode($savem);
}
if (!$rs) {
$ADODB_FETCH_MODE = $save;
return $false;
}
$arr = array();
while ($r = $rs->FetchRow()) {
$type = explode('(', $r['type']);
$size = '';
if (sizeof($type) == 2) {
$size = trim($type[1], ')');
}
$fn = strtoupper($r['name']);
$fld = new ADOFieldObject;
$fld->name = $r['name'];
$fld->type = $type[0];
$fld->max_length = $size;
$fld->not_null = $r['notnull'];
$fld->primary_key = $r['pk'];
$fld->default_value = $r['dflt_value'];
$fld->scale = 0;
if ($save == ADODB_FETCH_NUM) {
$arr[] = $fld;
} else {
$arr[strtoupper($fld->name)] = $fld;
}
}
$rs->Close();
$ADODB_FETCH_MODE = $save;
return $arr;
}
function MetaTables($ttype=false,$showSchema=false,$mask=false)
@@ -208,5 +216,18 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
$this->metaTablesSQL = $save;
}
return $ret;
}
}
/**
* Returns a driver-specific format for a bind parameter
*
* @param string $name
* @param string $type (ignored in driver)
*
* @return string
*/
public function param($name,$type='C')
{
return sprintf(':%s', $name);
}
}
+44 -25
View File
@@ -26,6 +26,7 @@ class ADODB_postgres64 extends ADOConnection{
var $databaseType = 'postgres64';
var $dataProvider = 'postgres';
var $hasInsertID = true;
/** @var PgSql\Connection|resource|false */
var $_resultid = false;
var $concat_operator='||';
var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
@@ -154,7 +155,7 @@ class ADODB_postgres64 extends ADOConnection{
*/
protected function _insertID($table = '', $column = '')
{
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
if ($this->_resultid === false) return false;
$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);
@@ -162,13 +163,13 @@ class ADODB_postgres64 extends ADOConnection{
function _affectedrows()
{
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
if ($this->_resultid === false) return false;
return pg_affected_rows($this->_resultid);
}
/**
* @return true/false
* @return bool
*/
function BeginTrans()
{
@@ -378,7 +379,7 @@ class ADODB_postgres64 extends ADOConnection{
function BlobDelete( $blob )
{
pg_query($this->_connectionID, 'begin');
$result = @pg_lo_unlink($blob);
$result = @pg_lo_unlink($this->_connectionID, $blob);
pg_query($this->_connectionID, 'commit');
return( $result );
}
@@ -808,8 +809,7 @@ class ADODB_postgres64 extends ADOConnection{
if ($execp) $exsql = "EXECUTE $plan ($execp)";
else $exsql = "EXECUTE $plan";
$rez = @pg_execute($this->_connectionID,$exsql);
$rez = @pg_query($this->_connectionID, $exsql);
if (!$rez) {
# Perhaps plan does not exist? Prepare/compile plan.
$params = '';
@@ -833,18 +833,18 @@ class ADODB_postgres64 extends ADOConnection{
}
$s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2);
//adodb_pr($s);
$rez = pg_execute($this->_connectionID,$s);
$rez = pg_query($this->_connectionID, $s);
//echo $this->ErrorMsg();
}
if ($rez)
$rez = pg_execute($this->_connectionID,$exsql);
$rez = pg_query($this->_connectionID, $exsql);
} else {
//adodb_backtrace();
$rez = pg_query($this->_connectionID,$sql);
$rez = pg_query($this->_connectionID, $sql);
}
// check if no data returned, then no need to create real recordset
if ($rez && pg_num_fields($rez) <= 0) {
if (is_resource($this->_resultid) && get_resource_type($this->_resultid) === 'pgsql result') {
if ($this->_resultid !== false) {
pg_free_result($this->_resultid);
}
$this->_resultid = $rez;
@@ -1020,8 +1020,20 @@ class ADORecordSet_postgres64 extends ADORecordSet{
return pg_unescape_bytea($blob);
}
function _fixblobs()
/**
* Fetches and prepares the RecordSet's fields.
*
* Fixes the blobs if there are any.
*/
protected function _prepFields()
{
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
// Check prerequisites and bail early if we do not have what we need.
if (!isset($this->_blobArr) || $this->fields === false) {
return;
}
if ($this->fetchMode == PGSQL_NUM || $this->fetchMode == PGSQL_BOTH) {
foreach($this->_blobArr as $k => $v) {
$this->fields[$k] = ADORecordSet_postgres64::_decode($this->fields[$k]);
@@ -1040,9 +1052,8 @@ class ADORecordSet_postgres64 extends ADORecordSet{
if (!$this->EOF) {
$this->_currentRow++;
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if (is_array($this->fields) && $this->fields) {
if (isset($this->_blobArr)) $this->_fixblobs();
$this->_prepfields();
if ($this->fields !== false) {
return true;
}
}
@@ -1054,22 +1065,17 @@ class ADORecordSet_postgres64 extends ADORecordSet{
function _fetch()
{
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0)
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0) {
return false;
}
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
return (is_array($this->fields));
$this->_prepfields();
return $this->fields !== false;
}
function _close()
{
if (!is_resource($this->_queryID)
|| get_resource_type($this->_queryID) != 'pgsql result'
) {
if ($this->_queryID === false) {
return true;
}
return pg_free_result($this->_queryID);
@@ -1082,7 +1088,13 @@ class ADORecordSet_postgres64 extends ADORecordSet{
$t = $fieldobj->type;
$len = $fieldobj->max_length;
}
switch (strtoupper($t)) {
$t = strtoupper($t);
if (array_key_exists($t,$this->connection->customActualTypes))
return $this->connection->customActualTypes[$t];
switch ($t) {
case 'MONEY': // stupid, postgres expects money to be a string
case 'INTERVAL':
case 'CHAR':
@@ -1094,6 +1106,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
case 'CIDR':
case 'INET':
case 'MACADDR':
case 'UUID':
if ($len <= $this->blobSize) return 'C';
case 'TEXT':
@@ -1134,6 +1147,12 @@ class ADORecordSet_postgres64 extends ADORecordSet{
case 'SERIAL':
return 'R';
case 'NUMERIC':
case 'DECIMAL':
case 'FLOAT4':
case 'FLOAT8':
return 'N';
default:
return ADODB_DEFAULT_METATYPE;
}
+17 -61
View File
@@ -154,10 +154,7 @@ class ADODB_postgres7 extends ADODB_postgres64 {
}
}
/**
* @returns assoc array where keys are tables, and values are foreign keys
*/
function MetaForeignKeys($table, $owner=false, $upper=false)
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
# Regex isolates the 2 terms between parenthesis using subexpressions
$regex = '^.*\((.*)\).*\((.*)\).*$';
@@ -193,50 +190,18 @@ class ADODB_postgres7 extends ADODB_postgres64 {
$a = array();
while (!$rs->EOF) {
$lookup_table = $rs->fields('lookup_table');
$fields = $rs->fields('dep_field') . '=' . $rs->fields('lookup_field');
if ($upper) {
$a[strtoupper($rs->Fields('lookup_table'))][] = strtoupper(str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field')));
} else {
$a[$rs->Fields('lookup_table')][] = str_replace('"','',$rs->Fields('dep_field').'='.$rs->Fields('lookup_field'));
$lookup_table = strtoupper($lookup_table);
$fields = strtoupper($fields);
}
$a[$lookup_table][] = str_replace('"','', $fields);
$rs->MoveNext();
}
return $a;
}
// from Edward Jaramilla, improved version - works on pg 7.4
function _old_MetaForeignKeys($table, $owner=false, $upper=false)
{
$sql = 'SELECT t.tgargs as args
FROM
pg_trigger t,pg_class c,pg_proc p
WHERE
t.tgenabled AND
t.tgrelid = c.oid AND
t.tgfoid = p.oid AND
p.proname = \'RI_FKey_check_ins\' AND
c.relname = \''.strtolower($table).'\'
ORDER BY
t.tgrelid';
$rs = $this->Execute($sql);
if (!$rs || $rs->EOF) return false;
$arr = $rs->GetArray();
$a = array();
foreach($arr as $v) {
$data = explode(chr(0), $v['args']);
$size = count($data)-1; //-1 because the last node is empty
for($i = 4; $i < $size; $i++) {
if ($upper)
$a[strtoupper($data[2])][] = strtoupper($data[$i].'='.$data[++$i]);
else
$a[$data[2]][] = $data[$i].'='.$data[++$i];
}
}
return $a;
}
function _query($sql,$inputarr=false)
@@ -266,7 +231,7 @@ class ADODB_postgres7 extends ADODB_postgres64 {
}
// check if no data returned, then no need to create real recordset
if ($rez && pg_num_fields($rez) <= 0) {
if (is_resource($this->_resultid) && get_resource_type($this->_resultid) === 'pgsql result') {
if ($this->_resultid !== false) {
pg_free_result($this->_resultid);
}
$this->_resultid = $rez;
@@ -334,10 +299,8 @@ class ADORecordSet_postgres7 extends ADORecordSet_postgres64{
if (!$this->EOF) {
$this->_currentRow++;
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if (is_array($this->fields)) {
if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
$this->_prepfields();
if ($this->fields !== false) {
return true;
}
}
@@ -360,14 +323,13 @@ class ADORecordSet_assoc_postgres7 extends ADORecordSet_postgres64{
return false;
}
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if ($this->fields) {
if (isset($this->_blobArr)) $this->_fixblobs();
$this->_prepfields();
if ($this->fields !== false) {
$this->_updatefields();
return true;
}
return (is_array($this->fields));
return false;
}
function MoveNext()
@@ -375,19 +337,13 @@ class ADORecordSet_assoc_postgres7 extends ADORecordSet_postgres64{
if (!$this->EOF) {
$this->_currentRow++;
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if (is_array($this->fields)) {
if ($this->fields) {
if (isset($this->_blobArr)) $this->_fixblobs();
$this->_updatefields();
}
$this->_prepfields();
if ($this->fields !== false) {
$this->_updatefields();
return true;
}
}
$this->fields = false;
$this->EOF = true;
}
+134 -24
View File
@@ -24,6 +24,9 @@
// security - hide paths
if (!defined('ADODB_DIR')) die();
/**
* Class ADODB_sqlite3
*/
class ADODB_sqlite3 extends ADOConnection {
var $databaseType = "sqlite3";
var $dataProvider = "sqlite";
@@ -34,10 +37,13 @@ class ADODB_sqlite3 extends ADOConnection {
var $hasInsertID = true; /// supports autoincrement ID?
var $hasAffectedRows = true; /// supports affected rows for update/delete?
var $metaTablesSQL = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
var $sysDate = "adodb_date('Y-m-d')";
var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')";
var $sysDate = "DATE('now','localtime')";
var $sysTimeStamp = "DATETIME('now','localtime')";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
/** @var SQLite3 */
var $_connectionID;
function ServerInfo()
{
$version = SQLite3::version();
@@ -51,7 +57,7 @@ class ADODB_sqlite3 extends ADOConnection {
if ($this->transOff) {
return true;
}
$ret = $this->Execute("BEGIN TRANSACTION");
$this->Execute("BEGIN TRANSACTION");
$this->transCnt += 1;
return true;
}
@@ -95,6 +101,9 @@ class ADODB_sqlite3 extends ADOConnection {
$t = strtoupper($t);
if (array_key_exists($t,$this->customActualTypes))
return $this->customActualTypes[$t];
/*
* We are using the Sqlite affinity method here
* @link https://www.sqlite.org/datatype3.html
@@ -197,7 +206,7 @@ class ADODB_sqlite3 extends ADOConnection {
return $arr;
}
function metaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
public function metaForeignKeys($table, $owner = '', $upper = false, $associative = false)
{
global $ADODB_FETCH_MODE;
if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC
@@ -214,7 +223,7 @@ class ADODB_sqlite3 extends ADOConnection {
)
WHERE type != 'meta'
AND sql NOTNULL
AND LOWER(name) ='" . strtolower($table) . "'";
AND LOWER(name) ='" . strtolower($table) . "'";
$tableSql = $this->getOne($sql);
@@ -304,8 +313,7 @@ class ADODB_sqlite3 extends ADOConnection {
$this->_connectionID->createFunction('adodb_date2', 'adodb_date2', 2);
}
// returns true or false
/** @noinspection PhpUnusedParameterInspection */
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (empty($argHostname) && $argDatabasename) {
@@ -317,7 +325,6 @@ class ADODB_sqlite3 extends ADOConnection {
return true;
}
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
// There's no permanent connect in SQLite3
@@ -394,7 +401,7 @@ class ADODB_sqlite3 extends ADOConnection {
return false;
}
function CreateSequence($seqname='adodbseq',$start=1)
function createSequence($seqname='adodbseq', $startID=1)
{
if (empty($this->_genSeqSQL)) {
return false;
@@ -403,8 +410,8 @@ class ADODB_sqlite3 extends ADOConnection {
if (!$ok) {
return false;
}
$start -= 1;
return $this->Execute("insert into $seqname values($start)");
$startID -= 1;
return $this->Execute("insert into $seqname values($startID)");
}
var $_dropSeqSQL = 'drop table %s';
@@ -559,14 +566,13 @@ class ADODB_sqlite3 extends ADOConnection {
*
* This uses the more efficient strftime native function to process
*
* @param str $fld The name of the field to process
* @param string $fld The name of the field to process
*
* @return str The SQL Statement
* @return string The SQL Statement
*/
function month($fld)
{
$x = "strftime('%m',$fld)";
return $x;
return "strftime('%m',$fld)";
}
/**
@@ -574,13 +580,12 @@ class ADODB_sqlite3 extends ADOConnection {
*
* This uses the more efficient strftime native function to process
*
* @param str $fld The name of the field to process
* @param string $fld The name of the field to process
*
* @return str The SQL Statement
* @return string The SQL Statement
*/
function day($fld) {
$x = "strftime('%d',$fld)";
return $x;
return "strftime('%d',$fld)";
}
/**
@@ -588,14 +593,116 @@ class ADODB_sqlite3 extends ADOConnection {
*
* This uses the more efficient strftime native function to process
*
* @param str $fld The name of the field to process
* @param string $fld The name of the field to process
*
* @return str The SQL Statement
* @return string The SQL Statement
*/
function year($fld)
{
$x = "strftime('%Y',$fld)";
return $x;
return "strftime('%Y',$fld)";
}
/**
* SQLite update for blob
*
* SQLite must be a fully prepared statement (all variables must be bound),
* so $where can either be an array (array params) or a string that we will
* do our best to unpack and turn into a prepared statement.
*
* @param string $table
* @param string $column
* @param string $val Blob value to set
* @param mixed $where An array of parameters (key => value pairs),
* or a string (where clause).
* @param string $blobtype ignored
*
* @return bool success
*/
function updateBlob($table, $column, $val, $where, $blobtype = 'BLOB')
{
if (is_array($where)) {
// We were passed a set of key=>value pairs
$params = $where;
} else {
// Given a where clause string, we have to disassemble the
// statements into keys and values
$params = array();
$temp = preg_split('/(where|and)/i', $where);
$where = array_filter($temp);
foreach ($where as $wValue) {
$wTemp = preg_split('/[= \']+/', $wValue);
$wTemp = array_filter($wTemp);
$wTemp = array_values($wTemp);
$params[$wTemp[0]] = $wTemp[1];
}
}
$paramWhere = array();
foreach ($params as $bindKey => $bindValue) {
$paramWhere[] = $bindKey . '=?';
}
$sql = "UPDATE $table SET $column=? WHERE "
. implode(' AND ', $paramWhere);
// Prepare the statement
$stmt = $this->_connectionID->prepare($sql);
// Set the first bind value equal to value we want to update
if (!$stmt->bindValue(1, $val, SQLITE3_BLOB)) {
return false;
}
// Build as many keys as available
$bindIndex = 2;
foreach ($params as $bindValue) {
if (is_integer($bindValue) || is_bool($bindValue) || is_float($bindValue)) {
$type = SQLITE3_NUM;
} elseif (is_object($bindValue)) {
// Assume a blob, this should never appear in
// the binding for a where statement anyway
$type = SQLITE3_BLOB;
} else {
$type = SQLITE3_TEXT;
}
if (!$stmt->bindValue($bindIndex, $bindValue, $type)) {
return false;
}
$bindIndex++;
}
// Now execute the update. NB this is SQLite execute, not ADOdb
$ok = $stmt->execute();
return is_object($ok);
}
/**
* SQLite update for blob from a file
*
* @param string $table
* @param string $column
* @param string $path Filename containing blob data
* @param mixed $where {@see updateBlob()}
* @param string $blobtype ignored
*
* @return bool success
*/
function updateBlobFile($table, $column, $path, $where, $blobtype = 'BLOB')
{
if (!file_exists($path)) {
return false;
}
// Read file information
$fileContents = file_get_contents($path);
if ($fileContents === false)
// Distinguish between an empty file and failure
return false;
return $this->updateBlob($table, $column, $fileContents, $where, $blobtype);
}
}
@@ -609,9 +716,12 @@ class ADORecordset_sqlite3 extends ADORecordSet {
var $databaseType = "sqlite3";
var $bind = false;
/** @var SQLite3Result */
var $_queryID;
/** @noinspection PhpMissingParentConstructorInspection */
function __construct($queryID,$mode=false)
{
if ($mode === false) {
global $ADODB_FETCH_MODE;
$mode = $ADODB_FETCH_MODE;
+2 -2
View File
@@ -125,7 +125,7 @@ class perf_mysql extends adodb_perf{
/**
* Returns a list of table statuses.
*
*
* @param string $orderby Unused (compatibility with parent method)
* @return string A formatted set of recordsets
*/
@@ -299,7 +299,7 @@ class perf_mysql extends adodb_perf{
var $optimizeTableHigh = 'OPTIMIZE TABLE %s';
/**
* @see adodb_perf#optimizeTable
* @see adodb_perf::optimizeTable()
*/
function optimizeTable( $table, $mode = ADODB_OPT_LOW)
{
+2 -2
View File
@@ -102,7 +102,7 @@ class perf_postgres extends adodb_perf{
var $optimizeTableHigh = 'VACUUM ANALYZE %s';
/**
* @see adodb_perf#optimizeTable
* @see adodb_perf::optimizeTable()
*/
function optimizeTable($table, $mode = ADODB_OPT_LOW)
@@ -131,7 +131,7 @@ class perf_postgres extends adodb_perf{
if ($partial) {
$sqlq = $this->conn->qstr($sql.'%');
$arr = $this->conn->GetArray("select distinct distinct sql1 from adodb_logsql where sql1 like $sqlq");
$arr = $this->conn->getArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
if ($arr) {
foreach($arr as $row) {
$sql = reset($row);
+40
View File
@@ -0,0 +1,40 @@
<?php
// security - hide paths
if (!defined('ADODB_DIR')) die();
class perf_sqlite3 extends adodb_perf{
var $tablesSQL = "SELECT * FROM sqlite_master WHERE type='table'";
var $createTableSQL = "CREATE TABLE adodb_logsql (
created datetime NOT NULL,
sql0 varchar(250) NOT NULL,
sql1 text NOT NULL,
params text NOT NULL,
tracer text NOT NULL,
timer decimal(16,6) NOT NULL
)";
var $settings = array();
function __construct(&$conn)
{
$this->conn = $conn;
}
function tables($orderby='1')
{
if (!$this->tablesSQL){
return false;
}
$rs = $this->conn->execute($this->tablesSQL);
if (!$rs) {
return false;
}
$html = rs2html($rs, false, false, false, false);
return $html;
}
}
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<phpdocumentor
configVersion="3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://www.phpdoc.org"
xsi:noNamespaceSchemaLocation="https://docs.phpdoc.org/latest/phpdoc.xsd"
>
<paths>
<output>docs/api</output>
<cache>docs/cache</cache>
</paths>
<version number="latest">
<api>
<source dsn=".">
</source>
<ignore>
<path>scripts</path>
<path>tests</path>
<path>vendor/**/*</path>
<path>xsl</path>
</ignore>
</api>
</version>
</phpdocumentor>
+2 -5
View File
@@ -1,4 +1,4 @@
Description of ADOdb v5.21.4 library import into Moodle 4.0 and up
Description of ADOdb library import into Moodle
Source: https://github.com/ADOdb/ADOdb
@@ -16,13 +16,10 @@ Removed:
* pear/
* replicate/ (if present)
* scripts/ (if present)
* server.php
* server.php (if present)
* session/
* tests/ (if present)
Added:
* index.html - prevent directory browsing on misconfigured servers
* readme_moodle.txt - this file ;-)
Our changes (to be checked on next update if they are already applied upstream):
* https://github.com/ADOdb/ADOdb/issues/791
+1 -1
View File
@@ -4,7 +4,7 @@
<location>adodb</location>
<name>AdoDB</name>
<license>BSD/LGPL</license>
<version>5.21.4</version>
<version>5.22.2</version>
<licenseversion>3-Clause/2.1+</licenseversion>
</library>
<library>