mirror of
https://github.com/moodle/moodle.git
synced 2025-04-19 23:42:11 +02:00
MDL-74095 lib: Upgrade ADODB to 5.22.2
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
This commit is contained in:
parent
5500d143f4
commit
bfe70c09f9
@ -1,8 +1,9 @@
|
||||
ADOdb Library for PHP
|
||||
======================
|
||||
|
||||
[](https://gitter.im/adodb/adodb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://sourceforge.net/projects/adodb/files/latest/download)
|
||||
[](https://gitter.im/adodb/adodb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://sourceforge.net/projects/adodb/files/latest/download)
|
||||
[](https://packagist.org/packages/adodb/adodb-php)
|
||||
|
||||
(c) 2000-2013 John Lim (jlim@natsoft.com)
|
||||
(c) 2014 Damien Regad, Mark Newnham and the
|
||||
|
45
lib/adodb/SECURITY.md
Normal file
45
lib/adodb/SECURITY.md
Normal 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.
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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':
|
||||
|
@ -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';
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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':
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
@ -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';
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
|
@ -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 andrew005@mnogo.ru
|
||||
$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" <mille562@pilot.msu.edu>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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':
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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 robert@ud.com
|
||||
@ -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':
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
lib/adodb/perf/perf-sqlite3.inc.php
Normal file
40
lib/adodb/perf/perf-sqlite3.inc.php
Normal 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
lib/adodb/phpdoc.dist.xml
Normal file
24
lib/adodb/phpdoc.dist.xml
Normal 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>
|
@ -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
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user