diff --git a/lib/adodb/README.md b/lib/adodb/README.md
index e432b2fb0af..96ac67b2900 100644
--- a/lib/adodb/README.md
+++ b/lib/adodb/README.md
@@ -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
diff --git a/lib/adodb/SECURITY.md b/lib/adodb/SECURITY.md
new file mode 100644
index 00000000000..00670f24492
--- /dev/null
+++ b/lib/adodb/SECURITY.md
@@ -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.
diff --git a/lib/adodb/adodb-active-record.inc.php b/lib/adodb/adodb-active-record.inc.php
index 8f3b00538f6..ad40640a3ae 100644
--- a/lib/adodb/adodb-active-record.inc.php
+++ b/lib/adodb/adodb-active-record.inc.php
@@ -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);
}
diff --git a/lib/adodb/adodb-csvlib.inc.php b/lib/adodb/adodb-csvlib.inc.php
index c81254bfc03..77e63bfb062 100644
--- a/lib/adodb/adodb-csvlib.inc.php
+++ b/lib/adodb/adodb-csvlib.inc.php
@@ -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;
diff --git a/lib/adodb/adodb-datadict.inc.php b/lib/adodb/adodb-datadict.inc.php
index dbed95da714..9dfa07a6fcf 100644
--- a/lib/adodb/adodb-datadict.inc.php
+++ b/lib/adodb/adodb-datadict.inc.php
@@ -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;
diff --git a/lib/adodb/adodb-exceptions.inc.php b/lib/adodb/adodb-exceptions.inc.php
index 9f1176f0f69..560286a1847 100644
--- a/lib/adodb/adodb-exceptions.inc.php
+++ b/lib/adodb/adodb-exceptions.inc.php
@@ -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;
}
diff --git a/lib/adodb/adodb-loadbalancer.inc.php b/lib/adodb/adodb-loadbalancer.inc.php
index 2e4f3928d3e..88f5d0fdc21 100644
--- a/lib/adodb/adodb-loadbalancer.inc.php
+++ b/lib/adodb/adodb-loadbalancer.inc.php
@@ -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.
*
diff --git a/lib/adodb/adodb-memcache.lib.inc.php b/lib/adodb/adodb-memcache.lib.inc.php
index 7f110e7493c..a251c9c328b 100644
--- a/lib/adodb/adodb-memcache.lib.inc.php
+++ b/lib/adodb/adodb-memcache.lib.inc.php
@@ -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! \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! \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! \n");
- else ADOConnection::outp("flushall: succeeded! \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! \n");
- else ADOConnection::outp("flushcache: $key entry flushed from memcache server! \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! \n");
+ } else {
+ ADOConnection::outp("flushall: succeeded! \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! \n");
+ } else {
+ ADOConnection::outp("flushcache: $filename entry flushed from memcache server! \n");
+ }
+ }
+
+ return $del;
+ }
+
+}
diff --git a/lib/adodb/adodb-xmlschema.inc.php b/lib/adodb/adodb-xmlschema.inc.php
index 58e3affd6c5..32b8afa1e61 100644
--- a/lib/adodb/adodb-xmlschema.inc.php
+++ b/lib/adodb/adodb-xmlschema.inc.php
@@ -26,133 +26,119 @@
* @author Dan Cech
*/
-function _file_get_contents($file)
-{
- if (function_exists('file_get_contents')) return file_get_contents($file);
-
- $f = fopen($file,'r');
- if (!$f) return '';
- $t = '';
-
- while ($s = fread($f,100000)) $t .= $s;
- fclose($f);
- return $t;
-}
-
-
/**
-* Debug on or off
-*/
+ * Debug on or off
+ */
if( !defined( 'XMLS_DEBUG' ) ) {
define( 'XMLS_DEBUG', FALSE );
}
/**
-* Default prefix key
-*/
+ * Default prefix key
+ */
if( !defined( 'XMLS_PREFIX' ) ) {
define( 'XMLS_PREFIX', '%%P' );
}
/**
-* Maximum length allowed for object prefix
-*/
+ * Maximum length allowed for object prefix
+ */
if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
define( 'XMLS_PREFIX_MAXLEN', 10 );
}
/**
-* Execute SQL inline as it is generated
-*/
+ * Execute SQL inline as it is generated
+ */
if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
define( 'XMLS_EXECUTE_INLINE', FALSE );
}
/**
-* Continue SQL Execution if an error occurs?
-*/
+ * Continue SQL Execution if an error occurs?
+ */
if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
}
/**
-* Current Schema Version
-*/
+ * Current Schema Version
+ */
if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
define( 'XMLS_SCHEMA_VERSION', '0.2' );
}
/**
-* Default Schema Version. Used for Schemas without an explicit version set.
-*/
+ * Default Schema Version. Used for Schemas without an explicit version set.
+ */
if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
}
/**
-* Default Schema Version. Used for Schemas without an explicit version set.
-*/
+ * Default Schema Version. Used for Schemas without an explicit version set.
+ */
if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
}
/**
-* Include the main ADODB library
-*/
+ * Include the main ADODB library
+ */
if( !defined( '_ADODB_LAYER' ) ) {
require( 'adodb.inc.php' );
require( 'adodb-datadict.inc.php' );
}
/**
-* Abstract DB Object. This class provides basic methods for database objects, such
-* as tables and indexes.
-*
-* @package axmls
-* @access private
-*/
+ * Abstract DB Object. This class provides basic methods for database objects, such
+ * as tables and indexes.
+ *
+ * @package axmls
+ * @access private
+ */
class dbObject {
/**
- * var object Parent
- */
+ * var object Parent
+ */
var $parent;
/**
- * var string current element
- */
+ * var string current element
+ */
var $currentElement;
/**
- * NOP
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * NOP
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
}
/**
- * XML Callback to process start elements
- *
- * @access private
- */
+ * XML Callback to process start elements
+ *
+ * @access private
+ */
function _tag_open( &$parser, $tag, $attributes ) {
}
/**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * @access private
+ */
function _tag_cdata( &$parser, $cdata ) {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( &$parser, $tag ) {
}
@@ -162,110 +148,110 @@ class dbObject {
}
/**
- * Destroys the object
- */
+ * Destroys the object
+ */
function destroy() {
}
/**
- * Checks whether the specified RDBMS is supported by the current
- * database object or its ranking ancestor.
- *
- * @param string $platform RDBMS platform name (from ADODB platform list).
- * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
- */
+ * Checks whether the specified RDBMS is supported by the current
+ * database object or its ranking ancestor.
+ *
+ * @param string $platform RDBMS platform name (from ADODB platform list).
+ * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
+ */
function supportedPlatform( $platform = NULL ) {
return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
}
/**
- * Returns the prefix set by the ranking ancestor of the database object.
- *
- * @param string $name Prefix string.
- * @return string Prefix.
- */
+ * Returns the prefix set by the ranking ancestor of the database object.
+ *
+ * @param string $name Prefix string.
+ * @return string Prefix.
+ */
function prefix( $name = '' ) {
return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
}
/**
- * Extracts a field ID from the specified field.
- *
- * @param string $field Field.
- * @return string Field ID.
- */
+ * Extracts a field ID from the specified field.
+ *
+ * @param string $field Field.
+ * @return string Field ID.
+ */
function FieldID( $field ) {
return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
}
}
/**
-* Creates a table object in ADOdb's datadict format
-*
-* This class stores information about a database table. As charactaristics
-* of the table are loaded from the external source, methods and properties
-* of this class are used to build up the table description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
+ * Creates a table object in ADOdb's datadict format
+ *
+ * This class stores information about a database table. As charactaristics
+ * of the table are loaded from the external source, methods and properties
+ * of this class are used to build up the table description in ADOdb's
+ * datadict format.
+ *
+ * @package axmls
+ * @access private
+ */
class dbTable extends dbObject {
/**
- * @var string Table name
- */
+ * @var string Table name
+ */
var $name;
/**
- * @var array Field specifier: Meta-information about each field
- */
+ * @var array Field specifier: Meta-information about each field
+ */
var $fields = array();
/**
- * @var array List of table indexes.
- */
+ * @var array List of table indexes.
+ */
var $indexes = array();
/**
- * @var array Table options: Table-level options
- */
+ * @var array Table options: Table-level options
+ */
var $opts = array();
/**
- * @var string Field index: Keeps track of which field is currently being processed
- */
+ * @var string Field index: Keeps track of which field is currently being processed
+ */
var $current_field;
/**
- * @var boolean Mark table for destruction
- * @access private
- */
+ * @var boolean Mark table for destruction
+ * @access private
+ */
var $drop_table;
/**
- * @var boolean Mark field for destruction (not yet implemented)
- * @access private
- */
+ * @var boolean Mark field for destruction (not yet implemented)
+ * @access private
+ */
var $drop_field = array();
/**
- * Iniitializes a new table object.
- *
- * @param string $prefix DB Object prefix
- * @param array $attributes Array of table attributes.
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * Iniitializes a new table object.
+ *
+ * @param string $prefix DB Object prefix
+ * @param array $attributes Array of table attributes.
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
$this->name = $this->prefix($attributes['NAME']);
}
/**
- * XML Callback to process start elements. Elements currently
- * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT.
- *
- * @access private
- */
+ * XML Callback to process start elements. Elements currently
+ * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT.
+ *
+ * @access private
+ */
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
@@ -321,10 +307,10 @@ class dbTable extends dbObject {
}
/**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * @access private
+ */
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Table constraint
@@ -345,10 +331,10 @@ class dbTable extends dbObject {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
@@ -366,11 +352,11 @@ class dbTable extends dbObject {
}
/**
- * Adds an index to a table object
- *
- * @param array $attributes Index attributes
- * @return object dbIndex object
- */
+ * Adds an index to a table object
+ *
+ * @param array $attributes Index attributes
+ * @return object dbIndex object
+ */
function addIndex( $attributes ) {
$name = strtoupper( $attributes['NAME'] );
$this->indexes[$name] = new dbIndex( $this, $attributes );
@@ -378,11 +364,11 @@ class dbTable extends dbObject {
}
/**
- * Adds data to a table object
- *
- * @param array $attributes Data attributes
- * @return object dbData object
- */
+ * Adds data to a table object
+ *
+ * @param array $attributes Data attributes
+ * @return object dbData object
+ */
function addData( $attributes ) {
if( !isset( $this->data ) ) {
$this->data = new dbData( $this, $attributes );
@@ -391,34 +377,34 @@ class dbTable extends dbObject {
}
/**
- * Adds a field to a table object
- *
- * $name is the name of the table to which the field should be added.
- * $type is an ADODB datadict field type. The following field types
- * are supported as of ADODB 3.40:
- * - C: varchar
- * - X: CLOB (character large object) or largest varchar size
- * if CLOB is not supported
- * - C2: Multibyte varchar
- * - X2: Multibyte CLOB
- * - B: BLOB (binary large object)
- * - D: Date (some databases do not support this, and we return a datetime type)
- * - T: Datetime or Timestamp
- * - L: Integer field suitable for storing booleans (0 or 1)
- * - I: Integer (mapped to I4)
- * - I1: 1-byte integer
- * - I2: 2-byte integer
- * - I4: 4-byte integer
- * - I8: 8-byte integer
- * - F: Floating point number
- * - N: Numeric or decimal number
- *
- * @param string $name Name of the table to which the field will be added.
- * @param string $type ADODB datadict field type.
- * @param string $size Field size
- * @param array $opts Field options array
- * @return array Field specifier array
- */
+ * Adds a field to a table object
+ *
+ * $name is the name of the table to which the field should be added.
+ * $type is an ADODB datadict field type. The following field types
+ * are supported as of ADODB 3.40:
+ * - C: varchar
+ * - X: CLOB (character large object) or largest varchar size
+ * if CLOB is not supported
+ * - C2: Multibyte varchar
+ * - X2: Multibyte CLOB
+ * - B: BLOB (binary large object)
+ * - D: Date (some databases do not support this, and we return a datetime type)
+ * - T: Datetime or Timestamp
+ * - L: Integer field suitable for storing booleans (0 or 1)
+ * - I: Integer (mapped to I4)
+ * - I1: 1-byte integer
+ * - I2: 2-byte integer
+ * - I4: 4-byte integer
+ * - I8: 8-byte integer
+ * - F: Floating point number
+ * - N: Numeric or decimal number
+ *
+ * @param string $name Name of the table to which the field will be added.
+ * @param string $type ADODB datadict field type.
+ * @param string $size Field size
+ * @param array $opts Field options array
+ * @return array Field specifier array
+ */
function addField( $name, $type, $size = NULL, $opts = NULL ) {
$field_id = $this->FieldID( $name );
@@ -443,16 +429,16 @@ class dbTable extends dbObject {
}
/**
- * Adds a field option to the current field specifier
- *
- * This method adds a field option allowed by the ADOdb datadict
- * and appends it to the given field.
- *
- * @param string $field Field name
- * @param string $opt ADOdb field option
- * @param mixed $value Field option value
- * @return array Field specifier array
- */
+ * Adds a field option to the current field specifier
+ *
+ * This method adds a field option allowed by the ADOdb datadict
+ * and appends it to the given field.
+ *
+ * @param string $field Field name
+ * @param string $opt ADOdb field option
+ * @param mixed $value Field option value
+ * @return array Field specifier array
+ */
function addFieldOpt( $field, $opt, $value = NULL ) {
if( !isset( $value ) ) {
$this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;
@@ -463,14 +449,14 @@ class dbTable extends dbObject {
}
/**
- * Adds an option to the table
- *
- * This method takes a comma-separated list of table-level options
- * and appends them to the table object.
- *
- * @param string $opt Table option
- * @return array Options
- */
+ * Adds an option to the table
+ *
+ * This method takes a comma-separated list of table-level options
+ * and appends them to the table object.
+ *
+ * @param string $opt Table option
+ * @return array Options
+ */
function addTableOpt( $opt ) {
if(isset($this->currentPlatform)) {
$this->opts[$this->parent->db->databaseType] = $opt;
@@ -480,11 +466,11 @@ class dbTable extends dbObject {
/**
- * Generates the SQL that will create the table in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing table creation SQL
- */
+ * Generates the SQL that will create the table in the database
+ *
+ * @param object $xmls adoSchema object
+ * @return array Array containing table creation SQL
+ */
function create( &$xmls ) {
$sql = array();
@@ -592,8 +578,8 @@ class dbTable extends dbObject {
}
/**
- * Marks a field or table for destruction
- */
+ * Marks a field or table for destruction
+ */
function drop() {
if( isset( $this->current_field ) ) {
// Drop the current field
@@ -610,61 +596,61 @@ class dbTable extends dbObject {
}
/**
-* Creates an index object in ADOdb's datadict format
-*
-* This class stores information about a database index. As charactaristics
-* of the index are loaded from the external source, methods and properties
-* of this class are used to build up the index description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
+ * Creates an index object in ADOdb's datadict format
+ *
+ * This class stores information about a database index. As charactaristics
+ * of the index are loaded from the external source, methods and properties
+ * of this class are used to build up the index description in ADOdb's
+ * datadict format.
+ *
+ * @package axmls
+ * @access private
+ */
class dbIndex extends dbObject {
/**
- * @var string Index name
- */
+ * @var string Index name
+ */
var $name;
/**
- * @var array Index options: Index-level options
- */
+ * @var array Index options: Index-level options
+ */
var $opts = array();
/**
- * @var array Indexed fields: Table columns included in this index
- */
+ * @var array Indexed fields: Table columns included in this index
+ */
var $columns = array();
/**
- * @var boolean Mark index for destruction
- * @access private
- */
+ * @var boolean Mark index for destruction
+ * @access private
+ */
var $drop = FALSE;
/**
- * Initializes the new dbIndex object.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- *
- * @internal
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * Initializes the new dbIndex object.
+ *
+ * @param object $parent Parent object
+ * @param array $attributes Attributes
+ *
+ * @internal
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
$this->name = $this->prefix ($attributes['NAME']);
}
/**
- * XML Callback to process start elements
- *
- * Processes XML opening tags.
- * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
- *
- * @access private
- */
+ * XML Callback to process start elements
+ *
+ * Processes XML opening tags.
+ * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
+ *
+ * @access private
+ */
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
@@ -686,12 +672,12 @@ class dbIndex extends dbObject {
}
/**
- * XML Callback to process CDATA elements
- *
- * Processes XML cdata.
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * Processes XML cdata.
+ *
+ * @access private
+ */
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
@@ -704,10 +690,10 @@ class dbIndex extends dbObject {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
@@ -719,11 +705,11 @@ class dbIndex extends dbObject {
}
/**
- * Adds a field to the index
- *
- * @param string $name Field name
- * @return string Field list
- */
+ * Adds a field to the index
+ *
+ * @param string $name Field name
+ * @return string Field list
+ */
function addField( $name ) {
$this->columns[$this->FieldID( $name )] = $name;
@@ -732,11 +718,11 @@ class dbIndex extends dbObject {
}
/**
- * Adds options to the index
- *
- * @param string $opt Comma-separated list of index options.
- * @return string Option list
- */
+ * Adds options to the index
+ *
+ * @param string $opt Comma-separated list of index options.
+ * @return string Option list
+ */
function addIndexOpt( $opt ) {
$this->opts[] = $opt;
@@ -745,11 +731,11 @@ class dbIndex extends dbObject {
}
/**
- * Generates the SQL that will create the index in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing index creation SQL
- */
+ * Generates the SQL that will create the index in the database
+ *
+ * @param object $xmls adoSchema object
+ * @return array Array containing index creation SQL
+ */
function create( &$xmls ) {
if( $this->drop ) {
return NULL;
@@ -766,21 +752,21 @@ class dbIndex extends dbObject {
}
/**
- * Marks an index for destruction
- */
+ * Marks an index for destruction
+ */
function drop() {
$this->drop = TRUE;
}
}
/**
-* Creates a data object in ADOdb's datadict format
-*
-* This class stores information about table data.
-*
-* @package axmls
-* @access private
-*/
+ * Creates a data object in ADOdb's datadict format
+ *
+ * This class stores information about table data.
+ *
+ * @package axmls
+ * @access private
+ */
class dbData extends dbObject {
var $data = array();
@@ -788,25 +774,25 @@ class dbData extends dbObject {
var $row;
/**
- * Initializes the new dbIndex object.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- *
- * @internal
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * Initializes the new dbIndex object.
+ *
+ * @param object $parent Parent object
+ * @param array $attributes Attributes
+ *
+ * @internal
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
}
/**
- * XML Callback to process start elements
- *
- * Processes XML opening tags.
- * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
- *
- * @access private
- */
+ * XML Callback to process start elements
+ *
+ * Processes XML opening tags.
+ * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
+ *
+ * @access private
+ */
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
@@ -823,12 +809,12 @@ class dbData extends dbObject {
}
/**
- * XML Callback to process CDATA elements
- *
- * Processes XML cdata.
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * Processes XML cdata.
+ *
+ * @access private
+ */
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
@@ -841,10 +827,10 @@ class dbData extends dbObject {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
@@ -856,11 +842,11 @@ class dbData extends dbObject {
}
/**
- * Adds a field to the index
- *
- * @param string $name Field name
- * @return string Field list
- */
+ * Adds a field to the index
+ *
+ * @param string $name Field name
+ * @return string Field list
+ */
function addField( $attributes ) {
if( isset( $attributes['NAME'] ) ) {
$name = $attributes['NAME'];
@@ -873,11 +859,11 @@ class dbData extends dbObject {
}
/**
- * Adds options to the index
- *
- * @param string $opt Comma-separated list of index options.
- * @return string Option list
- */
+ * Adds options to the index
+ *
+ * @param string $opt Comma-separated list of index options.
+ * @return string Option list
+ */
function addData( $cdata ) {
if( !isset( $this->data[$this->row] ) ) {
$this->data[$this->row] = array();
@@ -891,11 +877,11 @@ class dbData extends dbObject {
}
/**
- * Generates the SQL that will create the index in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing index creation SQL
- */
+ * Generates the SQL that will create the index in the database
+ *
+ * @param object $xmls adoSchema object
+ * @return array Array containing index creation SQL
+ */
function create( &$xmls ) {
$table = $xmls->dict->TableName($this->parent->name);
$table_field_count = count($this->parent->fields);
@@ -909,7 +895,8 @@ class dbData extends dbObject {
foreach( $row as $field_id => $field_data ) {
if( !array_key_exists( $field_id, $table_fields ) ) {
if( is_numeric( $field_id ) ) {
- $field_id = reset( array_keys( $table_fields ) );
+ $keys = array_keys($table_fields);
+ $field_id = reset($keys);
} else {
continue;
}
@@ -961,40 +948,40 @@ class dbData extends dbObject {
}
/**
-* Creates the SQL to execute a list of provided SQL queries
-*
-* @package axmls
-* @access private
-*/
+ * Creates the SQL to execute a list of provided SQL queries
+ *
+ * @package axmls
+ * @access private
+ */
class dbQuerySet extends dbObject {
/**
- * @var array List of SQL queries
- */
+ * @var array List of SQL queries
+ */
var $queries = array();
/**
- * @var string String used to build of a query line by line
- */
+ * @var string String used to build of a query line by line
+ */
var $query;
/**
- * @var string Query prefix key
- */
+ * @var string Query prefix key
+ */
var $prefixKey = '';
/**
- * @var boolean Auto prefix enable (TRUE)
- */
+ * @var boolean Auto prefix enable (TRUE)
+ */
var $prefixMethod = 'AUTO';
/**
- * Initializes the query set.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * Initializes the query set.
+ *
+ * @param object $parent Parent object
+ * @param array $attributes Attributes
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
// Overrides the manual prefix key
@@ -1019,11 +1006,11 @@ class dbQuerySet extends dbObject {
}
/**
- * XML Callback to process start elements. Elements currently
- * processed are: QUERY.
- *
- * @access private
- */
+ * XML Callback to process start elements. Elements currently
+ * processed are: QUERY.
+ *
+ * @access private
+ */
function _tag_open( &$parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
@@ -1044,8 +1031,8 @@ class dbQuerySet extends dbObject {
}
/**
- * XML Callback to process CDATA elements
- */
+ * XML Callback to process CDATA elements
+ */
function _tag_cdata( &$parser, $cdata ) {
switch( $this->currentElement ) {
// Line of queryset SQL data
@@ -1058,10 +1045,10 @@ class dbQuerySet extends dbObject {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( &$parser, $tag ) {
$this->currentElement = '';
@@ -1081,10 +1068,10 @@ class dbQuerySet extends dbObject {
}
/**
- * Re-initializes the query.
- *
- * @return boolean TRUE
- */
+ * Re-initializes the query.
+ *
+ * @return boolean TRUE
+ */
function newQuery() {
$this->query = '';
@@ -1092,10 +1079,10 @@ class dbQuerySet extends dbObject {
}
/**
- * Discards the existing query.
- *
- * @return boolean TRUE
- */
+ * Discards the existing query.
+ *
+ * @return boolean TRUE
+ */
function discardQuery() {
unset( $this->query );
@@ -1103,11 +1090,11 @@ class dbQuerySet extends dbObject {
}
/**
- * Appends a line to a query that is being built line by line
- *
- * @param string $data Line of SQL data or NULL to initialize a new query
- * @return string SQL query string.
- */
+ * Appends a line to a query that is being built line by line
+ *
+ * @param string $data Line of SQL data or NULL to initialize a new query
+ * @return string SQL query string.
+ */
function buildQuery( $sql = NULL ) {
if( !isset( $this->query ) OR empty( $sql ) ) {
return FALSE;
@@ -1119,10 +1106,10 @@ class dbQuerySet extends dbObject {
}
/**
- * Adds a completed query to the query list
- *
- * @return string SQL of added query
- */
+ * Adds a completed query to the query list
+ *
+ * @return string SQL of added query
+ */
function addQuery() {
if( !isset( $this->query ) ) {
return FALSE;
@@ -1136,11 +1123,11 @@ class dbQuerySet extends dbObject {
}
/**
- * Creates and returns the current query set
- *
- * @param object $xmls adoSchema object
- * @return array Query set
- */
+ * Creates and returns the current query set
+ *
+ * @param object $xmls adoSchema object
+ * @return array Query set
+ */
function create( &$xmls ) {
foreach( $this->queries as $id => $query ) {
switch( $this->prefixMethod ) {
@@ -1176,13 +1163,13 @@ class dbQuerySet extends dbObject {
}
/**
- * Rebuilds the query with the prefix attached to any objects
- *
- * @param string $regex Regex used to add prefix
- * @param string $query SQL query string
- * @param string $prefix Prefix to be appended to tables, indices, etc.
- * @return string Prefixed SQL query string.
- */
+ * Rebuilds the query with the prefix attached to any objects
+ *
+ * @param string $regex Regex used to add prefix
+ * @param string $query SQL query string
+ * @param string $prefix Prefix to be appended to tables, indices, etc.
+ * @return string Prefixed SQL query string.
+ */
function prefixQuery( $regex, $query, $prefix = NULL ) {
if( !isset( $prefix ) ) {
return $query;
@@ -1212,98 +1199,98 @@ class dbQuerySet extends dbObject {
}
/**
-* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
-*
-* This class is used to load and parse the XML file, to create an array of SQL statements
-* that can be used to build a database, and to build the database using the SQL array.
-*
-* @tutorial getting_started.pkg
-*
-* @author Richard Tango-Lowy & Dan Cech
-* @version $Revision: 1.12 $
-*
-* @package axmls
-*/
+ * Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
+ *
+ * This class is used to load and parse the XML file, to create an array of SQL statements
+ * that can be used to build a database, and to build the database using the SQL array.
+ *
+ * @tutorial getting_started.pkg
+ *
+ * @author Richard Tango-Lowy & Dan Cech
+ * @version 1.12
+ *
+ * @package axmls
+ */
class adoSchema {
/**
- * @var array Array containing SQL queries to generate all objects
- * @access private
- */
+ * @var array Array containing SQL queries to generate all objects
+ * @access private
+ */
var $sqlArray;
/**
- * @var object ADOdb connection object
- * @access private
- */
+ * @var object ADOdb connection object
+ * @access private
+ */
var $db;
/**
- * @var object ADOdb Data Dictionary
- * @access private
- */
+ * @var object ADOdb Data Dictionary
+ * @access private
+ */
var $dict;
/**
- * @var string Current XML element
- * @access private
- */
+ * @var string Current XML element
+ * @access private
+ */
var $currentElement = '';
/**
- * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
- * @access private
- */
+ * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
+ * @access private
+ */
var $upgrade = '';
/**
- * @var string Optional object prefix
- * @access private
- */
+ * @var string Optional object prefix
+ * @access private
+ */
var $objectPrefix = '';
/**
- * @var long System debug
- * @access private
- */
+ * @var long System debug
+ * @access private
+ */
var $debug;
/**
- * @var string Regular expression to find schema version
- * @access private
- */
+ * @var string Regular expression to find schema version
+ * @access private
+ */
var $versionRegex = '//';
/**
- * @var string Current schema version
- * @access private
- */
+ * @var string Current schema version
+ * @access private
+ */
var $schemaVersion;
/**
- * @var int Success of last Schema execution
- */
+ * @var int Success of last Schema execution
+ */
var $success;
/**
- * @var bool Execute SQL inline as it is generated
- */
+ * @var bool Execute SQL inline as it is generated
+ */
var $executeInline;
/**
- * @var bool Continue SQL execution if errors occur
- */
+ * @var bool Continue SQL execution if errors occur
+ */
var $continueOnError;
/**
- * Creates an adoSchema object
- *
- * Creating an adoSchema object is the first step in processing an XML schema.
- * The only parameter is an ADOdb database connection object, which must already
- * have been created.
- *
- * @param object $db ADOdb database connection object.
- */
+ * Creates an adoSchema object
+ *
+ * Creating an adoSchema object is the first step in processing an XML schema.
+ * The only parameter is an ADOdb database connection object, which must already
+ * have been created.
+ *
+ * @param object $db ADOdb database connection object.
+ */
function __construct( $db ) {
$this->db = $db;
$this->debug = $this->db->debug;
@@ -1316,21 +1303,21 @@ class adoSchema {
}
/**
- * Sets the method to be used for upgrading an existing database
- *
- * Use this method to specify how existing database objects should be upgraded.
- * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
- * alter each database object directly, REPLACE attempts to rebuild each object
- * from scratch, BEST attempts to determine the best upgrade method for each
- * object, and NONE disables upgrading.
- *
- * This method is not yet used by AXMLS, but exists for backward compatibility.
- * The ALTER method is automatically assumed when the adoSchema object is
- * instantiated; other upgrade methods are not currently supported.
- *
- * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
- * @returns string Upgrade method used
- */
+ * Sets the method to be used for upgrading an existing database
+ *
+ * Use this method to specify how existing database objects should be upgraded.
+ * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
+ * alter each database object directly, REPLACE attempts to rebuild each object
+ * from scratch, BEST attempts to determine the best upgrade method for each
+ * object, and NONE disables upgrading.
+ *
+ * This method is not yet used by AXMLS, but exists for backward compatibility.
+ * The ALTER method is automatically assumed when the adoSchema object is
+ * instantiated; other upgrade methods are not currently supported.
+ *
+ * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
+ * @returns string Upgrade method used
+ */
function SetUpgradeMethod( $method = '' ) {
if( !is_string( $method ) ) {
return FALSE;
@@ -1361,18 +1348,19 @@ class adoSchema {
}
/**
- * Enables/disables inline SQL execution.
- *
- * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
- * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
- * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
- * to apply the schema to the database.
- *
- * @param bool $mode execute
- * @return bool current execution mode
- *
- * @see ParseSchema(), ExecuteSchema()
- */
+ * Enables/disables inline SQL execution.
+ *
+ * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
+ * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
+ * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
+ * to apply the schema to the database.
+ *
+ * @param bool $mode execute
+ * @return bool current execution mode
+ *
+ * @see ParseSchema()
+ * @see ExecuteSchema()
+ */
function ExecuteInline( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->executeInline = $mode;
@@ -1382,18 +1370,19 @@ class adoSchema {
}
/**
- * Enables/disables SQL continue on error.
- *
- * Call this method to enable or disable continuation of SQL execution if an error occurs.
- * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
- * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
- * of the schema will continue.
- *
- * @param bool $mode execute
- * @return bool current continueOnError mode
- *
- * @see addSQL(), ExecuteSchema()
- */
+ * Enables/disables SQL continue on error.
+ *
+ * Call this method to enable or disable continuation of SQL execution if an error occurs.
+ * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
+ * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
+ * of the schema will continue.
+ *
+ * @param bool $mode execute
+ * @return bool current continueOnError mode
+ *
+ * @see addSQL()
+ * @see ExecuteSchema()
+ */
function ContinueOnError( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->continueOnError = $mode;
@@ -1403,33 +1392,34 @@ class adoSchema {
}
/**
- * Loads an XML schema from a file and converts it to SQL.
- *
- * Call this method to load the specified schema (see the DTD for the proper format) from
- * the filesystem and generate the SQL necessary to create the database described.
- * @see ParseSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute
- */
+ * Loads an XML schema from a file and converts it to SQL.
+ *
+ * Call this method to load the specified schema (see the DTD for the proper format) from
+ * the filesystem and generate the SQL necessary to create the database described.
+ * @see ParseSchemaString()
+ *
+ * @param string $file Name of XML schema file.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute
+ */
function ParseSchema( $filename, $returnSchema = FALSE ) {
return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
- * Loads an XML schema from a file and converts it to SQL.
- *
- * Call this method to load the specified schema from a file (see the DTD for the proper format)
- * and generate the SQL necessary to create the database described by the schema.
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- *
- * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
- * @see ParseSchema(), ParseSchemaString()
- */
+ * Loads an XML schema from a file and converts it to SQL.
+ *
+ * Call this method to load the specified schema from a file (see the DTD for the proper format)
+ * and generate the SQL necessary to create the database described by the schema.
+ *
+ * @param string $file Name of XML schema file.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute.
+ *
+ * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
+ * @see ParseSchema()
+ * @see ParseSchemaString()
+ */
function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
@@ -1472,16 +1462,16 @@ class adoSchema {
}
/**
- * Converts an XML schema string to SQL.
- *
- * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
- * and generate the SQL necessary to create the database described by the schema.
- * @see ParseSchema()
- *
- * @param string $xmlstring XML schema string.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- */
+ * Converts an XML schema string to SQL.
+ *
+ * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
+ * and generate the SQL necessary to create the database described by the schema.
+ * @see ParseSchema()
+ *
+ * @param string $xmlstring XML schema string.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute.
+ */
function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
@@ -1515,31 +1505,31 @@ class adoSchema {
}
/**
- * Loads an XML schema from a file and converts it to uninstallation SQL.
- *
- * Call this method to load the specified schema (see the DTD for the proper format) from
- * the filesystem and generate the SQL necessary to remove the database described.
- * @see RemoveSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute
- */
+ * Loads an XML schema from a file and converts it to uninstallation SQL.
+ *
+ * Call this method to load the specified schema (see the DTD for the proper format) from
+ * the filesystem and generate the SQL necessary to remove the database described.
+ * @see RemoveSchemaString()
+ *
+ * @param string $file Name of XML schema file.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute
+ */
function RemoveSchema( $filename, $returnSchema = FALSE ) {
return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
- * Converts an XML schema string to uninstallation SQL.
- *
- * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
- * and generate the SQL necessary to uninstall the database described by the schema.
- * @see RemoveSchema()
- *
- * @param string $schema XML schema string.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- */
+ * Converts an XML schema string to uninstallation SQL.
+ *
+ * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
+ * and generate the SQL necessary to uninstall the database described by the schema.
+ * @see RemoveSchema()
+ *
+ * @param string $schema XML schema string.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute.
+ */
function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
// grab current version
@@ -1551,18 +1541,20 @@ class adoSchema {
}
/**
- * Applies the current XML schema to the database (post execution).
- *
- * Call this method to apply the current schema (generally created by calling
- * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes,
- * and executing other SQL specified in the schema) after parsing.
- * @see ParseSchema(), ParseSchemaString(), ExecuteInline()
- *
- * @param array $sqlArray Array of SQL statements that will be applied rather than
- * the current schema.
- * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
- * @returns integer 0 if failure, 1 if errors, 2 if successful.
- */
+ * Applies the current XML schema to the database (post execution).
+ *
+ * Call this method to apply the current schema (generally created by calling
+ * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes,
+ * and executing other SQL specified in the schema) after parsing.
+ * @see ParseSchema()
+ * @see ParseSchemaString()
+ * @see ExecuteInline()
+ *
+ * @param array $sqlArray Array of SQL statements that will be applied rather than
+ * the current schema.
+ * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
+ * @returns integer 0 if failure, 1 if errors, 2 if successful.
+ */
function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
if( !is_bool( $continueOnErr ) ) {
$continueOnErr = $this->ContinueOnError();
@@ -1582,28 +1574,28 @@ class adoSchema {
}
/**
- * Returns the current SQL array.
- *
- * Call this method to fetch the array of SQL queries resulting from
- * ParseSchema() or ParseSchemaString().
- *
- * @param string $format Format: HTML, TEXT, or NONE (PHP array)
- * @return array Array of SQL statements or FALSE if an error occurs
- */
+ * Returns the current SQL array.
+ *
+ * Call this method to fetch the array of SQL queries resulting from
+ * ParseSchema() or ParseSchemaString().
+ *
+ * @param string $format Format: HTML, TEXT, or NONE (PHP array)
+ * @return array Array of SQL statements or FALSE if an error occurs
+ */
function PrintSQL( $format = 'NONE' ) {
$sqlArray = null;
return $this->getSQL( $format, $sqlArray );
}
/**
- * Saves the current SQL array to the local filesystem as a list of SQL queries.
- *
- * Call this method to save the array of SQL queries (generally resulting from a
- * parsed XML schema) to the filesystem.
- *
- * @param string $filename Path and name where the file should be saved.
- * @return boolean TRUE if save is successful, else FALSE.
- */
+ * Saves the current SQL array to the local filesystem as a list of SQL queries.
+ *
+ * Call this method to save the array of SQL queries (generally resulting from a
+ * parsed XML schema) to the filesystem.
+ *
+ * @param string $filename Path and name where the file should be saved.
+ * @return boolean TRUE if save is successful, else FALSE.
+ */
function SaveSQL( $filename = './schema.sql' ) {
if( !isset( $sqlArray ) ) {
@@ -1622,12 +1614,12 @@ class adoSchema {
}
/**
- * Create an xml parser
- *
- * @return object PHP XML parser object
- *
- * @access private
- */
+ * Create an xml parser
+ *
+ * @return object PHP XML parser object
+ *
+ * @access private
+ */
function create_parser() {
// Create the parser
$xmlParser = xml_parser_create();
@@ -1641,10 +1633,10 @@ class adoSchema {
}
/**
- * XML Callback to process start elements
- *
- * @access private
- */
+ * XML Callback to process start elements
+ *
+ * @access private
+ */
function _tag_open( &$parser, $tag, $attributes ) {
switch( strtoupper( $tag ) ) {
case 'TABLE':
@@ -1664,39 +1656,39 @@ class adoSchema {
}
/**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * @access private
+ */
function _tag_cdata( &$parser, $cdata ) {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- * @internal
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ * @internal
+ */
function _tag_close( &$parser, $tag ) {
}
/**
- * Converts an XML schema string to the specified DTD version.
- *
- * Call this method to convert a string containing an XML schema to a different AXMLS
- * DTD version. For instance, to convert a schema created for an pre-1.0 version for
- * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
- * parameter is specified, the schema will be converted to the current DTD version.
- * If the newFile parameter is provided, the converted schema will be written to the specified
- * file.
- * @see ConvertSchemaFile()
- *
- * @param string $schema String containing XML schema that will be converted.
- * @param string $newVersion DTD version to convert to.
- * @param string $newFile File name of (converted) output file.
- * @return string Converted XML schema or FALSE if an error occurs.
- */
+ * Converts an XML schema string to the specified DTD version.
+ *
+ * Call this method to convert a string containing an XML schema to a different AXMLS
+ * DTD version. For instance, to convert a schema created for an pre-1.0 version for
+ * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
+ * parameter is specified, the schema will be converted to the current DTD version.
+ * If the newFile parameter is provided, the converted schema will be written to the specified
+ * file.
+ * @see ConvertSchemaFile()
+ *
+ * @param string $schema String containing XML schema that will be converted.
+ * @param string $newVersion DTD version to convert to.
+ * @param string $newFile File name of (converted) output file.
+ * @return string Converted XML schema or FALSE if an error occurs.
+ */
function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
// grab current version
@@ -1722,29 +1714,22 @@ class adoSchema {
return $result;
}
- // compat for pre-4.3 - jlim
- function _file_get_contents($path)
- {
- if (function_exists('file_get_contents')) return file_get_contents($path);
- return join('',file($path));
- }
-
/**
- * Converts an XML schema file to the specified DTD version.
- *
- * Call this method to convert the specified XML schema file to a different AXMLS
- * DTD version. For instance, to convert a schema created for an pre-1.0 version for
- * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
- * parameter is specified, the schema will be converted to the current DTD version.
- * If the newFile parameter is provided, the converted schema will be written to the specified
- * file.
- * @see ConvertSchemaString()
- *
- * @param string $filename Name of XML schema file that will be converted.
- * @param string $newVersion DTD version to convert to.
- * @param string $newFile File name of (converted) output file.
- * @return string Converted XML schema or FALSE if an error occurs.
- */
+ * Converts an XML schema file to the specified DTD version.
+ *
+ * Call this method to convert the specified XML schema file to a different AXMLS
+ * DTD version. For instance, to convert a schema created for an pre-1.0 version for
+ * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
+ * parameter is specified, the schema will be converted to the current DTD version.
+ * If the newFile parameter is provided, the converted schema will be written to the specified
+ * file.
+ * @see ConvertSchemaString()
+ *
+ * @param string $filename Name of XML schema file that will be converted.
+ * @param string $newVersion DTD version to convert to.
+ * @param string $newFile File name of (converted) output file.
+ * @return string Converted XML schema or FALSE if an error occurs.
+ */
function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
// grab current version
@@ -1757,7 +1742,7 @@ class adoSchema {
}
if( $version == $newVersion ) {
- $result = _file_get_contents( $filename );
+ $result = file_get_contents( $filename );
// remove unicode BOM if present
if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
@@ -1796,7 +1781,7 @@ class adoSchema {
return FALSE;
}
- $schema = _file_get_contents( $schema );
+ $schema = file_get_contents( $schema );
break;
case 'string':
default:
@@ -1807,14 +1792,14 @@ class adoSchema {
$arguments = array (
'/_xml' => $schema,
- '/_xsl' => _file_get_contents( $xsl_file )
+ '/_xsl' => file_get_contents( $xsl_file )
);
// create an XSLT processor
$xh = xslt_create ();
// set error handler
- xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
+ xslt_set_error_handler ($xh, array ($this, 'xslt_error_handler'));
// process the schema
$result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
@@ -1825,15 +1810,15 @@ class adoSchema {
}
/**
- * Processes XSLT transformation errors
- *
- * @param object $parser XML parser object
- * @param integer $errno Error number
- * @param integer $level Error level
- * @param array $fields Error information fields
- *
- * @access private
- */
+ * Processes XSLT transformation errors
+ *
+ * @param object $parser XML parser object
+ * @param integer $errno Error number
+ * @param integer $level Error level
+ * @param array $fields Error information fields
+ *
+ * @access private
+ */
function xslt_error_handler( $parser, $errno, $level, $fields ) {
if( is_array( $fields ) ) {
$msg = array(
@@ -1878,14 +1863,14 @@ class adoSchema {
}
/**
- * Returns the AXMLS Schema Version of the requested XML schema file.
- *
- * Call this method to obtain the AXMLS DTD version of the requested XML schema file.
- * @see SchemaStringVersion()
- *
- * @param string $filename AXMLS schema file
- * @return string Schema version number or FALSE on error
- */
+ * Returns the AXMLS Schema Version of the requested XML schema file.
+ *
+ * Call this method to obtain the AXMLS DTD version of the requested XML schema file.
+ * @see SchemaStringVersion()
+ *
+ * @param string $filename AXMLS schema file
+ * @return string Schema version number or FALSE on error
+ */
function SchemaFileVersion( $filename ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
@@ -1904,14 +1889,14 @@ class adoSchema {
}
/**
- * Returns the AXMLS Schema Version of the provided XML schema string.
- *
- * Call this method to obtain the AXMLS DTD version of the provided XML schema string.
- * @see SchemaFileVersion()
- *
- * @param string $xmlstring XML schema string
- * @return string Schema version number or FALSE on error
- */
+ * Returns the AXMLS Schema Version of the provided XML schema string.
+ *
+ * Call this method to obtain the AXMLS DTD version of the provided XML schema string.
+ * @see SchemaFileVersion()
+ *
+ * @param string $xmlstring XML schema string
+ * @return string Schema version number or FALSE on error
+ */
function SchemaStringVersion( $xmlstring ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
@@ -1925,15 +1910,15 @@ class adoSchema {
}
/**
- * Extracts an XML schema from an existing database.
- *
- * Call this method to create an XML schema string from an existing database.
- * If the data parameter is set to TRUE, AXMLS will include the data from the database
- * in the schema.
- *
- * @param boolean $data Include data in schema dump
- * @return string Generated XML schema
- */
+ * Extracts an XML schema from an existing database.
+ *
+ * Call this method to create an XML schema string from an existing database.
+ * If the data parameter is set to TRUE, AXMLS will include the data from the database
+ * in the schema.
+ *
+ * @param boolean $data Include data in schema dump
+ * @return string Generated XML schema
+ */
function ExtractSchema( $data = FALSE ) {
$old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
@@ -2032,15 +2017,15 @@ class adoSchema {
}
/**
- * Sets a prefix for database objects
- *
- * Call this method to set a standard prefix that will be prepended to all database tables
- * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
- *
- * @param string $prefix Prefix that will be prepended.
- * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
- * @return boolean TRUE if successful, else FALSE
- */
+ * Sets a prefix for database objects
+ *
+ * Call this method to set a standard prefix that will be prepended to all database tables
+ * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
+ *
+ * @param string $prefix Prefix that will be prepended.
+ * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
+ * @return boolean TRUE if successful, else FALSE
+ */
function SetPrefix( $prefix = '', $underscore = TRUE ) {
switch( TRUE ) {
// clear prefix
@@ -2067,13 +2052,13 @@ class adoSchema {
}
/**
- * Returns an object name with the current prefix prepended.
- *
- * @param string $name Name
- * @return string Prefixed name
- *
- * @access private
- */
+ * Returns an object name with the current prefix prepended.
+ *
+ * @param string $name Name
+ * @return string Prefixed name
+ *
+ * @access private
+ */
function prefix( $name = '' ) {
// if prefix is set
if( !empty( $this->objectPrefix ) ) {
@@ -2087,13 +2072,13 @@ class adoSchema {
}
/**
- * Checks if element references a specific platform
- *
- * @param string $platform Requested platform
- * @returns boolean TRUE if platform check succeeds
- *
- * @access private
- */
+ * Checks if element references a specific platform
+ *
+ * @param string $platform Requested platform
+ * @returns boolean TRUE if platform check succeeds
+ *
+ * @access private
+ */
function supportedPlatform( $platform = NULL ) {
$regex = '/^(\w*\|)*' . $this->db->databaseType . '(\|\w*)*$/';
@@ -2107,22 +2092,22 @@ class adoSchema {
}
/**
- * Clears the array of generated SQL.
- *
- * @access private
- */
+ * Clears the array of generated SQL.
+ *
+ * @access private
+ */
function clearSQL() {
$this->sqlArray = array();
}
/**
- * Adds SQL into the SQL array.
- *
- * @param mixed $sql SQL to Add
- * @return boolean TRUE if successful, else FALSE.
- *
- * @access private
- */
+ * Adds SQL into the SQL array.
+ *
+ * @param mixed $sql SQL to Add
+ * @return boolean TRUE if successful, else FALSE.
+ *
+ * @access private
+ */
function addSQL( $sql = NULL ) {
if( is_array( $sql ) ) {
foreach( $sql as $line ) {
@@ -2158,13 +2143,13 @@ class adoSchema {
}
/**
- * Gets the SQL array in the specified format.
- *
- * @param string $format Format
- * @return mixed SQL
- *
- * @access private
- */
+ * Gets the SQL array in the specified format.
+ *
+ * @param string $format Format
+ * @return mixed SQL
+ *
+ * @access private
+ */
function getSQL( $format = NULL, $sqlArray = NULL ) {
if( !is_array( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
@@ -2186,19 +2171,19 @@ class adoSchema {
}
/**
- * Destroys an adoSchema object.
- *
- * Call this method to clean up after an adoSchema object that is no longer in use.
- * @deprecated adoSchema now cleans up automatically.
- */
+ * Destroys an adoSchema object.
+ *
+ * Call this method to clean up after an adoSchema object that is no longer in use.
+ * @deprecated adoSchema now cleans up automatically.
+ */
function Destroy() {}
}
/**
-* Message logging function
-*
-* @access private
-*/
+ * Message logging function
+ *
+ * @access private
+ */
function logMsg( $msg, $title = NULL, $force = FALSE ) {
if( XMLS_DEBUG or $force ) {
echo '
';
diff --git a/lib/adodb/adodb-xmlschema03.inc.php b/lib/adodb/adodb-xmlschema03.inc.php
index de1ea26c7d6..a03386b3cc3 100644
--- a/lib/adodb/adodb-xmlschema03.inc.php
+++ b/lib/adodb/adodb-xmlschema03.inc.php
@@ -26,74 +26,60 @@
* @author Dan Cech
*/
-function _file_get_contents($file)
-{
- if (function_exists('file_get_contents')) return file_get_contents($file);
-
- $f = fopen($file,'r');
- if (!$f) return '';
- $t = '';
-
- while ($s = fread($f,100000)) $t .= $s;
- fclose($f);
- return $t;
-}
-
-
/**
-* Debug on or off
-*/
+ * Debug on or off
+ */
if( !defined( 'XMLS_DEBUG' ) ) {
define( 'XMLS_DEBUG', FALSE );
}
/**
-* Default prefix key
-*/
+ * Default prefix key
+ */
if( !defined( 'XMLS_PREFIX' ) ) {
define( 'XMLS_PREFIX', '%%P' );
}
/**
-* Maximum length allowed for object prefix
-*/
+ * Maximum length allowed for object prefix
+ */
if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
define( 'XMLS_PREFIX_MAXLEN', 10 );
}
/**
-* Execute SQL inline as it is generated
-*/
+ * Execute SQL inline as it is generated
+ */
if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
define( 'XMLS_EXECUTE_INLINE', FALSE );
}
/**
-* Continue SQL Execution if an error occurs?
-*/
+ * Continue SQL Execution if an error occurs?
+ */
if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
}
/**
-* Current Schema Version
-*/
+ * Current Schema Version
+ */
if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
define( 'XMLS_SCHEMA_VERSION', '0.3' );
}
/**
-* Default Schema Version. Used for Schemas without an explicit version set.
-*/
+ * Default Schema Version. Used for Schemas without an explicit version set.
+ */
if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
}
/**
-* How to handle data rows that already exist in a database during and upgrade.
-* Options are INSERT (attempts to insert duplicate rows), UPDATE (updates existing
-* rows) and IGNORE (ignores existing rows).
-*/
+ * How to handle data rows that already exist in a database during and upgrade.
+ * Options are INSERT (attempts to insert duplicate rows), UPDATE (updates existing
+ * rows) and IGNORE (ignores existing rows).
+ */
if( !defined( 'XMLS_MODE_INSERT' ) ) {
define( 'XMLS_MODE_INSERT', 0 );
}
@@ -108,69 +94,69 @@ if( !defined( 'XMLS_EXISTING_DATA' ) ) {
}
/**
-* Default Schema Version. Used for Schemas without an explicit version set.
-*/
+ * Default Schema Version. Used for Schemas without an explicit version set.
+ */
if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
}
/**
-* Include the main ADODB library
-*/
+ * Include the main ADODB library
+ */
if( !defined( '_ADODB_LAYER' ) ) {
require( 'adodb.inc.php' );
require( 'adodb-datadict.inc.php' );
}
/**
-* Abstract DB Object. This class provides basic methods for database objects, such
-* as tables and indexes.
-*
-* @package axmls
-* @access private
-*/
+ * Abstract DB Object. This class provides basic methods for database objects, such
+ * as tables and indexes.
+ *
+ * @package axmls
+ * @access private
+ */
class dbObject {
/**
- * var object Parent
- */
+ * var object Parent
+ */
var $parent;
/**
- * var string current element
- */
+ * var string current element
+ */
var $currentElement;
/**
- * NOP
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * NOP
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
}
/**
- * XML Callback to process start elements
- *
- * @access private
- */
+ * XML Callback to process start elements
+ *
+ * @access private
+ */
function _tag_open( $parser, $tag, $attributes ) {
}
/**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * @access private
+ */
function _tag_cdata( $parser, $cdata ) {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( $parser, $tag ) {
}
@@ -180,117 +166,117 @@ class dbObject {
}
/**
- * Destroys the object
- */
+ * Destroys the object
+ */
function destroy() {
}
/**
- * Checks whether the specified RDBMS is supported by the current
- * database object or its ranking ancestor.
- *
- * @param string $platform RDBMS platform name (from ADODB platform list).
- * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
- */
+ * Checks whether the specified RDBMS is supported by the current
+ * database object or its ranking ancestor.
+ *
+ * @param string $platform RDBMS platform name (from ADODB platform list).
+ * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
+ */
function supportedPlatform( $platform = NULL ) {
return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
}
/**
- * Returns the prefix set by the ranking ancestor of the database object.
- *
- * @param string $name Prefix string.
- * @return string Prefix.
- */
+ * Returns the prefix set by the ranking ancestor of the database object.
+ *
+ * @param string $name Prefix string.
+ * @return string Prefix.
+ */
function prefix( $name = '' ) {
return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
}
/**
- * Extracts a field ID from the specified field.
- *
- * @param string $field Field.
- * @return string Field ID.
- */
+ * Extracts a field ID from the specified field.
+ *
+ * @param string $field Field.
+ * @return string Field ID.
+ */
function fieldID( $field ) {
return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
}
}
/**
-* Creates a table object in ADOdb's datadict format
-*
-* This class stores information about a database table. As charactaristics
-* of the table are loaded from the external source, methods and properties
-* of this class are used to build up the table description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
+ * Creates a table object in ADOdb's datadict format
+ *
+ * This class stores information about a database table. As charactaristics
+ * of the table are loaded from the external source, methods and properties
+ * of this class are used to build up the table description in ADOdb's
+ * datadict format.
+ *
+ * @package axmls
+ * @access private
+ */
class dbTable extends dbObject {
/**
- * @var string Table name
- */
+ * @var string Table name
+ */
var $name;
/**
- * @var array Field specifier: Meta-information about each field
- */
+ * @var array Field specifier: Meta-information about each field
+ */
var $fields = array();
/**
- * @var array List of table indexes.
- */
+ * @var array List of table indexes.
+ */
var $indexes = array();
/**
- * @var array Table options: Table-level options
- */
+ * @var array Table options: Table-level options
+ */
var $opts = array();
/**
- * @var string Field index: Keeps track of which field is currently being processed
- */
+ * @var string Field index: Keeps track of which field is currently being processed
+ */
var $current_field;
/**
- * @var boolean Mark table for destruction
- * @access private
- */
+ * @var boolean Mark table for destruction
+ * @access private
+ */
var $drop_table;
/**
- * @var boolean Mark field for destruction (not yet implemented)
- * @access private
- */
+ * @var boolean Mark field for destruction (not yet implemented)
+ * @access private
+ */
var $drop_field = array();
/**
- * @var array Platform-specific options
- * @access private
- */
+ * @var array Platform-specific options
+ * @access private
+ */
var $currentPlatform = true;
/**
- * Iniitializes a new table object.
- *
- * @param string $prefix DB Object prefix
- * @param array $attributes Array of table attributes.
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * Iniitializes a new table object.
+ *
+ * @param string $prefix DB Object prefix
+ * @param array $attributes Array of table attributes.
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
$this->name = $this->prefix($attributes['NAME']);
}
/**
- * XML Callback to process start elements. Elements currently
- * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT.
- *
- * @access private
- */
+ * XML Callback to process start elements. Elements currently
+ * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT.
+ *
+ * @access private
+ */
function _tag_open( $parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
@@ -349,10 +335,10 @@ class dbTable extends dbObject {
}
/**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * @access private
+ */
function _tag_cdata( $parser, $cdata ) {
switch( $this->currentElement ) {
// Table or field comment
@@ -385,10 +371,10 @@ class dbTable extends dbObject {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( $parser, $tag ) {
$this->currentElement = '';
@@ -411,11 +397,11 @@ class dbTable extends dbObject {
}
/**
- * Adds an index to a table object
- *
- * @param array $attributes Index attributes
- * @return object dbIndex object
- */
+ * Adds an index to a table object
+ *
+ * @param array $attributes Index attributes
+ * @return object dbIndex object
+ */
function addIndex( $attributes ) {
$name = strtoupper( $attributes['NAME'] );
$this->indexes[$name] = new dbIndex( $this, $attributes );
@@ -423,11 +409,11 @@ class dbTable extends dbObject {
}
/**
- * Adds data to a table object
- *
- * @param array $attributes Data attributes
- * @return object dbData object
- */
+ * Adds data to a table object
+ *
+ * @param array $attributes Data attributes
+ * @return object dbData object
+ */
function addData( $attributes ) {
if( !isset( $this->data ) ) {
$this->data = new dbData( $this, $attributes );
@@ -436,34 +422,34 @@ class dbTable extends dbObject {
}
/**
- * Adds a field to a table object
- *
- * $name is the name of the table to which the field should be added.
- * $type is an ADODB datadict field type. The following field types
- * are supported as of ADODB 3.40:
- * - C: varchar
- * - X: CLOB (character large object) or largest varchar size
- * if CLOB is not supported
- * - C2: Multibyte varchar
- * - X2: Multibyte CLOB
- * - B: BLOB (binary large object)
- * - D: Date (some databases do not support this, and we return a datetime type)
- * - T: Datetime or Timestamp
- * - L: Integer field suitable for storing booleans (0 or 1)
- * - I: Integer (mapped to I4)
- * - I1: 1-byte integer
- * - I2: 2-byte integer
- * - I4: 4-byte integer
- * - I8: 8-byte integer
- * - F: Floating point number
- * - N: Numeric or decimal number
- *
- * @param string $name Name of the table to which the field will be added.
- * @param string $type ADODB datadict field type.
- * @param string $size Field size
- * @param array $opts Field options array
- * @return array Field specifier array
- */
+ * Adds a field to a table object
+ *
+ * $name is the name of the table to which the field should be added.
+ * $type is an ADODB datadict field type. The following field types
+ * are supported as of ADODB 3.40:
+ * - C: varchar
+ * - X: CLOB (character large object) or largest varchar size
+ * if CLOB is not supported
+ * - C2: Multibyte varchar
+ * - X2: Multibyte CLOB
+ * - B: BLOB (binary large object)
+ * - D: Date (some databases do not support this, and we return a datetime type)
+ * - T: Datetime or Timestamp
+ * - L: Integer field suitable for storing booleans (0 or 1)
+ * - I: Integer (mapped to I4)
+ * - I1: 1-byte integer
+ * - I2: 2-byte integer
+ * - I4: 4-byte integer
+ * - I8: 8-byte integer
+ * - F: Floating point number
+ * - N: Numeric or decimal number
+ *
+ * @param string $name Name of the table to which the field will be added.
+ * @param string $type ADODB datadict field type.
+ * @param string $size Field size
+ * @param array $opts Field options array
+ * @return array Field specifier array
+ */
function addField( $name, $type, $size = NULL, $opts = NULL ) {
$field_id = $this->fieldID( $name );
@@ -490,16 +476,16 @@ class dbTable extends dbObject {
}
/**
- * Adds a field option to the current field specifier
- *
- * This method adds a field option allowed by the ADOdb datadict
- * and appends it to the given field.
- *
- * @param string $field Field name
- * @param string $opt ADOdb field option
- * @param mixed $value Field option value
- * @return array Field specifier array
- */
+ * Adds a field option to the current field specifier
+ *
+ * This method adds a field option allowed by the ADOdb datadict
+ * and appends it to the given field.
+ *
+ * @param string $field Field name
+ * @param string $opt ADOdb field option
+ * @param mixed $value Field option value
+ * @return array Field specifier array
+ */
function addFieldOpt( $field, $opt, $value = NULL ) {
if( $this->currentPlatform ) {
if( !isset( $value ) ) {
@@ -512,14 +498,14 @@ class dbTable extends dbObject {
}
/**
- * Adds an option to the table
- *
- * This method takes a comma-separated list of table-level options
- * and appends them to the table object.
- *
- * @param string $opt Table option
- * @return array Options
- */
+ * Adds an option to the table
+ *
+ * This method takes a comma-separated list of table-level options
+ * and appends them to the table object.
+ *
+ * @param string $opt Table option
+ * @return array Options
+ */
function addTableOpt( $opt ) {
if(isset($this->currentPlatform)) {
$this->opts[$this->parent->db->dataProvider] = $opt;
@@ -533,11 +519,11 @@ class dbTable extends dbObject {
}
/**
- * Generates the SQL that will create the table in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing table creation SQL
- */
+ * Generates the SQL that will create the table in the database
+ *
+ * @param object $xmls adoSchema object
+ * @return array Array containing table creation SQL
+ */
function create( &$xmls ) {
$sql = array();
@@ -599,8 +585,11 @@ class dbTable extends dbObject {
// Option has an argument.
if( is_array( $opt ) ) {
$key = key( $opt );
- $value = $opt[key( $opt )];
- @$fldarray[$field_id][$key] .= $value;
+ $value = $opt[$key];
+ if(!isset($fldarray[$field_id][$key])) {
+ $fldarray[$field_id][$key] = "";
+ }
+ $fldarray[$field_id][$key] .= $value;
// Option doesn't have arguments
} else {
$fldarray[$field_id][$opt] = $opt;
@@ -645,8 +634,8 @@ class dbTable extends dbObject {
}
/**
- * Marks a field or table for destruction
- */
+ * Marks a field or table for destruction
+ */
function drop() {
if( isset( $this->current_field ) ) {
// Drop the current field
@@ -663,61 +652,61 @@ class dbTable extends dbObject {
}
/**
-* Creates an index object in ADOdb's datadict format
-*
-* This class stores information about a database index. As charactaristics
-* of the index are loaded from the external source, methods and properties
-* of this class are used to build up the index description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
+ * Creates an index object in ADOdb's datadict format
+ *
+ * This class stores information about a database index. As charactaristics
+ * of the index are loaded from the external source, methods and properties
+ * of this class are used to build up the index description in ADOdb's
+ * datadict format.
+ *
+ * @package axmls
+ * @access private
+ */
class dbIndex extends dbObject {
/**
- * @var string Index name
- */
+ * @var string Index name
+ */
var $name;
/**
- * @var array Index options: Index-level options
- */
+ * @var array Index options: Index-level options
+ */
var $opts = array();
/**
- * @var array Indexed fields: Table columns included in this index
- */
+ * @var array Indexed fields: Table columns included in this index
+ */
var $columns = array();
/**
- * @var boolean Mark index for destruction
- * @access private
- */
+ * @var boolean Mark index for destruction
+ * @access private
+ */
var $drop = FALSE;
/**
- * Initializes the new dbIndex object.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- *
- * @internal
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * Initializes the new dbIndex object.
+ *
+ * @param object $parent Parent object
+ * @param array $attributes Attributes
+ *
+ * @internal
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
$this->name = $this->prefix ($attributes['NAME']);
}
/**
- * XML Callback to process start elements
- *
- * Processes XML opening tags.
- * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
- *
- * @access private
- */
+ * XML Callback to process start elements
+ *
+ * Processes XML opening tags.
+ * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
+ *
+ * @access private
+ */
function _tag_open( $parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
@@ -739,12 +728,12 @@ class dbIndex extends dbObject {
}
/**
- * XML Callback to process CDATA elements
- *
- * Processes XML cdata.
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * Processes XML cdata.
+ *
+ * @access private
+ */
function _tag_cdata( $parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
@@ -757,10 +746,10 @@ class dbIndex extends dbObject {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( $parser, $tag ) {
$this->currentElement = '';
@@ -772,11 +761,11 @@ class dbIndex extends dbObject {
}
/**
- * Adds a field to the index
- *
- * @param string $name Field name
- * @return string Field list
- */
+ * Adds a field to the index
+ *
+ * @param string $name Field name
+ * @return string Field list
+ */
function addField( $name ) {
$this->columns[$this->fieldID( $name )] = $name;
@@ -785,11 +774,11 @@ class dbIndex extends dbObject {
}
/**
- * Adds options to the index
- *
- * @param string $opt Comma-separated list of index options.
- * @return string Option list
- */
+ * Adds options to the index
+ *
+ * @param string $opt Comma-separated list of index options.
+ * @return string Option list
+ */
function addIndexOpt( $opt ) {
$this->opts[] = $opt;
@@ -798,11 +787,11 @@ class dbIndex extends dbObject {
}
/**
- * Generates the SQL that will create the index in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing index creation SQL
- */
+ * Generates the SQL that will create the index in the database
+ *
+ * @param object $xmls adoSchema object
+ * @return array Array containing index creation SQL
+ */
function create( &$xmls ) {
if( $this->drop ) {
return NULL;
@@ -819,22 +808,22 @@ class dbIndex extends dbObject {
}
/**
- * Marks an index for destruction
- */
+ * Marks an index for destruction
+ */
function drop() {
$this->drop = TRUE;
}
}
/**
-* Creates a data object in ADOdb's datadict format
-*
-* This class stores information about table data, and is called
-* when we need to load field data into a table.
-*
-* @package axmls
-* @access private
-*/
+ * Creates a data object in ADOdb's datadict format
+ *
+ * This class stores information about table data, and is called
+ * when we need to load field data into a table.
+ *
+ * @package axmls
+ * @access private
+ */
class dbData extends dbObject {
var $data = array();
@@ -842,25 +831,25 @@ class dbData extends dbObject {
var $row;
/**
- * Initializes the new dbData object.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- *
- * @internal
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * Initializes the new dbData object.
+ *
+ * @param object $parent Parent object
+ * @param array $attributes Attributes
+ *
+ * @internal
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
}
/**
- * XML Callback to process start elements
- *
- * Processes XML opening tags.
- * Elements currently processed are: ROW and F (field).
- *
- * @access private
- */
+ * XML Callback to process start elements
+ *
+ * Processes XML opening tags.
+ * Elements currently processed are: ROW and F (field).
+ *
+ * @access private
+ */
function _tag_open( $parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
@@ -877,12 +866,12 @@ class dbData extends dbObject {
}
/**
- * XML Callback to process CDATA elements
- *
- * Processes XML cdata.
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * Processes XML cdata.
+ *
+ * @access private
+ */
function _tag_cdata( $parser, $cdata ) {
switch( $this->currentElement ) {
// Index field name
@@ -895,10 +884,10 @@ class dbData extends dbObject {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( $parser, $tag ) {
$this->currentElement = '';
@@ -910,11 +899,11 @@ class dbData extends dbObject {
}
/**
- * Adds a field to the insert
- *
- * @param string $name Field name
- * @return string Field list
- */
+ * Adds a field to the insert
+ *
+ * @param string $name Field name
+ * @return string Field list
+ */
function addField( $attributes ) {
// check we're in a valid row
if( !isset( $this->row ) || !isset( $this->data[$this->row] ) ) {
@@ -935,11 +924,11 @@ class dbData extends dbObject {
}
/**
- * Adds options to the index
- *
- * @param string $opt Comma-separated list of index options.
- * @return string Option list
- */
+ * Adds options to the index
+ *
+ * @param string $opt Comma-separated list of index options.
+ * @return string Option list
+ */
function addData( $cdata ) {
// check we're in a valid field
if ( isset( $this->data[$this->row][$this->current_field] ) ) {
@@ -949,11 +938,11 @@ class dbData extends dbObject {
}
/**
- * Generates the SQL that will add/update the data in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing index creation SQL
- */
+ * Generates the SQL that will add/update the data in the database
+ *
+ * @param object $xmls adoSchema object
+ * @return array Array containing index creation SQL
+ */
function create( &$xmls ) {
$table = $xmls->dict->tableName($this->parent->name);
$table_field_count = count($this->parent->fields);
@@ -976,7 +965,8 @@ class dbData extends dbObject {
foreach( $row as $field_id => $field_data ) {
if( !array_key_exists( $field_id, $table_fields ) ) {
if( is_numeric( $field_id ) ) {
- $field_id = reset( array_keys( $table_fields ) );
+ $keys = array_keys($table_fields);
+ $field_id = reset($keys);
} else {
continue;
}
@@ -1072,40 +1062,40 @@ class dbData extends dbObject {
}
/**
-* Creates the SQL to execute a list of provided SQL queries
-*
-* @package axmls
-* @access private
-*/
+ * Creates the SQL to execute a list of provided SQL queries
+ *
+ * @package axmls
+ * @access private
+ */
class dbQuerySet extends dbObject {
/**
- * @var array List of SQL queries
- */
+ * @var array List of SQL queries
+ */
var $queries = array();
/**
- * @var string String used to build of a query line by line
- */
+ * @var string String used to build of a query line by line
+ */
var $query;
/**
- * @var string Query prefix key
- */
+ * @var string Query prefix key
+ */
var $prefixKey = '';
/**
- * @var boolean Auto prefix enable (TRUE)
- */
+ * @var boolean Auto prefix enable (TRUE)
+ */
var $prefixMethod = 'AUTO';
/**
- * Initializes the query set.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- */
- function __construct( &$parent, $attributes = NULL ) {
+ * Initializes the query set.
+ *
+ * @param object $parent Parent object
+ * @param array $attributes Attributes
+ */
+ function __construct( $parent, $attributes = NULL ) {
$this->parent = $parent;
// Overrides the manual prefix key
@@ -1130,11 +1120,11 @@ class dbQuerySet extends dbObject {
}
/**
- * XML Callback to process start elements. Elements currently
- * processed are: QUERY.
- *
- * @access private
- */
+ * XML Callback to process start elements. Elements currently
+ * processed are: QUERY.
+ *
+ * @access private
+ */
function _tag_open( $parser, $tag, $attributes ) {
$this->currentElement = strtoupper( $tag );
@@ -1155,8 +1145,8 @@ class dbQuerySet extends dbObject {
}
/**
- * XML Callback to process CDATA elements
- */
+ * XML Callback to process CDATA elements
+ */
function _tag_cdata( $parser, $cdata ) {
switch( $this->currentElement ) {
// Line of queryset SQL data
@@ -1169,10 +1159,10 @@ class dbQuerySet extends dbObject {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ */
function _tag_close( $parser, $tag ) {
$this->currentElement = '';
@@ -1192,10 +1182,10 @@ class dbQuerySet extends dbObject {
}
/**
- * Re-initializes the query.
- *
- * @return boolean TRUE
- */
+ * Re-initializes the query.
+ *
+ * @return boolean TRUE
+ */
function newQuery() {
$this->query = '';
@@ -1203,10 +1193,10 @@ class dbQuerySet extends dbObject {
}
/**
- * Discards the existing query.
- *
- * @return boolean TRUE
- */
+ * Discards the existing query.
+ *
+ * @return boolean TRUE
+ */
function discardQuery() {
unset( $this->query );
@@ -1214,11 +1204,11 @@ class dbQuerySet extends dbObject {
}
/**
- * Appends a line to a query that is being built line by line
- *
- * @param string $data Line of SQL data or NULL to initialize a new query
- * @return string SQL query string.
- */
+ * Appends a line to a query that is being built line by line
+ *
+ * @param string $data Line of SQL data or NULL to initialize a new query
+ * @return string SQL query string.
+ */
function buildQuery( $sql = NULL ) {
if( !isset( $this->query ) OR empty( $sql ) ) {
return FALSE;
@@ -1230,10 +1220,10 @@ class dbQuerySet extends dbObject {
}
/**
- * Adds a completed query to the query list
- *
- * @return string SQL of added query
- */
+ * Adds a completed query to the query list
+ *
+ * @return string SQL of added query
+ */
function addQuery() {
if( !isset( $this->query ) ) {
return FALSE;
@@ -1247,11 +1237,11 @@ class dbQuerySet extends dbObject {
}
/**
- * Creates and returns the current query set
- *
- * @param object $xmls adoSchema object
- * @return array Query set
- */
+ * Creates and returns the current query set
+ *
+ * @param object $xmls adoSchema object
+ * @return array Query set
+ */
function create( &$xmls ) {
foreach( $this->queries as $id => $query ) {
switch( $this->prefixMethod ) {
@@ -1287,13 +1277,13 @@ class dbQuerySet extends dbObject {
}
/**
- * Rebuilds the query with the prefix attached to any objects
- *
- * @param string $regex Regex used to add prefix
- * @param string $query SQL query string
- * @param string $prefix Prefix to be appended to tables, indices, etc.
- * @return string Prefixed SQL query string.
- */
+ * Rebuilds the query with the prefix attached to any objects
+ *
+ * @param string $regex Regex used to add prefix
+ * @param string $query SQL query string
+ * @param string $prefix Prefix to be appended to tables, indices, etc.
+ * @return string Prefixed SQL query string.
+ */
function prefixQuery( $regex, $query, $prefix = NULL ) {
if( !isset( $prefix ) ) {
return $query;
@@ -1323,103 +1313,103 @@ class dbQuerySet extends dbObject {
}
/**
-* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
-*
-* This class is used to load and parse the XML file, to create an array of SQL statements
-* that can be used to build a database, and to build the database using the SQL array.
-*
-* @tutorial getting_started.pkg
-*
-* @author Richard Tango-Lowy & Dan Cech
-* @version $Revision: 1.62 $
-*
-* @package axmls
-*/
+ * Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
+ *
+ * This class is used to load and parse the XML file, to create an array of SQL statements
+ * that can be used to build a database, and to build the database using the SQL array.
+ *
+ * @tutorial getting_started.pkg
+ *
+ * @author Richard Tango-Lowy & Dan Cech
+ * @version 1.62
+ *
+ * @package axmls
+ */
class adoSchema {
/**
- * @var array Array containing SQL queries to generate all objects
- * @access private
- */
+ * @var array Array containing SQL queries to generate all objects
+ * @access private
+ */
var $sqlArray;
/**
- * @var object ADOdb connection object
- * @access private
- */
+ * @var object ADOdb connection object
+ * @access private
+ */
var $db;
/**
- * @var object ADOdb Data Dictionary
- * @access private
- */
+ * @var object ADOdb Data Dictionary
+ * @access private
+ */
var $dict;
/**
- * @var string Current XML element
- * @access private
- */
+ * @var string Current XML element
+ * @access private
+ */
var $currentElement = '';
/**
- * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
- * @access private
- */
+ * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
+ * @access private
+ */
var $upgrade = '';
/**
- * @var string Optional object prefix
- * @access private
- */
+ * @var string Optional object prefix
+ * @access private
+ */
var $objectPrefix = '';
/**
- * @var long System debug
- * @access private
- */
+ * @var long System debug
+ * @access private
+ */
var $debug;
/**
- * @var string Regular expression to find schema version
- * @access private
- */
+ * @var string Regular expression to find schema version
+ * @access private
+ */
var $versionRegex = '//';
/**
- * @var string Current schema version
- * @access private
- */
+ * @var string Current schema version
+ * @access private
+ */
var $schemaVersion;
/**
- * @var int Success of last Schema execution
- */
+ * @var int Success of last Schema execution
+ */
var $success;
/**
- * @var bool Execute SQL inline as it is generated
- */
+ * @var bool Execute SQL inline as it is generated
+ */
var $executeInline;
/**
- * @var bool Continue SQL execution if errors occur
- */
+ * @var bool Continue SQL execution if errors occur
+ */
var $continueOnError;
/**
- * @var int How to handle existing data rows (insert, update, or ignore)
- */
+ * @var int How to handle existing data rows (insert, update, or ignore)
+ */
var $existingData;
/**
- * Creates an adoSchema object
- *
- * Creating an adoSchema object is the first step in processing an XML schema.
- * The only parameter is an ADOdb database connection object, which must already
- * have been created.
- *
- * @param object $db ADOdb database connection object.
- */
+ * Creates an adoSchema object
+ *
+ * Creating an adoSchema object is the first step in processing an XML schema.
+ * The only parameter is an ADOdb database connection object, which must already
+ * have been created.
+ *
+ * @param object $db ADOdb database connection object.
+ */
function __construct( $db ) {
$this->db = $db;
$this->debug = $this->db->debug;
@@ -1433,21 +1423,21 @@ class adoSchema {
}
/**
- * Sets the method to be used for upgrading an existing database
- *
- * Use this method to specify how existing database objects should be upgraded.
- * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
- * alter each database object directly, REPLACE attempts to rebuild each object
- * from scratch, BEST attempts to determine the best upgrade method for each
- * object, and NONE disables upgrading.
- *
- * This method is not yet used by AXMLS, but exists for backward compatibility.
- * The ALTER method is automatically assumed when the adoSchema object is
- * instantiated; other upgrade methods are not currently supported.
- *
- * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
- * @returns string Upgrade method used
- */
+ * Sets the method to be used for upgrading an existing database
+ *
+ * Use this method to specify how existing database objects should be upgraded.
+ * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
+ * alter each database object directly, REPLACE attempts to rebuild each object
+ * from scratch, BEST attempts to determine the best upgrade method for each
+ * object, and NONE disables upgrading.
+ *
+ * This method is not yet used by AXMLS, but exists for backward compatibility.
+ * The ALTER method is automatically assumed when the adoSchema object is
+ * instantiated; other upgrade methods are not currently supported.
+ *
+ * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
+ * @returns string Upgrade method used
+ */
function setUpgradeMethod( $method = '' ) {
if( !is_string( $method ) ) {
return FALSE;
@@ -1478,24 +1468,24 @@ class adoSchema {
}
/**
- * Specifies how to handle existing data row when there is a unique key conflict.
- *
- * The existingData setting specifies how the parser should handle existing rows
- * when a unique key violation occurs during the insert. This can happen when inserting
- * data into an existing table with one or more primary keys or unique indexes.
- * The existingData method takes one of three options: XMLS_MODE_INSERT attempts
- * to always insert the data as a new row. In the event of a unique key violation,
- * the database will generate an error. XMLS_MODE_UPDATE attempts to update the
- * any existing rows with the new data based upon primary or unique key fields in
- * the schema. If the data row in the schema specifies no unique fields, the row
- * data will be inserted as a new row. XMLS_MODE_IGNORE specifies that any data rows
- * that would result in a unique key violation be ignored; no inserts or updates will
- * take place. For backward compatibility, the default setting is XMLS_MODE_INSERT,
- * but XMLS_MODE_UPDATE will generally be the most appropriate setting.
- *
- * @param int $mode XMLS_MODE_INSERT, XMLS_MODE_UPDATE, or XMLS_MODE_IGNORE
- * @return int current mode
- */
+ * Specifies how to handle existing data row when there is a unique key conflict.
+ *
+ * The existingData setting specifies how the parser should handle existing rows
+ * when a unique key violation occurs during the insert. This can happen when inserting
+ * data into an existing table with one or more primary keys or unique indexes.
+ * The existingData method takes one of three options: XMLS_MODE_INSERT attempts
+ * to always insert the data as a new row. In the event of a unique key violation,
+ * the database will generate an error. XMLS_MODE_UPDATE attempts to update the
+ * any existing rows with the new data based upon primary or unique key fields in
+ * the schema. If the data row in the schema specifies no unique fields, the row
+ * data will be inserted as a new row. XMLS_MODE_IGNORE specifies that any data rows
+ * that would result in a unique key violation be ignored; no inserts or updates will
+ * take place. For backward compatibility, the default setting is XMLS_MODE_INSERT,
+ * but XMLS_MODE_UPDATE will generally be the most appropriate setting.
+ *
+ * @param int $mode XMLS_MODE_INSERT, XMLS_MODE_UPDATE, or XMLS_MODE_IGNORE
+ * @return int current mode
+ */
function existingData( $mode = NULL ) {
if( is_int( $mode ) ) {
switch( $mode ) {
@@ -1519,18 +1509,19 @@ class adoSchema {
}
/**
- * Enables/disables inline SQL execution.
- *
- * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
- * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
- * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
- * to apply the schema to the database.
- *
- * @param bool $mode execute
- * @return bool current execution mode
- *
- * @see ParseSchema(), ExecuteSchema()
- */
+ * Enables/disables inline SQL execution.
+ *
+ * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
+ * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
+ * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
+ * to apply the schema to the database.
+ *
+ * @param bool $mode execute
+ * @return bool current execution mode
+ *
+ * @see ParseSchema()
+ * @see ExecuteSchema()
+ */
function executeInline( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->executeInline = $mode;
@@ -1540,18 +1531,19 @@ class adoSchema {
}
/**
- * Enables/disables SQL continue on error.
- *
- * Call this method to enable or disable continuation of SQL execution if an error occurs.
- * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
- * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
- * of the schema will continue.
- *
- * @param bool $mode execute
- * @return bool current continueOnError mode
- *
- * @see addSQL(), ExecuteSchema()
- */
+ * Enables/disables SQL continue on error.
+ *
+ * Call this method to enable or disable continuation of SQL execution if an error occurs.
+ * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
+ * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
+ * of the schema will continue.
+ *
+ * @param bool $mode execute
+ * @return bool current continueOnError mode
+ *
+ * @see addSQL()
+ * @see ExecuteSchema()
+ */
function continueOnError( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->continueOnError = $mode;
@@ -1561,43 +1553,44 @@ class adoSchema {
}
/**
- * Loads an XML schema from a file and converts it to SQL.
- *
- * Call this method to load the specified schema (see the DTD for the proper format) from
- * the filesystem and generate the SQL necessary to create the database
- * described. This method automatically converts the schema to the latest
- * axmls schema version.
- * @see ParseSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute
- */
+ * Loads an XML schema from a file and converts it to SQL.
+ *
+ * Call this method to load the specified schema (see the DTD for the proper format) from
+ * the filesystem and generate the SQL necessary to create the database
+ * described. This method automatically converts the schema to the latest
+ * axmls schema version.
+ * @see ParseSchemaString()
+ *
+ * @param string $file Name of XML schema file.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute
+ */
function parseSchema( $filename, $returnSchema = FALSE ) {
return $this->parseSchemaString( $this->convertSchemaFile( $filename ), $returnSchema );
}
/**
- * Loads an XML schema from a file and converts it to SQL.
- *
- * Call this method to load the specified schema directly from a file (see
- * the DTD for the proper format) and generate the SQL necessary to create
- * the database described by the schema. Use this method when you are dealing
- * with large schema files. Otherwise, parseSchema() is faster.
- * This method does not automatically convert the schema to the latest axmls
- * schema version. You must convert the schema manually using either the
- * convertSchemaFile() or convertSchemaString() method.
- * @see parseSchema()
- * @see convertSchemaFile()
- * @see convertSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- *
- * @deprecated Replaced by adoSchema::parseSchema() and adoSchema::parseSchemaString()
- * @see parseSchema(), parseSchemaString()
- */
+ * Loads an XML schema from a file and converts it to SQL.
+ *
+ * Call this method to load the specified schema directly from a file (see
+ * the DTD for the proper format) and generate the SQL necessary to create
+ * the database described by the schema. Use this method when you are dealing
+ * with large schema files. Otherwise, parseSchema() is faster.
+ * This method does not automatically convert the schema to the latest axmls
+ * schema version. You must convert the schema manually using either the
+ * convertSchemaFile() or convertSchemaString() method.
+ * @see parseSchema()
+ * @see convertSchemaFile()
+ * @see convertSchemaString()
+ *
+ * @param string $file Name of XML schema file.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute.
+ *
+ * @deprecated Replaced by adoSchema::parseSchema() and adoSchema::parseSchemaString()
+ * @see parseSchema()
+ * @see parseSchemaString()
+ */
function parseSchemaFile( $filename, $returnSchema = FALSE ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
@@ -1640,16 +1633,16 @@ class adoSchema {
}
/**
- * Converts an XML schema string to SQL.
- *
- * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
- * and generate the SQL necessary to create the database described by the schema.
- * @see parseSchema()
- *
- * @param string $xmlstring XML schema string.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- */
+ * Converts an XML schema string to SQL.
+ *
+ * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
+ * and generate the SQL necessary to create the database described by the schema.
+ * @see parseSchema()
+ *
+ * @param string $xmlstring XML schema string.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute.
+ */
function parseSchemaString( $xmlstring, $returnSchema = FALSE ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
logMsg( 'Empty or Invalid Schema' );
@@ -1684,31 +1677,31 @@ class adoSchema {
}
/**
- * Loads an XML schema from a file and converts it to uninstallation SQL.
- *
- * Call this method to load the specified schema (see the DTD for the proper format) from
- * the filesystem and generate the SQL necessary to remove the database described.
- * @see RemoveSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute
- */
+ * Loads an XML schema from a file and converts it to uninstallation SQL.
+ *
+ * Call this method to load the specified schema (see the DTD for the proper format) from
+ * the filesystem and generate the SQL necessary to remove the database described.
+ * @see RemoveSchemaString()
+ *
+ * @param string $file Name of XML schema file.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute
+ */
function removeSchema( $filename, $returnSchema = FALSE ) {
return $this->removeSchemaString( $this->convertSchemaFile( $filename ), $returnSchema );
}
/**
- * Converts an XML schema string to uninstallation SQL.
- *
- * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
- * and generate the SQL necessary to uninstall the database described by the schema.
- * @see removeSchema()
- *
- * @param string $schema XML schema string.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- */
+ * Converts an XML schema string to uninstallation SQL.
+ *
+ * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
+ * and generate the SQL necessary to uninstall the database described by the schema.
+ * @see removeSchema()
+ *
+ * @param string $schema XML schema string.
+ * @param bool $returnSchema Return schema rather than parsing.
+ * @return array Array of SQL queries, ready to execute.
+ */
function removeSchemaString( $schema, $returnSchema = FALSE ) {
// grab current version
@@ -1720,18 +1713,20 @@ class adoSchema {
}
/**
- * Applies the current XML schema to the database (post execution).
- *
- * Call this method to apply the current schema (generally created by calling
- * parseSchema() or parseSchemaString() ) to the database (creating the tables, indexes,
- * and executing other SQL specified in the schema) after parsing.
- * @see parseSchema(), parseSchemaString(), executeInline()
- *
- * @param array $sqlArray Array of SQL statements that will be applied rather than
- * the current schema.
- * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
- * @returns integer 0 if failure, 1 if errors, 2 if successful.
- */
+ * Applies the current XML schema to the database (post execution).
+ *
+ * Call this method to apply the current schema (generally created by calling
+ * parseSchema() or parseSchemaString() ) to the database (creating the tables, indexes,
+ * and executing other SQL specified in the schema) after parsing.
+ * @see parseSchema()
+ * @see parseSchemaString()
+ * @see executeInline()
+ *
+ * @param array $sqlArray Array of SQL statements that will be applied rather than
+ * the current schema.
+ * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
+ * @returns integer 0 if failure, 1 if errors, 2 if successful.
+ */
function executeSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
if( !is_bool( $continueOnErr ) ) {
$continueOnErr = $this->continueOnError();
@@ -1751,28 +1746,28 @@ class adoSchema {
}
/**
- * Returns the current SQL array.
- *
- * Call this method to fetch the array of SQL queries resulting from
- * parseSchema() or parseSchemaString().
- *
- * @param string $format Format: HTML, TEXT, or NONE (PHP array)
- * @return array Array of SQL statements or FALSE if an error occurs
- */
+ * Returns the current SQL array.
+ *
+ * Call this method to fetch the array of SQL queries resulting from
+ * parseSchema() or parseSchemaString().
+ *
+ * @param string $format Format: HTML, TEXT, or NONE (PHP array)
+ * @return array Array of SQL statements or FALSE if an error occurs
+ */
function printSQL( $format = 'NONE' ) {
$sqlArray = null;
return $this->getSQL( $format, $sqlArray );
}
/**
- * Saves the current SQL array to the local filesystem as a list of SQL queries.
- *
- * Call this method to save the array of SQL queries (generally resulting from a
- * parsed XML schema) to the filesystem.
- *
- * @param string $filename Path and name where the file should be saved.
- * @return boolean TRUE if save is successful, else FALSE.
- */
+ * Saves the current SQL array to the local filesystem as a list of SQL queries.
+ *
+ * Call this method to save the array of SQL queries (generally resulting from a
+ * parsed XML schema) to the filesystem.
+ *
+ * @param string $filename Path and name where the file should be saved.
+ * @return boolean TRUE if save is successful, else FALSE.
+ */
function saveSQL( $filename = './schema.sql' ) {
if( !isset( $sqlArray ) ) {
@@ -1791,12 +1786,12 @@ class adoSchema {
}
/**
- * Create an xml parser
- *
- * @return object PHP XML parser object
- *
- * @access private
- */
+ * Create an xml parser
+ *
+ * @return object PHP XML parser object
+ *
+ * @access private
+ */
function create_parser() {
// Create the parser
$xmlParser = xml_parser_create();
@@ -1810,10 +1805,10 @@ class adoSchema {
}
/**
- * XML Callback to process start elements
- *
- * @access private
- */
+ * XML Callback to process start elements
+ *
+ * @access private
+ */
function _tag_open( $parser, $tag, $attributes ) {
switch( strtoupper( $tag ) ) {
case 'TABLE':
@@ -1835,39 +1830,39 @@ class adoSchema {
}
/**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
+ * XML Callback to process CDATA elements
+ *
+ * @access private
+ */
function _tag_cdata( $parser, $cdata ) {
}
/**
- * XML Callback to process end elements
- *
- * @access private
- * @internal
- */
+ * XML Callback to process end elements
+ *
+ * @access private
+ * @internal
+ */
function _tag_close( $parser, $tag ) {
}
/**
- * Converts an XML schema string to the specified DTD version.
- *
- * Call this method to convert a string containing an XML schema to a different AXMLS
- * DTD version. For instance, to convert a schema created for an pre-1.0 version for
- * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
- * parameter is specified, the schema will be converted to the current DTD version.
- * If the newFile parameter is provided, the converted schema will be written to the specified
- * file.
- * @see convertSchemaFile()
- *
- * @param string $schema String containing XML schema that will be converted.
- * @param string $newVersion DTD version to convert to.
- * @param string $newFile File name of (converted) output file.
- * @return string Converted XML schema or FALSE if an error occurs.
- */
+ * Converts an XML schema string to the specified DTD version.
+ *
+ * Call this method to convert a string containing an XML schema to a different AXMLS
+ * DTD version. For instance, to convert a schema created for an pre-1.0 version for
+ * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
+ * parameter is specified, the schema will be converted to the current DTD version.
+ * If the newFile parameter is provided, the converted schema will be written to the specified
+ * file.
+ * @see convertSchemaFile()
+ *
+ * @param string $schema String containing XML schema that will be converted.
+ * @param string $newVersion DTD version to convert to.
+ * @param string $newFile File name of (converted) output file.
+ * @return string Converted XML schema or FALSE if an error occurs.
+ */
function convertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
// grab current version
@@ -1893,30 +1888,22 @@ class adoSchema {
return $result;
}
- /*
- // compat for pre-4.3 - jlim
- function _file_get_contents($path)
- {
- if (function_exists('file_get_contents')) return file_get_contents($path);
- return join('',file($path));
- }*/
-
/**
- * Converts an XML schema file to the specified DTD version.
- *
- * Call this method to convert the specified XML schema file to a different AXMLS
- * DTD version. For instance, to convert a schema created for an pre-1.0 version for
- * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
- * parameter is specified, the schema will be converted to the current DTD version.
- * If the newFile parameter is provided, the converted schema will be written to the specified
- * file.
- * @see convertSchemaString()
- *
- * @param string $filename Name of XML schema file that will be converted.
- * @param string $newVersion DTD version to convert to.
- * @param string $newFile File name of (converted) output file.
- * @return string Converted XML schema or FALSE if an error occurs.
- */
+ * Converts an XML schema file to the specified DTD version.
+ *
+ * Call this method to convert the specified XML schema file to a different AXMLS
+ * DTD version. For instance, to convert a schema created for an pre-1.0 version for
+ * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
+ * parameter is specified, the schema will be converted to the current DTD version.
+ * If the newFile parameter is provided, the converted schema will be written to the specified
+ * file.
+ * @see convertSchemaString()
+ *
+ * @param string $filename Name of XML schema file that will be converted.
+ * @param string $newVersion DTD version to convert to.
+ * @param string $newFile File name of (converted) output file.
+ * @return string Converted XML schema or FALSE if an error occurs.
+ */
function convertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
// grab current version
@@ -1929,7 +1916,7 @@ class adoSchema {
}
if( $version == $newVersion ) {
- $result = _file_get_contents( $filename );
+ $result = file_get_contents( $filename );
// remove unicode BOM if present
if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
@@ -1968,7 +1955,7 @@ class adoSchema {
return FALSE;
}
- $schema = _file_get_contents( $schema );
+ $schema = file_get_contents( $schema );
break;
case 'string':
default:
@@ -1979,14 +1966,14 @@ class adoSchema {
$arguments = array (
'/_xml' => $schema,
- '/_xsl' => _file_get_contents( $xsl_file )
+ '/_xsl' => file_get_contents( $xsl_file )
);
// create an XSLT processor
$xh = xslt_create ();
// set error handler
- xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
+ xslt_set_error_handler ($xh, array ($this, 'xslt_error_handler'));
// process the schema
$result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
@@ -1997,15 +1984,15 @@ class adoSchema {
}
/**
- * Processes XSLT transformation errors
- *
- * @param object $parser XML parser object
- * @param integer $errno Error number
- * @param integer $level Error level
- * @param array $fields Error information fields
- *
- * @access private
- */
+ * Processes XSLT transformation errors
+ *
+ * @param object $parser XML parser object
+ * @param integer $errno Error number
+ * @param integer $level Error level
+ * @param array $fields Error information fields
+ *
+ * @access private
+ */
function xslt_error_handler( $parser, $errno, $level, $fields ) {
if( is_array( $fields ) ) {
$msg = array(
@@ -2050,14 +2037,14 @@ class adoSchema {
}
/**
- * Returns the AXMLS Schema Version of the requested XML schema file.
- *
- * Call this method to obtain the AXMLS DTD version of the requested XML schema file.
- * @see SchemaStringVersion()
- *
- * @param string $filename AXMLS schema file
- * @return string Schema version number or FALSE on error
- */
+ * Returns the AXMLS Schema Version of the requested XML schema file.
+ *
+ * Call this method to obtain the AXMLS DTD version of the requested XML schema file.
+ * @see SchemaStringVersion()
+ *
+ * @param string $filename AXMLS schema file
+ * @return string Schema version number or FALSE on error
+ */
function schemaFileVersion( $filename ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
@@ -2076,14 +2063,14 @@ class adoSchema {
}
/**
- * Returns the AXMLS Schema Version of the provided XML schema string.
- *
- * Call this method to obtain the AXMLS DTD version of the provided XML schema string.
- * @see SchemaFileVersion()
- *
- * @param string $xmlstring XML schema string
- * @return string Schema version number or FALSE on error
- */
+ * Returns the AXMLS Schema Version of the provided XML schema string.
+ *
+ * Call this method to obtain the AXMLS DTD version of the provided XML schema string.
+ * @see SchemaFileVersion()
+ *
+ * @param string $xmlstring XML schema string
+ * @return string Schema version number or FALSE on error
+ */
function schemaStringVersion( $xmlstring ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
@@ -2097,18 +2084,18 @@ class adoSchema {
}
/**
- * Extracts an XML schema from an existing database.
- *
- * Call this method to create an XML schema string from an existing database.
- * If the data parameter is set to TRUE, AXMLS will include the data from the database
- * tables in the schema.
- *
- * @param boolean $data include data in schema dump
- * @param string $indent indentation to use
- * @param string $prefix extract only tables with given prefix
- * @param boolean $stripprefix strip prefix string when storing in XML schema
- * @return string Generated XML schema
- */
+ * Extracts an XML schema from an existing database.
+ *
+ * Call this method to create an XML schema string from an existing database.
+ * If the data parameter is set to TRUE, AXMLS will include the data from the database
+ * tables in the schema.
+ *
+ * @param boolean $data include data in schema dump
+ * @param string $indent indentation to use
+ * @param string $prefix extract only tables with given prefix
+ * @param boolean $stripprefix strip prefix string when storing in XML schema
+ * @return string Generated XML schema
+ */
function extractSchema( $data = FALSE, $indent = ' ', $prefix = '' , $stripprefix=false) {
$old_mode = $this->db->setFetchMode( ADODB_FETCH_NUM );
@@ -2217,15 +2204,15 @@ class adoSchema {
}
/**
- * Sets a prefix for database objects
- *
- * Call this method to set a standard prefix that will be prepended to all database tables
- * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
- *
- * @param string $prefix Prefix that will be prepended.
- * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
- * @return boolean TRUE if successful, else FALSE
- */
+ * Sets a prefix for database objects
+ *
+ * Call this method to set a standard prefix that will be prepended to all database tables
+ * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
+ *
+ * @param string $prefix Prefix that will be prepended.
+ * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
+ * @return boolean TRUE if successful, else FALSE
+ */
function setPrefix( $prefix = '', $underscore = TRUE ) {
switch( TRUE ) {
// clear prefix
@@ -2252,13 +2239,13 @@ class adoSchema {
}
/**
- * Returns an object name with the current prefix prepended.
- *
- * @param string $name Name
- * @return string Prefixed name
- *
- * @access private
- */
+ * Returns an object name with the current prefix prepended.
+ *
+ * @param string $name Name
+ * @return string Prefixed name
+ *
+ * @access private
+ */
function prefix( $name = '' ) {
// if prefix is set
if( !empty( $this->objectPrefix ) ) {
@@ -2272,13 +2259,13 @@ class adoSchema {
}
/**
- * Checks if element references a specific platform
- *
- * @param string $platform Requested platform
- * @returns boolean TRUE if platform check succeeds
- *
- * @access private
- */
+ * Checks if element references a specific platform
+ *
+ * @param string $platform Requested platform
+ * @returns boolean TRUE if platform check succeeds
+ *
+ * @access private
+ */
function supportedPlatform( $platform = NULL ) {
if( !empty( $platform ) ) {
$regex = '/(^|\|)' . $this->db->databaseType . '(\||$)/i';
@@ -2301,22 +2288,22 @@ class adoSchema {
}
/**
- * Clears the array of generated SQL.
- *
- * @access private
- */
+ * Clears the array of generated SQL.
+ *
+ * @access private
+ */
function clearSQL() {
$this->sqlArray = array();
}
/**
- * Adds SQL into the SQL array.
- *
- * @param mixed $sql SQL to Add
- * @return boolean TRUE if successful, else FALSE.
- *
- * @access private
- */
+ * Adds SQL into the SQL array.
+ *
+ * @param mixed $sql SQL to Add
+ * @return boolean TRUE if successful, else FALSE.
+ *
+ * @access private
+ */
function addSQL( $sql = NULL ) {
if( is_array( $sql ) ) {
foreach( $sql as $line ) {
@@ -2352,13 +2339,13 @@ class adoSchema {
}
/**
- * Gets the SQL array in the specified format.
- *
- * @param string $format Format
- * @return mixed SQL
- *
- * @access private
- */
+ * Gets the SQL array in the specified format.
+ *
+ * @param string $format Format
+ * @return mixed SQL
+ *
+ * @access private
+ */
function getSQL( $format = NULL, $sqlArray = NULL ) {
if( !is_array( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
@@ -2380,20 +2367,20 @@ class adoSchema {
}
/**
- * Destroys an adoSchema object.
- *
- * Call this method to clean up after an adoSchema object that is no longer in use.
- * @deprecated adoSchema now cleans up automatically.
- */
+ * Destroys an adoSchema object.
+ *
+ * Call this method to clean up after an adoSchema object that is no longer in use.
+ * @deprecated adoSchema now cleans up automatically.
+ */
function destroy() {
}
}
/**
-* Message logging function
-*
-* @access private
-*/
+ * Message logging function
+ *
+ * @access private
+ */
function logMsg( $msg, $title = NULL, $force = FALSE ) {
if( XMLS_DEBUG or $force ) {
echo '
';
diff --git a/lib/adodb/adodb.inc.php b/lib/adodb/adodb.inc.php
index 3d5d1ad3c78..7ed8242b0db 100644
--- a/lib/adodb/adodb.inc.php
+++ b/lib/adodb/adodb.inc.php
@@ -70,19 +70,19 @@ if (!defined('_ADODB_LAYER')) {
//==============================================================================================
/*********************************************************
- * Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3).
- * Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi
- * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:adodb_force_type
- *
- * 0 = ignore empty fields. All empty fields in array are ignored.
- * 1 = force null. All empty, php null and string 'null' fields are
- * changed to sql NULL values.
- * 2 = force empty. All empty, php null and string 'null' fields are
- * changed to sql empty '' or 0 values.
- * 3 = force value. Value is left as it is. Php null and string 'null'
- * are set to sql NULL values and empty fields '' are set to empty '' sql values.
- * 4 = force value. Like 1 but numeric empty fields are set to zero.
- */
+ * Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3).
+ * Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:adodb_force_type
+ *
+ * 0 = ignore empty fields. All empty fields in array are ignored.
+ * 1 = force null. All empty, php null and string 'null' fields are
+ * changed to sql NULL values.
+ * 2 = force empty. All empty, php null and string 'null' fields are
+ * changed to sql empty '' or 0 values.
+ * 3 = force value. Value is left as it is. Php null and string 'null'
+ * are set to sql NULL values and empty fields '' are set to empty '' sql values.
+ * 4 = force value. Like 1 but numeric empty fields are set to zero.
+ */
define('ADODB_FORCE_IGNORE',0);
define('ADODB_FORCE_NULL',1);
define('ADODB_FORCE_EMPTY',2);
@@ -99,10 +99,10 @@ if (!defined('_ADODB_LAYER')) {
define ('ADODB_STRINGMAX_NOLIMIT',-2);
/*
- * Defines the the default meta type returned
- * when ADOdb encounters a type that it is not
- * defined in the metaTypes.
- */
+ * Defines the the default meta type returned
+ * when ADOdb encounters a type that it is not
+ * defined in the metaTypes.
+ */
if (!defined('ADODB_DEFAULT_METATYPE'))
define ('ADODB_DEFAULT_METATYPE','N');
@@ -198,7 +198,7 @@ if (!defined('_ADODB_LAYER')) {
/**
* ADODB version as a string.
*/
- $ADODB_vers = 'v5.21.4 2022-01-22';
+ $ADODB_vers = 'v5.22.2 2022-05-08';
/**
* Determines whether recordset->RecordCount() is used.
@@ -240,12 +240,25 @@ if (!defined('_ADODB_LAYER')) {
}
+ /**
+ * Parse date string to prevent injection attack.
+ *
+ * @param string $s
+ *
+ * @return string
+ */
function _adodb_safedate($s) {
return str_replace(array("'", '\\'), '', $s);
}
- // parse date string to prevent injection attack
- // date string will have one quote at beginning e.g. '3434343'
+ /**
+ * Parse date string to prevent injection attack.
+ * Date string will have one quote at beginning e.g. '3434343'
+ *
+ * @param string $s
+ *
+ * @return string
+ */
function _adodb_safedateq($s) {
$len = strlen($s);
if ($s[0] !== "'") {
@@ -269,9 +282,17 @@ if (!defined('_ADODB_LAYER')) {
return strlen($s2) == 0 ? 'null' : $s2;
}
-
- // for transaction handling
-
+ /**
+ * For transaction handling.
+ *
+ * @param $dbms
+ * @param $fn
+ * @param $errno
+ * @param $errmsg
+ * @param $p1
+ * @param $p2
+ * @param $thisConnection
+ */
function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) {
//print "Errorno ($fn errno=$errno m=$errmsg) ";
$thisConnection->_transOK = false;
@@ -281,8 +302,9 @@ if (!defined('_ADODB_LAYER')) {
}
}
- //------------------
- // class for caching
+ /**
+ * Class ADODB_Cache_File
+ */
class ADODB_Cache_File {
var $createdir = true; // requires creation of temp dirs
@@ -294,18 +316,42 @@ if (!defined('_ADODB_LAYER')) {
}
}
- // write serialised recordset to cache item/file
- function writecache($filename, $contents, $debug, $secs2cache) {
+ /**
+ * Write serialised RecordSet to cache item/file.
+ *
+ * @param $filename
+ * @param $contents
+ * @param $debug
+ * @param $secs2cache
+ *
+ * @return bool|int
+ */
+ function writecache($filename, $contents, $debug, $secs2cache) {
return adodb_write_file($filename, $contents,$debug);
}
- // load serialised recordset and unserialise it
+ /**
+ * load serialised RecordSet and unserialise it
+ *
+ * @param $filename
+ * @param $err
+ * @param $secs2cache
+ * @param $rsClass
+ *
+ * @return ADORecordSet
+ */
function &readcache($filename, &$err, $secs2cache, $rsClass) {
$rs = csv2rs($filename,$err,$secs2cache,$rsClass);
return $rs;
}
- // flush all items in cache
+ /**
+ * Flush all items in cache.
+ *
+ * @param bool $debug
+ *
+ * @return bool|void
+ */
function flushall($debug=false) {
global $ADODB_CACHE_DIR;
@@ -320,7 +366,12 @@ if (!defined('_ADODB_LAYER')) {
return $rez;
}
- // flush one file in cache
+ /**
+ * Flush one file in cache.
+ *
+ * @param string $f
+ * @param bool $debug
+ */
function flushcache($f, $debug=false) {
if (!@unlink($f)) {
if ($debug) {
@@ -329,6 +380,11 @@ if (!defined('_ADODB_LAYER')) {
}
}
+ /**
+ * @param string $hash
+ *
+ * @return string
+ */
function getdirname($hash) {
global $ADODB_CACHE_DIR;
if (!isset($this->notSafeMode)) {
@@ -337,7 +393,14 @@ if (!defined('_ADODB_LAYER')) {
return ($this->notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($hash,0,2) : $ADODB_CACHE_DIR;
}
- // create temp directories
+ /**
+ * Create temp directories.
+ *
+ * @param string $hash
+ * @param bool $debug
+ *
+ * @return string
+ */
function createdir($hash, $debug) {
global $ADODB_CACHE_PERMS;
@@ -396,6 +459,12 @@ if (!defined('_ADODB_LAYER')) {
var $dataProvider = 'native';
var $databaseType = ''; /// RDBMS currently in use, eg. odbc, mysql, mssql
var $database = ''; /// Name of database to be used.
+
+ /**
+ * @var string If the driver is PDO, then the dsnType is e.g. sqlsrv, otherwise empty
+ */
+ public $dsnType = '';
+
var $host = ''; /// The hostname of the database server
var $port = ''; /// The port of the database server
var $user = ''; /// The username which is used to connect to the database server.
@@ -440,11 +509,47 @@ if (!defined('_ADODB_LAYER')) {
var $isoDates = false; /// accepts dates in ISO format
var $cacheSecs = 3600; /// cache for 1 hour
- // memcache
- var $memCache = false; /// should we use memCache instead of caching in files
- var $memCacheHost; /// memCache host
- var $memCachePort = 11211; /// memCache port
- var $memCacheCompress = false; /// Use 'true' to store the item compressed (uses zlib, not supported w/memcached library)
+ /*****************************************
+ * memcached server options
+ ******************************************/
+
+ /**
+ * Use memCache library instead of caching in files.
+ * @var bool $memCache
+ */
+ public $memCache = false;
+
+ /**
+ * The memcache server(s) to connect to. Can be defined as:
+ * - a single host name/ip address
+ * - a list of hosts/ip addresses
+ * - an array of server connection data (weighted server groups).
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:userguide:memcached
+ * @var string|array $memCacheHost
+ */
+ public $memCacheHost;
+
+ /**
+ * Default port number.
+ * The default port can be overridden if memcache server connection data
+ * is provided as an array {@see $memCacheHost}.
+ * @var int $memCachePort
+ */
+ public $memCachePort = 11211;
+
+ /**
+ * Enable compression of stored items.
+ * @var bool $memCacheCompress
+ */
+ public $memCacheCompress = false;
+
+ /**
+ * An array of memcached options.
+ * Only used with memcached; memcache ignores this setting.
+ * @link https://www.php.net/manual/en/memcached.constants.php
+ * @var array $memCacheOptions
+ */
+ public $memCacheOptions = array();
var $sysDate = false; /// name of function that returns the current date
var $sysTimeStamp = false; /// name of function that returns the current timestamp
@@ -512,6 +617,23 @@ if (!defined('_ADODB_LAYER')) {
*/
protected $connectionParameters = array();
+ /*
+ * A simple associative array of user-defined custom actual/meta types
+ */
+ public $customActualTypes = array();
+
+ /*
+ * An array of user-defined custom meta/actual types.
+ * $this->customMetaTypes[$meta] = array(
+ * 'actual'=>'',
+ * 'dictionary'=>'',
+ * 'handler'=>'',
+ * 'callback'=>''
+ * );
+ */
+ public $customMetaTypes = array();
+
+
/**
* Default Constructor.
* We define it even though it does not actually do anything. This avoids
@@ -572,11 +694,54 @@ if (!defined('_ADODB_LAYER')) {
return $matches[1];
}
+ /**
+ * Set a custom meta type with a corresponding actual
+ *
+ * @param string $metaType The Custom ADOdb metatype
+ * @param string $dictionaryType The database dictionary type
+ * @param string $actualType The database actual type
+ * @param bool $handleAsType handle like an existing Metatype
+ * @param mixed $callBack A pre-processing function
+ *
+ * @return bool success if the actual exists
+ */
+ final public function setCustomMetaType(
+ $metaType,
+ $dictionaryType,
+ $actualType,
+ $handleAsType=false,
+ $callback=false){
+
+ $this->customMetaTypes[strtoupper($metaType)] = array(
+ 'actual'=>$actualType,
+ 'dictionary'=>strtoupper($dictionaryType),
+ 'handler'=>$handleAsType,
+ 'callback'=>$callback
+ );
+
+ /*
+ * Create a reverse lookup for the actualType
+ */
+ $this->customActualTypes[$actualType] = $metaType;
+
+ return true;
+ }
+
+ /**
+ * Get a list of custom meta types.
+ *
+ * @return string[]
+ */
+ final public function getCustomMetaTypes()
+ {
+ return $this->customMetaTypes;
+ }
+
+
/**
* Get server version info.
*
- * @return string[] An array with 2 elements: $arr['string'] is the description string,
- * and $arr[version] is the version (also a string).
+ * @return string[] Array with 2 string elements: version and description
*/
function ServerInfo() {
return array('description' => '', 'version' => '');
@@ -591,6 +756,13 @@ if (!defined('_ADODB_LAYER')) {
return !empty($this->_connectionID);
}
+ /**
+ * Find version string.
+ *
+ * @param string $str
+ *
+ * @return string
+ */
function _findvers($str) {
if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) {
return $arr[1];
@@ -729,6 +901,16 @@ if (!defined('_ADODB_LAYER')) {
return false;
}
+ /**
+ * Always force a new connection to database.
+ *
+ * @param string $argHostname Host to connect to
+ * @param string $argUsername Userid to login
+ * @param string $argPassword Associated password
+ * @param string $argDatabaseName Database name
+ *
+ * @return bool
+ */
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) {
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName);
}
@@ -807,7 +989,13 @@ if (!defined('_ADODB_LAYER')) {
return $ret;
}
- function outp_throw($msg,$src='WARN',$sql='') {
+ /**
+ * Throw an exception if the handler is defined or prints the message if not.
+ * @param string $msg Message
+ * @param string $src the name of the calling function (in uppercase)
+ * @param string $sql Optional offending SQL statement
+ */
+ function outp_throw($msg, $src='WARN', $sql='') {
if (defined('ADODB_ERROR_HANDLER') && ADODB_ERROR_HANDLER == 'adodb_throw') {
adodb_throw($this->databaseType,$src,-9999,$msg,$sql,false,$this);
return;
@@ -843,6 +1031,8 @@ if (!defined('_ADODB_LAYER')) {
*
* @param string $fmt Format string
* @param string $col Date column; use system date if not specified.
+ *
+ * @return string
*/
function SQLDate($fmt, $col = '') {
if (!$col) {
@@ -852,14 +1042,14 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * Prepare an sql statement and return the statement resource.
+ * Prepare an SQL statement and return the statement resource.
*
- * For databases that do not support this, we return the $sql. To ensure
- * compatibility with databases that do not support prepare:
+ * For databases that do not support prepared statements, we return the
+ * provided SQL statement as-is, to ensure compatibility:
*
- * $stmt = $db->Prepare("insert into table (id, name) values (?,?)");
- * $db->Execute($stmt,array(1,'Jill')) or die('insert failed');
- * $db->Execute($stmt,array(2,'Joe')) or die('insert failed');
+ * $stmt = $db->prepare("insert into table (id, name) values (?,?)");
+ * $db->execute($stmt, array(1,'Jill')) or die('insert failed');
+ * $db->execute($stmt, array(2,'Joe')) or die('insert failed');
*
* @param string $sql SQL to send to database
*
@@ -870,6 +1060,17 @@ if (!defined('_ADODB_LAYER')) {
return $sql;
}
+ /**
+ * Releases a previously prepared statement.
+ *
+ * @param mixed $stmt Statement resource, as returned by {@see prepare()}
+ *
+ * @return bool
+ */
+ function releaseStatement(&$stmt) {
+ return true;
+ }
+
/**
* Prepare a Stored Procedure and return the statement resource.
*
@@ -897,6 +1098,12 @@ if (!defined('_ADODB_LAYER')) {
return $this->qstr($s);
}
+ /**
+ * Quotes a string so that all strings are escaped.
+ * Wrapper for qstr with magic_quotes = false.
+ *
+ * @param string &$s
+ */
function q(&$s) {
//if (!empty($this->qNull && $s == 'null') {
// return $s;
@@ -905,8 +1112,9 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * PEAR DB Compat - do not use internally.
- */
+ * PEAR DB Compat - do not use internally.
+ * @return int
+ */
function ErrorNative() {
return $this->ErrorNo();
}
@@ -914,18 +1122,23 @@ if (!defined('_ADODB_LAYER')) {
/**
* PEAR DB Compat - do not use internally.
+ * @param string $seq_name
+ * @return int
*/
function nextId($seq_name) {
return $this->GenID($seq_name);
}
/**
- * Lock a row, will escalate and lock the table if row locking not supported
- * will normally free the lock at the end of the transaction
+ * Lock a row.
+ * Will escalate and lock the table if row locking is not supported.
+ * Will normally free the lock at the end of the transaction.
*
- * @param string $table name of table to lock
- * @param string $where where clause to use, eg: "WHERE row=12". If left empty, will escalate to table lock
- * @param string $col
+ * @param string $table name of table to lock
+ * @param string $where where clause to use, eg: "WHERE row=12". If left empty, will escalate to table lock
+ * @param string $col
+ *
+ * @return bool
*/
function RowLock($table,$where,$col='1 as adodbignore') {
return false;
@@ -948,15 +1161,15 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * PEAR DB Compat - do not use internally.
- *
- * The fetch modes for NUMERIC and ASSOC for PEAR DB and ADODB are identical
- * for easy porting :-)
- *
- * @param int $mode The fetchmode ADODB_FETCH_ASSOC or ADODB_FETCH_NUM
- *
- * @return int Previous fetch mode
- */
+ * PEAR DB Compat - do not use internally.
+ *
+ * The fetch modes for NUMERIC and ASSOC for PEAR DB and ADODB are identical
+ * for easy porting :-)
+ *
+ * @param int $mode The fetchmode ADODB_FETCH_ASSOC or ADODB_FETCH_NUM
+ *
+ * @return int Previous fetch mode
+ */
function SetFetchMode($mode) {
$old = $this->fetchMode;
$this->fetchMode = $mode;
@@ -968,15 +1181,14 @@ if (!defined('_ADODB_LAYER')) {
return $old;
}
-
/**
- * PEAR DB Compat - do not use internally.
+ * PEAR DB Compat - do not use internally.
*
* @param string $sql
* @param array|bool $inputarr
*
* @return ADORecordSet|bool
- */
+ */
function Query($sql, $inputarr=false) {
$rs = $this->Execute($sql, $inputarr);
if (!$rs && defined('ADODB_PEAR')) {
@@ -985,7 +1197,6 @@ if (!defined('_ADODB_LAYER')) {
return $rs;
}
-
/**
* PEAR DB Compat - do not use internally
*/
@@ -1026,36 +1237,54 @@ if (!defined('_ADODB_LAYER')) {
return '?';
}
- /*
- InParameter and OutParameter are self-documenting versions of Parameter().
- */
- function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) {
+ /**
+ * Self-documenting version of Parameter().
+ *
+ * @param $stmt
+ * @param &$var
+ * @param $name
+ * @param int $maxLen
+ * @param bool $type
+ *
+ * @return bool
+ */
+ function InParameter(&$stmt, &$var, $name, $maxLen=4000, $type=false) {
return $this->Parameter($stmt,$var,$name,false,$maxLen,$type);
}
- /*
- */
+ /**
+ * Self-documenting version of Parameter().
+ *
+ * @param $stmt
+ * @param $var
+ * @param $name
+ * @param int $maxLen
+ * @param bool $type
+ *
+ * @return bool
+ */
function OutParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) {
return $this->Parameter($stmt,$var,$name,true,$maxLen,$type);
}
-
- /*
- Usage in oracle
- $stmt = $db->Prepare('select * from table where id =:myid and group=:group');
- $db->Parameter($stmt,$id,'myid');
- $db->Parameter($stmt,$group,'group',64);
- $db->Execute();
-
- @param $stmt Statement returned by Prepare() or 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.
-
- */
+ /**
+ *
+ * Usage in oracle
+ * $stmt = $db->Prepare('select * from table where id =:myid and group=:group');
+ * $db->Parameter($stmt,$id,'myid');
+ * $db->Parameter($stmt,$group,'group',64);
+ * $db->Execute();
+ *
+ * @param mixed &$stmt Statement returned by Prepare() or PrepareSP().
+ * @param mixed &$var PHP variable to bind to
+ * @param string $name Name of stored procedure variable name to bind to.
+ * @param int|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.
+ *
+ * @return bool
+ */
function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) {
return false;
}
@@ -1102,13 +1331,16 @@ if (!defined('_ADODB_LAYER')) {
/**
- Used together with StartTrans() to end a transaction. Monitors connection
- for sql errors, and will commit or rollback as appropriate.
-
- @autoComplete if true, monitor sql errors and commit and rollback as appropriate,
- and if set to false force rollback even if no SQL error detected.
- @returns true on commit, false on rollback.
- */
+ * Complete a transation.
+ *
+ * Used together with StartTrans() to end a transaction. Monitors connection
+ * for sql errors, and will commit or rollback as appropriate.
+ *
+ * @param bool autoComplete if true, monitor sql errors and commit and
+ * rollback as appropriate, and if set to false
+ * force rollback even if no SQL error detected.
+ * @returns true on commit, false on rollback.
+ */
function CompleteTrans($autoComplete = true) {
if ($this->transOff > 1) {
$this->transOff -= 1;
@@ -1132,16 +1364,16 @@ if (!defined('_ADODB_LAYER')) {
$this->_transOK = false;
$this->RollbackTrans();
if ($this->debug) {
- ADOCOnnection::outp("Smart Rollback occurred");
+ ADOConnection::outp("Smart Rollback occurred");
}
}
return $this->_transOK;
}
- /*
- At the end of a StartTrans/CompleteTrans block, perform a rollback.
- */
+ /**
+ * At the end of a StartTrans/CompleteTrans block, perform a rollback.
+ */
function FailTrans() {
if ($this->debug)
if ($this->transOff == 0) {
@@ -1154,8 +1386,8 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- Check if transaction has failed, only for Smart Transactions.
- */
+ * Check if transaction has failed, only for Smart Transactions.
+ */
function HasFailedTrans() {
if ($this->transOff > 0) {
return $this->_transOK == false;
@@ -1496,8 +1728,8 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * @return # rows affected by UPDATE/DELETE
- */
+ * @return int|false Number of rows affected by UPDATE/DELETE
+ */
function Affected_Rows() {
if ($this->hasAffectedRows) {
if ($this->fnExecute === 'adodb_log_sql') {
@@ -1572,11 +1804,24 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * @returns assoc array where keys are tables, and values are foreign keys
+ * Returns a list of Foreign Keys associated with a specific table.
+ *
+ * If there are no foreign keys then the function returns false.
+ *
+ * @param string $table The name of the table to get the foreign keys for.
+ * @param string $owner Table owner/schema.
+ * @param bool $upper If true, only matches the table with the uppercase name.
+ * @param bool $associative Returns the result in associative mode;
+ * if ADODB_FETCH_MODE is already associative, then
+ * this parameter is discarded.
+ *
+ * @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) {
+ function metaForeignKeys($table, $owner = '', $upper = false, $associative = false) {
return false;
}
+
/**
* Choose a database to connect to. Many databases do not support this.
*
@@ -1693,12 +1938,12 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * Create serializable recordset. Breaks rs link to connection.
- *
- * @param ADORecordSet $rs the recordset to serialize
+ * Create serializable recordset. Breaks rs link to connection.
*
- * @return ADORecordSet_array|bool the new recordset
- */
+ * @param ADORecordSet $rs the recordset to serialize
+ *
+ * @return ADORecordSet_array|bool the new recordset
+ */
function SerializableRS(&$rs) {
$rs2 = $this->_rs2rs($rs);
$ignore = false;
@@ -1708,17 +1953,17 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * Convert a database recordset to an array recordset.
+ * Convert a database recordset to an array recordset.
+ *
+ * Input recordset's cursor should be at beginning, and old $rs will be closed.
*
- * Input recordset's cursor should be at beginning, and old $rs will be closed.
- *
* @param ADORecordSet $rs the recordset to copy
* @param int $nrows number of rows to retrieve (optional)
* @param int $offset offset by number of rows (optional)
* @param bool $close
*
* @return ADORecordSet_array|ADORecordSet|bool the new recordset
- */
+ */
function &_rs2rs(&$rs,$nrows=-1,$offset=-1,$close=true) {
if (! $rs) {
$ret = false;
@@ -1747,7 +1992,7 @@ if (!defined('_ADODB_LAYER')) {
$arrayClass = $this->arrayClass;
- $rs2 = new $arrayClass();
+ $rs2 = new $arrayClass($fakeQueryId=1);
$rs2->connection = $this;
$rs2->sql = $rs->sql;
$rs2->dataProvider = $this->dataProvider;
@@ -1756,7 +2001,7 @@ if (!defined('_ADODB_LAYER')) {
return $rs2;
}
- /*
+ /**
* Return all rows.
*
* Compat with PEAR DB.
@@ -1765,9 +2010,9 @@ if (!defined('_ADODB_LAYER')) {
* @param array|bool $inputarr Input bind array
*
* @return array|false
- */
+ */
function GetAll($sql, $inputarr=false) {
- return $this->GetArray($sql,$inputarr);
+ return $this->GetArray($sql,$inputarr);
}
/**
@@ -1941,23 +2186,17 @@ if (!defined('_ADODB_LAYER')) {
return $rv;
}
- function Transpose(&$rs,$addfieldnames=true) {
- $rs2 = $this->_rs2rs($rs);
- if (!$rs2) {
- return false;
- }
-
- $rs2->_transpose($addfieldnames);
- return $rs2;
- }
-
- /*
- Calculate the offset of a date for a particular database and generate
- appropriate SQL. Useful for calculating future/past dates and storing
- in a database.
-
- If dayFraction=1.5 means 1.5 days from now, 1.0/24 for 1 hour.
- */
+ /**
+ * Calculate the offset of a date for a particular database
+ * and generate appropriate SQL.
+ *
+ * Useful for calculating future/past dates and storing in a database.
+ *
+ * @param double $dayFraction 1.5 means 1.5 days from now, 1.0/24 for 1 hour
+ * @param string|false $date Reference date, false for system time
+ *
+ * @return string
+ */
function OffsetDate($dayFraction,$date=false) {
if (!$date) {
$date = $this->sysDate;
@@ -2029,14 +2268,14 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * Return one row of sql statement. Recordset is disposed for you.
- * Note that SelectLimit should not be called.
- *
- * @param string $sql SQL statement
- * @param array|bool $inputarr input bind array
+ * Return one row of sql statement. Recordset is disposed for you.
+ * Note that SelectLimit should not be called.
*
- * @return array|false Array containing the first row of the query
- */
+ * @param string $sql SQL statement
+ * @param array|bool $inputarr input bind array
+ *
+ * @return array|false Array containing the first row of the query
+ */
function GetRow($sql,$inputarr=false) {
global $ADODB_COUNTRECS;
@@ -2083,24 +2322,24 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * Insert or replace a single record. Note: this is not the same as MySQL's replace.
- * ADOdb's Replace() uses update-insert semantics, not insert-delete-duplicates of MySQL.
- * Also note that no table locking is done currently, so it is possible that the
- * record be inserted twice by two programs...
- *
- * $this->Replace('products', array('prodname' =>"'Nails'","price" => 3.99), 'prodname');
- *
- * $table table name
- * $fieldArray associative array of data (you must quote strings yourself).
- * $keyCol the primary key field name or if compound key, array of field names
- * autoQuote set to true to use a heuristic to quote strings. Works with nulls and numbers
- * but does not work with dates nor SQL functions.
- * has_autoinc the primary key is an auto-inc field, so skip in insert.
- *
- * Currently blob replace not supported
- *
- * returns 0 = fail, 1 = update, 2 = insert
- */
+ * Insert or replace a single record. Note: this is not the same as MySQL's replace.
+ * ADOdb's Replace() uses update-insert semantics, not insert-delete-duplicates of MySQL.
+ * Also note that no table locking is done currently, so it is possible that the
+ * record be inserted twice by two programs...
+ *
+ * $this->Replace('products', array('prodname' =>"'Nails'","price" => 3.99), 'prodname');
+ *
+ * $table table name
+ * $fieldArray associative array of data (you must quote strings yourself).
+ * $keyCol the primary key field name or if compound key, array of field names
+ * autoQuote set to true to use a heuristic to quote strings. Works with nulls and numbers
+ * but does not work with dates nor SQL functions.
+ * has_autoinc the primary key is an auto-inc field, so skip in insert.
+ *
+ * Currently blob replace not supported
+ *
+ * returns 0 = fail, 1 = update, 2 = insert
+ */
function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false) {
global $ADODB_INCLUDED_LIB;
@@ -2457,37 +2696,47 @@ if (!defined('_ADODB_LAYER')) {
/**
- * Update a blob column, given a where clause. There are more sophisticated
- * blob handling functions that we could have implemented, but all require
- * a very complex API. Instead we have chosen something that is extremely
- * simple to understand and use.
- *
- * Note: $blobtype supports 'BLOB' and 'CLOB', default is BLOB of course.
- *
- * Usage to update a $blobvalue which has a primary key blob_id=1 into a
- * field blobtable.blobcolumn:
- *
- * UpdateBlob('blobtable', 'blobcolumn', $blobvalue, 'blob_id=1');
- *
- * Insert example:
- *
- * $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
- * $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
- */
- function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') {
+ * Update a BLOB column, given a where clause.
+ *
+ * There are more sophisticated blob handling functions that we could have
+ * implemented, but all require a very complex API. Instead we have chosen
+ * something that is extremely simple to understand and use.
+ *
+ * Sample usage:
+ * - update a BLOB in field table.blob_col with value $blobValue, for a
+ * record having primary key id=1
+ * $conn->updateBlob('table', 'blob_col', $blobValue, 'id=1');
+ * - insert example:
+ * $conn->execute('INSERT INTO table (id, blob_col) VALUES (1, null)');
+ * $conn->updateBlob('table', 'blob_col', $blobValue, 'id=1');
+ *
+ * @param string $table
+ * @param string $column
+ * @param string $val Filename containing blob data
+ * @param mixed $where {@see updateBlob()}
+ * @param string $blobtype supports 'BLOB' (default) and 'CLOB'
+ *
+ * @return bool success
+ */
+ function updateBlob($table, $column, $val, $where, $blobtype='BLOB') {
return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
}
/**
- * Usage:
- * UpdateBlob('TABLE', 'COLUMN', '/path/to/file', 'ID=1');
- *
- * $blobtype supports 'BLOB' and 'CLOB'
- *
- * $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
- * $conn->UpdateBlob('blobtable','blobcol',$blobpath,'id=1');
- */
- function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB') {
+ * Update a BLOB from a file.
+ *
+ * Usage example:
+ * $conn->updateBlobFile('table', 'blob_col', '/path/to/file', 'id=1');
+ *
+ * @param string $table
+ * @param string $column
+ * @param string $path Filename containing blob data
+ * @param mixed $where {@see updateBlob()}
+ * @param string $blobtype supports 'BLOB' and 'CLOB'
+ *
+ * @return bool success
+ */
+ function updateBlobFile($table, $column, $path, $where, $blobtype='BLOB') {
$fd = fopen($path,'rb');
if ($fd === false) {
return false;
@@ -2551,12 +2800,12 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * Usage:
- * UpdateClob('TABLE', 'COLUMN', $var, 'ID=1', 'CLOB');
- *
- * $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)');
- * $conn->UpdateClob('clobtable','clobcol',$clob,'id=1');
- */
+ * Usage:
+ * UpdateClob('TABLE', 'COLUMN', $var, 'ID=1', 'CLOB');
+ *
+ * $conn->Execute('INSERT INTO clobtable (id, clobcol) VALUES (1, null)');
+ * $conn->UpdateClob('clobtable','clobcol',$clob,'id=1');
+ */
function UpdateClob($table,$column,$val,$where) {
return $this->UpdateBlob($table,$column,$val,$where,'CLOB');
}
@@ -2575,9 +2824,9 @@ if (!defined('_ADODB_LAYER')) {
/**
- * Change the SQL connection locale to a specified locale.
- * This is used to get the date formats written depending on the client locale.
- */
+ * Change the SQL connection locale to a specified locale.
+ * This is used to get the date formats written depending on the client locale.
+ */
function SetDateLocale($locale = 'En') {
$this->locale = $locale;
switch (strtoupper($locale))
@@ -2656,7 +2905,9 @@ if (!defined('_ADODB_LAYER')) {
}
/**
- * Begin a Transaction. Must be followed by CommitTrans() or RollbackTrans().
+ * Begin a Transaction.
+ *
+ * Must be followed by CommitTrans() or RollbackTrans().
*
* @return bool true if succeeded or false if database does not support transactions
*/
@@ -2718,11 +2969,14 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
/**
- * If database does not support transactions, always return true as data always committed
+ * Commits a transaction.
*
- * @param bool $ok set to false to rollback transaction, true to commit
+ * If database does not support transactions, return true as data is
+ * always committed.
*
- * @return true/false.
+ * @param bool $ok True to commit, false to rollback the transaction.
+ *
+ * @return bool true if successful
*/
function CommitTrans($ok=true) {
return true;
@@ -2730,9 +2984,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
- * If database does not support transactions, rollbacks always fail, so return false
+ * Rolls back a transaction.
*
- * @return bool
+ * If database does not support transactions, return false as rollbacks
+ * always fail.
+ *
+ * @return bool true if successful
*/
function RollbackTrans() {
return false;
@@ -3269,17 +3526,17 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
- * Will select the supplied $page number from a recordset, given that it is paginated in pages of
- * $nrows rows per page. It also saves two boolean values saying if the given page is the first
- * and/or last one of the recordset. Added by Iván Oliva to provide recordset pagination.
- *
- * @param int $secs2cache seconds to cache data, set to 0 to force query
- * @param string $sql
- * @param int $nrows is the number of rows per page to get
- * @param int $page is the page number to get (1-based)
- * @param mixed[]|bool $inputarr array of bind variables
- * @return mixed the recordset ($rs->databaseType == 'array')
- */
+ * Will select the supplied $page number from a recordset, given that it is paginated in pages of
+ * $nrows rows per page. It also saves two boolean values saying if the given page is the first
+ * and/or last one of the recordset. Added by Iván Oliva to provide recordset pagination.
+ *
+ * @param int $secs2cache seconds to cache data, set to 0 to force query
+ * @param string $sql
+ * @param int $nrows is the number of rows per page to get
+ * @param int $page is the page number to get (1-based)
+ * @param mixed[]|bool $inputarr array of bind variables
+ * @return mixed the recordset ($rs->databaseType == 'array')
+ */
function CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) {
/*switch($this->dataProvider) {
case 'postgres':
@@ -3291,37 +3548,37 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
/**
- * Returns the maximum size of a MetaType C field. If the method
- * is not defined in the driver returns ADODB_STRINGMAX_NOTSET
- *
- * @return int
- */
+ * Returns the maximum size of a MetaType C field. If the method
+ * is not defined in the driver returns ADODB_STRINGMAX_NOTSET
+ *
+ * @return int
+ */
function charMax() {
return ADODB_STRINGMAX_NOTSET;
}
/**
- * Returns the maximum size of a MetaType X field. If the method
- * is not defined in the driver returns ADODB_STRINGMAX_NOTSET
- *
- * @return int
- */
+ * Returns the maximum size of a MetaType X field. If the method
+ * is not defined in the driver returns ADODB_STRINGMAX_NOTSET
+ *
+ * @return int
+ */
function textMax() {
return ADODB_STRINGMAX_NOTSET;
}
/**
- * Returns a substring of a varchar type field
- *
- * Some databases have variations of the parameters, which is why
- * we have an ADOdb function for it
- *
- * @param string $fld The field to sub-string
- * @param int $start The start point
- * @param int $length An optional length
- *
- * @return string The SQL text
- */
+ * Returns a substring of a varchar type field
+ *
+ * Some databases have variations of the parameters, which is why
+ * we have an ADOdb function for it
+ *
+ * @param string $fld The field to sub-string
+ * @param int $start The start point
+ * @param int $length An optional length
+ *
+ * @return string The SQL text
+ */
function substr($fld,$start,$length=0) {
$text = "{$this->substr}($fld,$start";
if ($length > 0)
@@ -3426,15 +3683,14 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
//==============================================================================================
/**
- * Internal placeholder for record objects. Used by ADORecordSet->FetchObj().
- */
+ * Internal placeholder for record objects. Used by ADORecordSet->FetchObj().
+ */
class ADOFetchObj {
};
- //==============================================================================================
- // CLASS ADORecordSet_empty
- //==============================================================================================
-
+ /**
+ * Class ADODB_Iterator_empty
+ */
class ADODB_Iterator_empty implements Iterator {
private $rs;
@@ -3477,8 +3733,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
- * Lightweight recordset when there are no records to be returned
- */
+ * Lightweight recordset when there are no records to be returned
+ */
class ADORecordSet_empty implements IteratorAggregate
{
var $dataProvider = 'empty';
@@ -3564,10 +3820,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
include_once(ADODB_DIR.'/adodb-time.inc.php');
}
- //==============================================================================================
- // CLASS ADORecordSet
- //==============================================================================================
-
+ /**
+ * Class ADODB_Iterator
+ */
class ADODB_Iterator implements Iterator {
private $rs;
@@ -3612,13 +3867,14 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
- /**
- * RecordSet class that represents the dataset returned by the database.
- * To keep memory overhead low, this class holds only the current row in memory.
- * No prefetching of data is done, so the RecordCount() can return -1 ( which
- * means recordcount not known).
- */
- class ADORecordSet implements IteratorAggregate {
+/**
+ * RecordSet class that represents the dataset returned by the database.
+ *
+ * To keep memory overhead low, this class holds only the current row in memory.
+ * No prefetching of data is done, so the RecordCount() can return -1 (which
+ * means recordcount not known).
+ */
+class ADORecordSet implements IteratorAggregate {
/**
* public variables
@@ -3639,8 +3895,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
var $bind = false; /// used by Fields() to hold array - should be private?
var $fetchMode; /// default fetch mode
- var $connection = false; /// the parent connection
-
+ /** @var ADOConnection The parent connection */
+ var $connection = false;
/**
* private variables
*/
@@ -3661,6 +3917,10 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
var $_maxRecordCount = 0;
var $datetime = false;
+ public $customActualTypes;
+ public $customMetaTypes;
+
+
/**
* @var ADOFieldObject[] Field metadata cache
* @see fieldTypesArray()
@@ -3670,10 +3930,10 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
* Constructor
*
- * @param resource|int queryID this is the queryID returned by ADOConnection->_query()
- *
+ * @param resource|int $queryID Query ID returned by ADOConnection->_query()
+ * @param int|bool $mode The ADODB_FETCH_MODE value
*/
- function __construct($queryID) {
+ function __construct($queryID,$mode=false) {
$this->_queryID = $queryID;
}
@@ -3698,7 +3958,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
$this->_inited = true;
if ($this->_queryID) {
- @$this->_initrs();
+ @$this->_initRS();
} else {
$this->_numOfRows = 0;
$this->_numOfFields = 0;
@@ -3713,6 +3973,16 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
}
+ /**
+ * Recordset initialization stub
+ */
+ protected function _initRS() {}
+
+ /**
+ * Row fetch stub
+ * @return bool
+ */
+ protected function _fetch() {}
/**
* Generate a SELECT tag from a recordset, and return the HTML markup.
@@ -3851,24 +4121,28 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
return $this->GetArray($nRows);
}
- /*
- * Some databases allow multiple recordsets to be returned. This function
- * will return true if there is a next recordset, or false if no more.
- */
+ /**
+ * Checks if there is another available recordset.
+ *
+ * Some databases allow multiple recordsets to be returned.
+ *
+ * @return boolean true if there is a next recordset, or false if no more
+ */
function NextRecordSet() {
return false;
}
/**
- * return recordset as a 2-dimensional array.
+ * Return recordset as a 2-dimensional array.
+ *
* Helper function for ADOConnection->SelectLimit()
*
- * @param offset is the row to start calculations from (1-based)
- * @param [nrows] is the number of rows to return
+ * @param int $nrows Number of rows to return
+ * @param int $offset Starting row (1-based)
*
* @return array an array indexed by the rows (0-based) from the recordset
*/
- function GetArrayLimit($nrows,$offset=-1) {
+ function getArrayLimit($nrows, $offset=-1) {
if ($offset <= 0) {
return $this->GetArray($nrows);
}
@@ -3889,11 +4163,11 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
* Synonym for GetArray() for compatibility with ADO.
*
- * @param [nRows] is the number of rows to return. -1 means every row.
+ * @param int $nRows Number of rows to return. -1 means every row.
*
* @return array an array indexed by the rows (0-based) from the recordset
*/
- function GetRows($nRows = -1) {
+ function getRows($nRows = -1) {
return $this->GetArray($nRows);
}
@@ -4106,8 +4380,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
- * PEAR DB Compat - do not use internally
- */
+ * PEAR DB Compat - do not use internally
+ */
function Free() {
return $this->Close();
}
@@ -4152,13 +4426,13 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
- * Fetch a row, returning PEAR_Error if no more rows.
- * This is PEAR DB compat mode.
- *
- * @param mixed[]|false $arr
- *
- * @return mixed DB_OK or error object
- */
+ * Fetch a row, returning PEAR_Error if no more rows.
+ * This is PEAR DB compat mode.
+ *
+ * @param mixed[]|false $arr
+ *
+ * @return mixed DB_OK or error object
+ */
function FetchInto(&$arr) {
if ($this->EOF) {
return (defined('PEAR_ERROR_RETURN')) ? new PEAR_Error('EOF',-1): false;
@@ -4281,6 +4555,14 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
return false;
}
+ /**
+ * Adjusts the result pointer to an arbitrary row in the result.
+ *
+ * @param int $row The row to seek to.
+ *
+ * @return bool False if the recordset contains no rows, otherwise true.
+ */
+ function _seek($row) {}
/**
* Get the value of a field in the current row by column name.
@@ -4354,8 +4636,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
* Use associative array to get fields array for databases that do not support
* associative arrays. Submitted by Paolo S. Asioli paolo.asioli#libero.it
*
- * @param int [$upper] Case for the array keys, defaults to uppercase
+ * @param int $upper Case for the array keys, defaults to uppercase
* (see ADODB_ASSOC_CASE_xxx constants)
+ * @return array
*/
function GetRowAssoc($upper = ADODB_ASSOC_CASE) {
$record = array();
@@ -4391,15 +4674,14 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
/**
- * Synonyms RecordCount and RowCount
+ * Number of rows in recordset.
*
* @return int Number of rows or -1 if this is not supported
*/
- function RecordCount() {
+ function recordCount() {
return $this->_numOfRows;
}
-
/**
* If we are using PageExecute(), this will return the maximum possible rows
* that can be returned when paging a recordset.
@@ -4407,26 +4689,32 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
* @return int
*/
function MaxRecordCount() {
- return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->RecordCount();
+ return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->recordCount();
}
/**
- * synonyms RecordCount and RowCount
+ * Number of rows in recordset.
+ * Alias for {@see recordCount()}
*
- * @return the number of rows or -1 if this is not supported
+ * @return int Number of rows or -1 if this is not supported
*/
- function RowCount() {
- return $this->_numOfRows;
+ function rowCount() {
+ return $this->recordCount();
}
-
- /**
- * Portable RecordCount. Pablo Roca
+ /**
+ * Portable RecordCount.
*
- * @return the number of records from a previous SELECT. All databases support this.
+ * Be aware of possible problems in multiuser environments.
+ * For better speed the table must be indexed by the condition.
+ * Heavy test this before deploying.
*
- * But aware possible problems in multiuser environments. For better speed the table
- * must be indexed by the condition. Heavy test this before deploying.
+ * @param string $table
+ * @param string $condition
+ *
+ * @return int Number of records from a previous SELECT. All databases support this.
+ *
+ * @author Pablo Roca
*/
function PO_RecordCount($table="", $condition="") {
@@ -4500,24 +4788,24 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
/**
- * Return the fields array of the current row as an object for convenience.
- * The default case is lowercase field names.
- *
- * @return the object with the properties set to the fields of the current row
- */
+ * Return the fields array of the current row as an object for convenience.
+ * The default case is lowercase field names.
+ *
+ * @return the object with the properties set to the fields of the current row
+ */
function FetchObj() {
return $this->FetchObject(false);
}
/**
- * Return the fields array of the current row as an object for convenience.
- * The default case is uppercase.
- *
- * @param $isupper to set the object property names to uppercase
- *
- * @return the object with the properties set to the fields of the current row
- */
- function FetchObject($isupper=true) {
+ * Return the fields array of the current row as an object for convenience.
+ * The default case is uppercase.
+ *
+ * @param bool $isUpper to set the object property names to uppercase
+ *
+ * @return ADOFetchObj The object with properties set to the fields of the current row
+ */
+ function FetchObject($isUpper=true) {
if (empty($this->_obj)) {
$this->_obj = new ADOFetchObj();
$this->_names = array();
@@ -4526,12 +4814,11 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
$this->_names[] = $f->name;
}
}
- $i = 0;
$o = clone($this->_obj);
for ($i=0; $i <$this->_numOfFields; $i++) {
$name = $this->_names[$i];
- if ($isupper) {
+ if ($isUpper) {
$n = strtoupper($name);
} else {
$n = $name;
@@ -4543,34 +4830,34 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
/**
- * Return the fields array of the current row as an object for convenience.
- * The default is lower-case field names.
- *
- * @return the object with the properties set to the fields of the current row,
- * or false if EOF
- *
- * Fixed bug reported by tim@orotech.net
- */
+ * Return the fields array of the current row as an object for convenience.
+ * The default is lower-case field names.
+ *
+ * @return ADOFetchObj|false The object with properties set to the fields of the current row
+ * or false if EOF.
+ *
+ * Fixed bug reported by tim@orotech.net
+ */
function FetchNextObj() {
return $this->FetchNextObject(false);
}
/**
- * Return the fields array of the current row as an object for convenience.
- * The default is upper case field names.
- *
- * @param $isupper to set the object property names to uppercase
- *
- * @return the object with the properties set to the fields of the current row,
- * or false if EOF
- *
- * Fixed bug reported by tim@orotech.net
- */
- function FetchNextObject($isupper=true) {
+ * Return the fields array of the current row as an object for convenience.
+ * The default is upper case field names.
+ *
+ * @param bool $isUpper to set the object property names to uppercase
+ *
+ * @return ADOFetchObj|false The object with properties set to the fields of the current row
+ * or false if EOF.
+ *
+ * Fixed bug reported by tim@orotech.net
+ */
+ function FetchNextObject($isUpper=true) {
$o = false;
if ($this->_numOfRows != 0 && !$this->EOF) {
- $o = $this->FetchObject($isupper);
+ $o = $this->FetchObject($isUpper);
$this->_currentRow++;
if ($this->_fetch()) {
return $o;
@@ -4581,37 +4868,29 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
/**
- * Get the metatype of the column. This is used for formatting. This is because
- * many databases use different names for the same type, so we transform the original
- * type to our standardised version which uses 1 character codes:
+ * Get the ADOdb metatype.
*
- * @param t is the type passed in. Normally is ADOFieldObject->type.
- * @param len is the maximum length of that field. This is because we treat character
- * fields bigger than a certain size as a 'B' (blob).
- * @param fieldobj is the field object returned by the database driver. Can hold
- * additional info (eg. primary_key for mysql).
+ * Many databases use different names for the same type, so we transform
+ * the native type to our standardised one, which uses 1 character codes.
+ * @see https://adodb.org/dokuwiki/doku.php?id=v5:dictionary:dictionary_index#portable_data_types
*
- * @return the general type of the data:
- * C for character < 250 chars
- * X for teXt (>= 250 chars)
- * B for Binary
- * N for numeric or floating point
- * D for date
- * T for timestamp
- * L for logical/Boolean
- * I for integer
- * R for autoincrement counter/integer
+ * @param string|ADOFieldObject $t Native type (usually ADOFieldObject->type)
+ * It is also possible to provide an
+ * ADOFieldObject here.
+ * @param int $len The field's maximum length. This is because we treat
+ * character fields bigger than a certain size as a 'B' (blob).
+ * @param ADOFieldObject $fieldObj Field object returned by the database driver;
+ * can hold additional info (eg. primary_key for mysql).
*
- *
- */
- function MetaType($t,$len=-1,$fieldobj=false) {
- if (is_object($t)) {
- $fieldobj = $t;
- $t = $fieldobj->type;
- $len = $fieldobj->max_length;
+ * @return string The ADOdb Standard type
+ */
+ function metaType($t, $len = -1, $fieldObj = false) {
+ if ($t instanceof ADOFieldObject) {
+ $fieldObj = $t;
+ $t = $fieldObj->type;
+ $len = $fieldObj->max_length;
}
-
// changed in 2.32 to hashing instead of switch stmt for speed...
static $typeMap = array(
'VARCHAR' => 'C',
@@ -4718,8 +4997,6 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
"SQLBOOL" => 'L'
);
-
- $tmap = false;
$t = strtoupper($t);
$tmap = (isset($typeMap[$t])) ? $typeMap[$t] : ADODB_DEFAULT_METATYPE;
switch ($tmap) {
@@ -4735,7 +5012,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
return 'C';
case 'I':
- if (!empty($fieldobj->primary_key)) {
+ if (!empty($fieldObj->primary_key)) {
return 'R';
}
return 'I';
@@ -4744,8 +5021,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
return 'N';
case 'B':
- if (isset($fieldobj->binary)) {
- return ($fieldobj->binary) ? 'B' : 'X';
+ if (isset($fieldObj->binary)) {
+ return ($fieldObj->binary) ? 'B' : 'X';
}
return 'B';
@@ -4796,8 +5073,10 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
* set/returns the current recordset page when paginating
+ * @param int $page
+ * @return int
*/
- function AbsolutePage($page=-1) {
+ function absolutePage($page=-1) {
if ($page != -1) {
$this->_currentPage = $page;
}
@@ -4806,6 +5085,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
* set/returns the status of the atFirstPage flag when paginating
+ * @param bool $status
+ * @return bool
*/
function AtFirstPage($status=false) {
if ($status != false) {
@@ -4814,6 +5095,10 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
return $this->_atFirstPage;
}
+ /**
+ * @param bool $page
+ * @return bool
+ */
function LastPageNo($page = false) {
if ($page != false) {
$this->_lastPageNo = $page;
@@ -4823,6 +5108,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
* set/returns the status of the atLastPage flag when paginating
+ * @param bool $status
+ * @return bool
*/
function AtLastPage($status=false) {
if ($status != false) {
@@ -4860,48 +5147,22 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
/**
* Constructor
+ *
+ * The parameters passed to this recordset are always fake because
+ * this class does not use the queryID
+ *
+ * @param resource|int $queryID Ignored
+ * @param int|bool $mode The ADODB_FETCH_MODE value
*/
- function __construct($fakeid=1) {
+ function __construct($queryID, $mode=false) {
global $ADODB_FETCH_MODE,$ADODB_COMPAT_FETCH;
// fetch() on EOF does not delete $this->fields
$this->compat = !empty($ADODB_COMPAT_FETCH);
- parent::__construct($fakeid); // fake queryID
+ parent::__construct($queryID); // fake queryID
$this->fetchMode = $ADODB_FETCH_MODE;
}
- function _transpose($addfieldnames=true) {
- global $ADODB_INCLUDED_LIB;
-
- if (empty($ADODB_INCLUDED_LIB)) {
- include_once(ADODB_DIR.'/adodb-lib.inc.php');
- }
- $hdr = true;
-
- $fobjs = $addfieldnames ? $this->_fieldobjects : false;
- adodb_transpose($this->_array, $newarr, $hdr, $fobjs);
- //adodb_pr($newarr);
-
- $this->_skiprow1 = false;
- $this->_array = $newarr;
- $this->_colnames = $hdr;
-
- adodb_probetypes($newarr,$this->_types);
-
- $this->_fieldobjects = array();
-
- foreach($hdr as $k => $name) {
- $f = new ADOFieldObject();
- $f->name = $name;
- $f->type = $this->_types[$k];
- $f->max_length = -1;
- $this->_fieldobjects[] = $f;
- }
- $this->fields = reset($this->_array);
-
- $this->_initrs();
-
- }
/**
* Setup the array.
@@ -5115,12 +5376,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
break;
case 'mysql':
- // mysql driver deprecated since 5.5, removed in 7.0
- // automatically switch to mysqli
- if(version_compare(PHP_VERSION, '7.0.0', '>=')) {
- $db = 'mysqli';
- }
- $class = $db;
+ // mysql extension removed in PHP 7.0 - automatically switch to mysqli
+ $class = $db = 'mysqli';
break;
default:
@@ -5497,9 +5754,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
return $dict;
}
- /*
- Perform a print_r, with pre tags for better formatting.
- */
+ /**
+ * Perform a print_r, with pre tags for better formatting.
+ */
function adodb_pr($var,$as_string=false) {
if ($as_string) {
ob_start();
@@ -5518,12 +5775,15 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
}
}
- /*
- Perform a stack-crawl and pretty print it.
-
- @param printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then).
- @param levels Number of levels to display
- */
+ /**
+ * Perform a stack-crawl and pretty print it.
+ *
+ * @param bool $printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then).
+ * @param int $levels Number of levels to display
+ * @param mixed $ishtml
+ *
+ * @return string
+ */
function adodb_backtrace($printOrArr=true,$levels=9999,$ishtml=null) {
global $ADODB_INCLUDED_LIB;
if (empty($ADODB_INCLUDED_LIB)) {
diff --git a/lib/adodb/datadict/datadict-access.inc.php b/lib/adodb/datadict/datadict-access.inc.php
index 7a7d4cbbdc8..b3f9fad0a2e 100644
--- a/lib/adodb/datadict/datadict-access.inc.php
+++ b/lib/adodb/datadict/datadict-access.inc.php
@@ -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;
}
diff --git a/lib/adodb/datadict/datadict-db2.inc.php b/lib/adodb/datadict/datadict-db2.inc.php
index c5dda09fb6b..9ac106bbbed 100644
--- a/lib/adodb/datadict/datadict-db2.inc.php
+++ b/lib/adodb/datadict/datadict-db2.inc.php
@@ -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';
diff --git a/lib/adodb/datadict/datadict-firebird.inc.php b/lib/adodb/datadict/datadict-firebird.inc.php
index 0020a0ae0b4..79d0a8f5c34 100644
--- a/lib/adodb/datadict/datadict-firebird.inc.php
+++ b/lib/adodb/datadict/datadict-firebird.inc.php
@@ -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);
}
diff --git a/lib/adodb/datadict/datadict-generic.inc.php b/lib/adodb/datadict/datadict-generic.inc.php
index c9c8dee871f..1a60dbc2466 100644
--- a/lib/adodb/datadict/datadict-generic.inc.php
+++ b/lib/adodb/datadict/datadict-generic.inc.php
@@ -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':
diff --git a/lib/adodb/datadict/datadict-ibase.inc.php b/lib/adodb/datadict/datadict-ibase.inc.php
index 5f58880ff5e..4310ded4b36 100644
--- a/lib/adodb/datadict/datadict-ibase.inc.php
+++ b/lib/adodb/datadict/datadict-ibase.inc.php
@@ -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':
diff --git a/lib/adodb/datadict/datadict-informix.inc.php b/lib/adodb/datadict/datadict-informix.inc.php
index acb5ba74ce6..9e151633fdf 100644
--- a/lib/adodb/datadict/datadict-informix.inc.php
+++ b/lib/adodb/datadict/datadict-informix.inc.php
@@ -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':
diff --git a/lib/adodb/datadict/datadict-mssql.inc.php b/lib/adodb/datadict/datadict-mssql.inc.php
index 1bcb27da169..17df9e39675 100644
--- a/lib/adodb/datadict/datadict-mssql.inc.php
+++ b/lib/adodb/datadict/datadict-mssql.inc.php
@@ -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';
diff --git a/lib/adodb/datadict/datadict-mssqlnative.inc.php b/lib/adodb/datadict/datadict-mssqlnative.inc.php
index b53dcd97b0f..59228cbe393 100644
--- a/lib/adodb/datadict/datadict-mssqlnative.inc.php
+++ b/lib/adodb/datadict/datadict-mssqlnative.inc.php
@@ -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';
diff --git a/lib/adodb/datadict/datadict-mysql.inc.php b/lib/adodb/datadict/datadict-mysql.inc.php
index a1ee950a6ba..9efbba1f316 100644
--- a/lib/adodb/datadict/datadict-mysql.inc.php
+++ b/lib/adodb/datadict/datadict-mysql.inc.php
@@ -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;
}
}
diff --git a/lib/adodb/datadict/datadict-oci8.inc.php b/lib/adodb/datadict/datadict-oci8.inc.php
index 9a239095cde..6d2cd244f5c 100644
--- a/lib/adodb/datadict/datadict-oci8.inc.php
+++ b/lib/adodb/datadict/datadict-oci8.inc.php
@@ -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;
diff --git a/lib/adodb/datadict/datadict-postgres.inc.php b/lib/adodb/datadict/datadict-postgres.inc.php
index 17627c44c18..d403cee3056 100644
--- a/lib/adodb/datadict/datadict-postgres.inc.php
+++ b/lib/adodb/datadict/datadict-postgres.inc.php
@@ -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;
}
diff --git a/lib/adodb/datadict/datadict-sapdb.inc.php b/lib/adodb/datadict/datadict-sapdb.inc.php
index 20c16aa6c50..c469800f2ef 100644
--- a/lib/adodb/datadict/datadict-sapdb.inc.php
+++ b/lib/adodb/datadict/datadict-sapdb.inc.php
@@ -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',
diff --git a/lib/adodb/datadict/datadict-sqlite.inc.php b/lib/adodb/datadict/datadict-sqlite.inc.php
index 942927f8a61..d565f887752 100644
--- a/lib/adodb/datadict/datadict-sqlite.inc.php
+++ b/lib/adodb/datadict/datadict-sqlite.inc.php
@@ -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
diff --git a/lib/adodb/datadict/datadict-sybase.inc.php b/lib/adodb/datadict/datadict-sybase.inc.php
index e565f8e21a4..d6573dfa3f7 100644
--- a/lib/adodb/datadict/datadict-sybase.inc.php
+++ b/lib/adodb/datadict/datadict-sybase.inc.php
@@ -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':
diff --git a/lib/adodb/drivers/adodb-ado.inc.php b/lib/adodb/drivers/adodb-ado.inc.php
index 67a032d7220..fc000cecb38 100644
--- a/lib/adodb/drivers/adodb-ado.inc.php
+++ b/lib/adodb/drivers/adodb-ado.inc.php
@@ -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;
diff --git a/lib/adodb/drivers/adodb-ado5.inc.php b/lib/adodb/drivers/adodb-ado5.inc.php
index f673d09298d..36f9c3b8d5b 100644
--- a/lib/adodb/drivers/adodb-ado5.inc.php
+++ b/lib/adodb/drivers/adodb-ado5.inc.php
@@ -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:
diff --git a/lib/adodb/drivers/adodb-db2.inc.php b/lib/adodb/drivers/adodb-db2.inc.php
index 6d1cf16c5c4..16c4054f174 100644
--- a/lib/adodb/drivers/adodb-db2.inc.php
+++ b/lib/adodb/drivers/adodb-db2.inc.php
@@ -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;
}
}
diff --git a/lib/adodb/drivers/adodb-fbsql.inc.php b/lib/adodb/drivers/adodb-fbsql.inc.php
index 0fb895a1d05..a4255eb97ed 100644
--- a/lib/adodb/drivers/adodb-fbsql.inc.php
+++ b/lib/adodb/drivers/adodb-fbsql.inc.php
@@ -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':
diff --git a/lib/adodb/drivers/adodb-firebird.inc.php b/lib/adodb/drivers/adodb-firebird.inc.php
index 2fafbe4fcee..135b72c6423 100644
--- a/lib/adodb/drivers/adodb-firebird.inc.php
+++ b/lib/adodb/drivers/adodb-firebird.inc.php
@@ -19,6 +19,10 @@
*
* @copyright 2000-2013 John Lim
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
+ *
+ * Driver was cloned from Interbase, so there's quite a lot of duplicated code
+ * @noinspection DuplicatedCode
+ * @noinspection PhpUnused
*/
// security - hide paths
@@ -35,39 +39,113 @@ class ADODB_firebird extends ADOConnection {
var $fmtTimeStamp = "'Y-m-d, H:i:s'";
var $concat_operator='||';
var $_transactionID;
- var $metaTablesSQL = "select lower(rdb\$relation_name) from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
+
+ public $metaTablesSQL = "SELECT LOWER(rdb\$relation_name) FROM rdb\$relations";
//OPN STUFF start
+
var $metaColumnsSQL = "select lower(a.rdb\$field_name), a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc";
//OPN STUFF end
- var $ibasetrans;
+
+ public $_genSeqSQL = "CREATE SEQUENCE %s START WITH %s";
+
+ public $_dropSeqSQL = "DROP SEQUENCE %s";
+
var $hasGenID = true;
var $_bindInputArray = true;
- var $buffers = 0;
- var $dialect = 3;
var $sysDate = "cast('TODAY' as timestamp)";
var $sysTimeStamp = "CURRENT_TIMESTAMP"; //"cast('NOW' as timestamp)";
var $ansiOuter = true;
var $hasAffectedRows = true;
var $poorAffectedRows = false;
var $blobEncodeType = 'C';
- var $role = false;
+ /*
+ * firebird custom optionally specifies the user role
+ */
+ public $role = false;
+ /*
+ * firebird custom optionally specifies the connection buffers
+ */
+ public $buffers = 0;
+
+ /*
+ * firebird custom optionally specifies database dialect
+ */
+ public $dialect = 3;
+
var $nameQuote = ''; /// string to use to quote identifiers and names
function __construct()
{
- // Ignore IBASE_DEFAULT we want a more practical transaction!
- // if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;
- // else
- $this->ibasetrans = IBASE_WAIT | IBASE_REC_VERSION | IBASE_COMMITTED;
+ parent::__construct();
+ $this->setTransactionMode('');
}
-
- // returns true or false
- function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$persist=false)
+ /**
+ * Sets the isolation level of a transaction.
+ *
+ * The default behavior is a more practical IBASE_WAIT | IBASE_REC_VERSION | IBASE_COMMITTED
+ * instead of IBASE_DEFAULT
+ *
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:settransactionmode
+ *
+ * @param string $transaction_mode The transaction mode to set.
+ *
+ * @return void
+ */
+ public function setTransactionMode($transaction_mode)
{
- if (!function_exists('fbird_pconnect')) return null;
- if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
+ $this->_transmode = $transaction_mode;
+
+ if (empty($transaction_mode)) {
+ $this->_transmode = IBASE_WAIT | IBASE_REC_VERSION | IBASE_COMMITTED;
+ }
+
+ }
+
+ /**
+ * Connect to a database.
+ *
+ * @todo add: parameter int $port, parameter string $socket
+ *
+ * @param string|null $argHostname (Optional) The host to connect to.
+ * @param string|null $argUsername (Optional) The username to connect as.
+ * @param string|null $argPassword (Optional) The password to connect with.
+ * @param string|null $argDatabasename (Optional) The name of the database to start in when connected.
+ * @param bool $persist (Optional) Whether or not to use a persistent connection.
+ *
+ * @return bool|null True if connected successfully, false if connection failed, or null if the mysqli extension
+ * isn't currently loaded.
+ */
+ public function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$persist=false)
+ {
+ if (!function_exists('fbird_pconnect'))
+ return null;
+
+ if ($argDatabasename)
+ $argHostname .= ':'.$argDatabasename;
+
$fn = ($persist) ? 'fbird_pconnect':'fbird_connect';
+
+ /*
+ * Now merge in the standard connection parameters setting
+ */
+ foreach ($this->connectionParameters as $options)
+ {
+ foreach($options as $k=>$v)
+ {
+ switch($k){
+ case 'role':
+ $this->role = $v;
+ break;
+ case 'dialect':
+ $this->dialect = $v;
+ break;
+ case 'buffers':
+ $this->buffers = $v;
+ }
+ }
+ }
+
if ($this->role)
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->charSet,$this->buffers,$this->dialect,$this->role);
@@ -75,40 +153,39 @@ class ADODB_firebird extends ADOConnection {
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->charSet,$this->buffers,$this->dialect);
- if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
- $this->replaceQuote = "''";
+ if ($this->dialect == 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
+ $this->replaceQuote = "";
}
if ($this->_connectionID === false) {
- $this->_handleerror();
+ $this->_handleError();
return false;
}
- // PHP5 change.
- if (function_exists('fbird_timefmt')) {
- fbird_timefmt($this->fbird_datefmt,fbird_DATE );
- if ($this->dialect == 1) {
- fbird_timefmt($this->fbird_datefmt,fbird_TIMESTAMP );
- } else {
- fbird_timefmt($this->fbird_timestampfmt,fbird_TIMESTAMP );
- }
- fbird_timefmt($this->fbird_timefmt,fbird_TIME );
+ ini_set("ibase.timestampformat", $this->fbird_timestampfmt);
+ ini_set("ibase.dateformat", $this->fbird_datefmt);
+ ini_set("ibase.timeformat", $this->fbird_timefmt);
- } else {
- ini_set("ibase.timestampformat", $this->fbird_timestampfmt);
- ini_set("ibase.dateformat", $this->fbird_datefmt);
- ini_set("ibase.timeformat", $this->fbird_timefmt);
- }
return true;
}
- // returns true or false
+ /**
+ * Connect to a database with a persistent connection.
+ *
+ * @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.
+ *
+ * @return bool|null True if connected successfully, false if connection failed, or null if the mysqli extension
+ * isn't currently loaded.
+ */
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,true);
}
- function MetaPrimaryKeys($table,$owner_notused=false,$internalKey=false)
+ public function metaPrimaryKeys($table,$owner_notused=false,$internalKey=false)
{
if ($internalKey) {
return array('RDB$DB_KEY');
@@ -126,31 +203,58 @@ class ADODB_firebird extends ADOConnection {
return false;
}
- function ServerInfo()
+ /**
+ * Get information about the current Firebird server.
+ *
+ * @return array
+ */
+ public function serverInfo()
{
$arr['dialect'] = $this->dialect;
switch($arr['dialect']) {
- case '':
- case '1': $s = 'Firebird Dialect 1'; break;
- case '2': $s = 'Firebird Dialect 2'; break;
- default:
- case '3': $s = 'Firebird Dialect 3'; break;
+ case '':
+ case '1':
+ $s = 'Firebird Dialect 1';
+ break;
+ case '2':
+ $s = 'Firebird Dialect 2';
+ break;
+ default:
+ case '3':
+ $s = 'Firebird Dialect 3';
+ break;
}
$arr['version'] = ADOConnection::_findvers($s);
$arr['description'] = $s;
return $arr;
}
- function BeginTrans()
+ /**
+ * Begin a Transaction. Must be followed by CommitTrans() or RollbackTrans().
+ *
+ * @return bool true if succeeded or false if database does not support transactions
+ */
+ public function beginTrans()
{
if ($this->transOff) return true;
$this->transCnt += 1;
$this->autoCommit = false;
- $this->_transactionID = fbird_trans( $this->ibasetrans, $this->_connectionID );
+ /*
+ * We manage the transaction mode via fbird_trans
+ */
+ $this->_transactionID = fbird_trans( $this->_transmode, $this->_connectionID );
return $this->_transactionID;
}
- function CommitTrans($ok=true)
+
+ /**
+ * Commits a transaction.
+ *
+ * @param bool $ok false to rollback transaction, true to commit
+ *
+ * @return bool
+ */
+ public function commitTrans($ok=true)
{
if (!$ok) {
return $this->RollbackTrans();
@@ -164,7 +268,6 @@ class ADODB_firebird extends ADOConnection {
$ret = false;
$this->autoCommit = true;
if ($this->_transactionID) {
- //print ' commit ';
$ret = fbird_commit($this->_transactionID);
}
$this->_transactionID = false;
@@ -173,31 +276,26 @@ class ADODB_firebird extends ADOConnection {
function _affectedrows()
{
- return fbird_affected_rows( $this->_transactionID ? $this->_transactionID : $this->_connectionID );
+ return fbird_affected_rows($this->_transactionID ?: $this->_connectionID);
}
- // there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
- // it appears that ibase extension cannot support multiple concurrent queryid's
- function _Execute($sql,$inputarr=false) {
- global $ADODB_COUNTRECS;
-
- if ($this->_logsql) {
- $savecrecs = $ADODB_COUNTRECS;
- $ADODB_COUNTRECS = true; // force countrecs
- $ret =& ADOConnection::_Execute($sql,$inputarr);
- $ADODB_COUNTRECS = $savecrecs;
- } else {
- $ret = ADOConnection::_Execute($sql,$inputarr);
- }
- return $ret;
- }
-
- function RollbackTrans()
+ /**
+ * Rollback a smart transaction.
+ *
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:rollbacktrans
+ *
+ * @return bool
+ */
+ public function rollbackTrans()
{
- if ($this->transOff) return true;
- if ($this->transCnt) $this->transCnt -= 1;
+ if ($this->transOff)
+ return true;
+ if ($this->transCnt)
+ $this->transCnt -= 1;
+
$ret = false;
$this->autoCommit = true;
+
if ($this->_transactionID) {
$ret = fbird_rollback($this->_transactionID);
}
@@ -206,16 +304,26 @@ class ADODB_firebird extends ADOConnection {
return $ret;
}
- function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+ /**
+ * Get a list of indexes on the specified table.
+ *
+ * @param string $table The name of the table to get indexes for.
+ * @param bool $primary (Optional) Whether or not to include the primary key.
+ * @param bool $owner (Optional) Unused.
+ *
+ * @return array|bool An array of the indexes, or false if the query to get the indexes failed.
+ */
+ public function metaIndexes($table, $primary = false, $owner = false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
- $false = false;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+
if ($this->fetchMode !== FALSE) {
$savem = $this->SetFetchMode(FALSE);
}
+
$table = strtoupper($table);
$sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";
if (!$primary) {
@@ -224,19 +332,19 @@ class ADODB_firebird extends ADOConnection {
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
}
// get index details
- $rs = $this->Execute($sql);
+ $rs = $this->execute($sql);
if (!is_object($rs)) {
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
}
$ADODB_FETCH_MODE = $save;
- return $false;
+ return false;
}
-
$indexes = array();
while ($row = $rs->FetchRow()) {
- $index = $row[0];
+
+ $index = trim($row[0]);
if (!isset($indexes[$index])) {
if (is_null($row[3])) {
$row[3] = 0;
@@ -246,12 +354,13 @@ class ADODB_firebird extends ADOConnection {
'columns' => array()
);
}
- $sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '".$index."' ORDER BY RDB\$FIELD_POSITION ASC";
- $rs1 = $this->Execute($sql);
+ $sql = sprintf("SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '%s' ORDER BY RDB\$FIELD_POSITION ASC",$index);
+ $rs1 = $this->execute($sql);
while ($row1 = $rs1->FetchRow()) {
- $indexes[$index]['columns'][$row1[2]] = $row1[1];
+ $indexes[$index]['columns'][$row1[2]] = trim($row1[1]);
}
}
+
// restore fetchmode
if (isset($savem)) {
$this->SetFetchMode($savem);
@@ -261,38 +370,60 @@ class ADODB_firebird extends ADOConnection {
return $indexes;
}
-
- // See http://community.borland.com/article/0,1410,25844,00.html
- function RowLock($tables,$where,$col=false)
+ /**
+ * Lock a table row for a duration of a transaction.
+ *
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:rowlock
+ * @link https://firebirdsql.org/refdocs/langrefupd21-notes-withlock.html
+ *
+ * @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.
+ */
+ public function rowLock($table,$where,$col=false)
{
- if ($this->autoCommit) {
- $this->BeginTrans();
- }
- $this->Execute("UPDATE $table SET $col=$col WHERE $where "); // is this correct - jlim?
- return 1;
+ if ($this->transCnt==0)
+ $this->beginTrans();
+
+ if ($where) $where = ' where '.$where;
+ $rs = $this->execute("SELECT $col FROM $table $where FOR UPDATE WITH LOCK");
+ return !empty($rs);
}
-
- function CreateSequence($seqname = 'adodbseq', $startID = 1)
+ /**
+ * Creates a sequence in the database.
+ *
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:createsequence
+ *
+ * @param string $seqname The sequence name.
+ * @param int $startID The start id.
+ *
+ * @return ADORecordSet|bool A record set if executed successfully, otherwise false.
+ */
+ public function createSequence($seqname='adodbseq', $startID = 1)
{
- $ok = $this->Execute(("CREATE GENERATOR $seqname" ));
- if (!$ok) return false;
- return $this->Execute("SET GENERATOR $seqname TO ".($startID-1));
+ $sql = sprintf($this->_genSeqSQL,$seqname,$startID);
+ return $this->execute($sql);
}
- function DropSequence($seqname = 'adodbseq')
- {
- $seqname = strtoupper($seqname);
- return $this->Execute("DROP GENERATOR $seqname");
- }
-
- function GenID($seqname='adodbseq',$startID=1)
+ /**
+ * A portable method of creating sequence numbers.
+ *
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:genid
+ *
+ * @param string $seqname (Optional) The name of the sequence to use.
+ * @param int $startID (Optional) The point to start at in the sequence.
+ *
+ * @return int
+ */
+ public function genID($seqname='adodbseq',$startID=1)
{
$getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
$rs = @$this->Execute($getnext);
if (!$rs) {
- $this->Execute(("CREATE GENERATOR $seqname" ));
- $this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
+ $this->Execute("CREATE SEQUENCE $seqname START WITH $startID");
$rs = $this->Execute($getnext);
}
if ($rs && !$rs->EOF) {
@@ -309,39 +440,62 @@ class ADODB_firebird extends ADOConnection {
return $this->genID;
}
- function SelectDB($dbName)
+ function selectDB($dbName)
{
return false;
}
- function _handleerror()
+ function _handleError()
{
- $this->_errorMsg = fbird_errmsg();
+ $this->_errorCode = fbird_errcode();
+ $this->_errorMsg = fbird_errmsg();
}
- function ErrorNo()
+
+ public function errorNo()
{
- if (preg_match('/error code = ([\-0-9]*)/i', $this->_errorMsg,$arr)) return (integer) $arr[1];
- else return 0;
+ return (integer) $this->_errorCode;
}
- function ErrorMsg()
+ function errorMsg()
{
return $this->_errorMsg;
}
- function Prepare($sql)
+ /**
+ * 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
+ *
+ * @param string $sql The SQL to prepare.
+ *
+ * @return bool|array The SQL that was provided and the prepared parameters,
+ * or false if the preparation fails
+ */
+ public function prepare($sql)
{
$stmt = fbird_prepare($this->_connectionID,$sql);
- if (!$stmt) return false;
+ if (!$stmt)
+ return false;
return array($sql,$stmt);
}
- // returns query ID if successful, otherwise false
- // there have been reports of problems with nested queries - the code is probably not re-entrant?
- function _query($sql,$iarr=false)
+ /**
+ * Return the query id.
+ *
+ * @param string|array $sql
+ * @param array $iarr
+ *
+ * @return bool|object
+ */
+ function _query($sql, $iarr = false)
{
- if ( !$this->isConnected() ) return false;
+ if (!$this->isConnected()) {
+ return false;
+ }
+
if (!$this->autoCommit && $this->_transactionID) {
$conn = $this->_transactionID;
$docommit = false;
@@ -349,36 +503,25 @@ class ADODB_firebird extends ADOConnection {
$conn = $this->_connectionID;
$docommit = true;
}
+
if (is_array($sql)) {
+ // Prepared statement
$fn = 'fbird_execute';
- $sql = $sql[1];
- if (is_array($iarr)) {
- if ( !isset($iarr[0]) )
- $iarr[0] = ''; // PHP5 compat hack
- $fnarr = array_merge( array($sql) , $iarr);
- $ret = call_user_func_array($fn,$fnarr);
- }
- else {
- $ret = $fn($sql);
- }
+ $args = [$sql[1]];
} else {
$fn = 'fbird_query';
- if (is_array($iarr))
- {
- if (sizeof($iarr) == 0)
- $iarr[0] = ''; // PHP5 compat hack
- $fnarr = array_merge( array($conn,$sql) , $iarr);
- $ret = call_user_func_array($fn,$fnarr);
- }
- else {
- $ret = $fn($conn, $sql);
- }
+ $args = [$conn, $sql];
}
+ if (is_array($iarr)) {
+ $args = array_merge($args, $iarr);
+ }
+ $ret = call_user_func_array($fn, $args);
+
if ($docommit && $ret === true) {
fbird_commit($this->_connectionID);
}
- $this->_handleerror();
+ $this->_handleError();
return $ret;
}
@@ -398,122 +541,133 @@ class ADODB_firebird extends ADOConnection {
$fld->max_length = $flen;
$fld->scale = null;
switch($ftype){
- case 7:
- case 8:
- if ($dialect3) {
- switch($fsubtype){
- case 0:
- $fld->type = ($ftype == 7 ? 'smallint' : 'integer');
- break;
- case 1:
- $fld->type = 'numeric';
- $fld->max_length = $fprecision;
- $fld->scale = $fscale;
- break;
- case 2:
- $fld->type = 'decimal';
- $fld->max_length = $fprecision;
- $fld->scale = $fscale;
- break;
- } // switch
- } else {
- if ($fscale !=0) {
- $fld->type = 'decimal';
- $fld->scale = $fscale;
- $fld->max_length = ($ftype == 7 ? 4 : 9);
- } else {
+ case 7:
+ case 8:
+ if ($dialect3) {
+ switch($fsubtype){
+ case 0:
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
- }
- }
- break;
- case 16:
- if ($dialect3) {
- switch($fsubtype){
- case 0:
- $fld->type = 'decimal';
- $fld->max_length = 18;
- $fld->scale = 0;
- break;
- case 1:
- $fld->type = 'numeric';
- $fld->max_length = $fprecision;
- $fld->scale = $fscale;
- break;
- case 2:
- $fld->type = 'decimal';
- $fld->max_length = $fprecision;
- $fld->scale = $fscale;
- break;
- } // switch
- }
- break;
- case 10:
- $fld->type = 'float';
- break;
- case 14:
- $fld->type = 'char';
- break;
- case 27:
+ break;
+ case 1:
+ $fld->type = 'numeric';
+ $fld->max_length = $fprecision;
+ $fld->scale = $fscale;
+ break;
+ case 2:
+ $fld->type = 'decimal';
+ $fld->max_length = $fprecision;
+ $fld->scale = $fscale;
+ break;
+ } // switch
+ } else {
if ($fscale !=0) {
$fld->type = 'decimal';
- $fld->max_length = 15;
- $fld->scale = 5;
+ $fld->scale = $fscale;
+ $fld->max_length = ($ftype == 7 ? 4 : 9);
} else {
- $fld->type = 'double';
+ $fld->type = ($ftype == 7 ? 'smallint' : 'integer');
}
- break;
- case 35:
- if ($dialect3) {
- $fld->type = 'timestamp';
- } else {
- $fld->type = 'date';
- }
- break;
- case 12:
+ }
+ break;
+ case 16:
+ if ($dialect3) {
+ switch($fsubtype){
+ case 0:
+ $fld->type = 'decimal';
+ $fld->max_length = 18;
+ $fld->scale = 0;
+ break;
+ case 1:
+ $fld->type = 'numeric';
+ $fld->max_length = $fprecision;
+ $fld->scale = $fscale;
+ break;
+ case 2:
+ $fld->type = 'decimal';
+ $fld->max_length = $fprecision;
+ $fld->scale = $fscale;
+ break;
+ } // switch
+ }
+ break;
+ case 10:
+ $fld->type = 'float';
+ break;
+ case 14:
+ $fld->type = 'char';
+ break;
+ case 27:
+ if ($fscale !=0) {
+ $fld->type = 'decimal';
+ $fld->max_length = 15;
+ $fld->scale = 5;
+ } else {
+ $fld->type = 'double';
+ }
+ break;
+ case 35:
+ if ($dialect3) {
+ $fld->type = 'timestamp';
+ } else {
$fld->type = 'date';
- break;
- case 13:
- $fld->type = 'time';
- break;
- case 37:
- $fld->type = 'varchar';
- break;
- case 40:
- $fld->type = 'cstring';
- break;
- case 261:
- $fld->type = 'blob';
- $fld->max_length = -1;
- break;
+ }
+ break;
+ case 12:
+ $fld->type = 'date';
+ break;
+ case 13:
+ $fld->type = 'time';
+ break;
+ case 37:
+ $fld->type = 'varchar';
+ break;
+ case 40:
+ $fld->type = 'cstring';
+ break;
+ case 261:
+ $fld->type = 'blob';
+ $fld->max_length = -1;
+ break;
} // switch
}
//OPN STUFF end
- // returns array of ADOFieldObjects for current table
- function MetaColumns($table, $normalize=true)
+ /**
+ * Return an array of information about a table's columns.
+ *
+ * @param string $table The name of the table to get the column info for.
+ * @param bool $normalize (Optional) Unused.
+ *
+ * @return ADOFieldObject[]|bool An array of info for each column,
+ * or false if it could not determine the info.
+ */
+ public function metaColumns($table, $normalize = true)
{
- global $ADODB_FETCH_MODE;
+
+ global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
- $rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
+ $rs = $this->execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
$ADODB_FETCH_MODE = $save;
- $false = false;
+
if ($rs === false) {
- return $false;
+ return false;
}
$retarr = array();
//OPN STUFF start
- $dialect3 = ($this->dialect==3 ? true : false);
+ $dialect3 = $this->dialect == 3;
//OPN STUFF end
while (!$rs->EOF) { //print_r($rs->fields);
$fld = new ADOFieldObject();
$fld->name = trim($rs->fields[0]);
//OPN STUFF start
- $this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
+ //print_r($rs->fields);
+ $this->_ConvertFieldType(
+ $fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
if (isset($rs->fields[1]) && $rs->fields[1]) {
$fld->not_null = true;
}
@@ -521,17 +675,24 @@ class ADODB_firebird extends ADOConnection {
$fld->has_default = true;
$d = substr($rs->fields[2],strlen('default '));
- switch ($fld->type)
- {
- case 'smallint':
- case 'integer': $fld->default_value = (int) $d; break;
- case 'char':
- case 'blob':
- case 'text':
- case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;
- case 'double':
- case 'float': $fld->default_value = (float) $d; break;
- default: $fld->default_value = $d; break;
+ switch ($fld->type) {
+ case 'smallint':
+ case 'integer':
+ $fld->default_value = (int)$d;
+ break;
+ case 'char':
+ case 'blob':
+ case 'text':
+ case 'varchar':
+ $fld->default_value = (string)substr($d, 1, strlen($d) - 2);
+ break;
+ case 'double':
+ case 'float':
+ $fld->default_value = (float)$d;
+ break;
+ default:
+ $fld->default_value = $d;
+ break;
}
// case 35:$tt = 'TIMESTAMP'; break;
}
@@ -547,61 +708,115 @@ class ADODB_firebird extends ADOConnection {
$rs->MoveNext();
}
$rs->Close();
- if ( empty($retarr)) return $false;
+ if ( empty($retarr))
+ return false;
else return $retarr;
}
- function BlobEncode( $blob )
+ /**
+ * Retrieves a list of tables based on given criteria
+ *
+ * @param string|bool $ttype (Optional) Table type = 'TABLE', 'VIEW' or false=both (default)
+ * @param string|bool $showSchema (Optional) schema name, false = current schema (default)
+ * @param string|bool $mask (Optional) filters the table by name
+ *
+ * @return array list of tables
+ */
+ public function metaTables($ttype = false, $showSchema = false, $mask = false)
+ {
+ $save = $this->metaTablesSQL;
+ if (!$showSchema) {
+ $this->metaTablesSQL .= " WHERE (rdb\$relation_name NOT LIKE 'RDB\$%' AND rdb\$relation_name NOT LIKE 'MON\$%' AND rdb\$relation_name NOT LIKE 'SEC\$%')";
+ } elseif (is_string($showSchema)) {
+ $this->metaTablesSQL .= $this->qstr($showSchema);
+ }
+
+ if ($mask) {
+ $mask = $this->qstr($mask);
+ $this->metaTablesSQL .= " AND table_name LIKE $mask";
+ }
+ $ret = ADOConnection::metaTables($ttype,$showSchema);
+
+ $this->metaTablesSQL = $save;
+ return $ret;
+ }
+
+ /**
+ * Encodes a blob, then assigns an id ready to be used
+ *
+ * @param string $blob The blob to be encoded
+ *
+ * @return bool success
+ */
+ public function blobEncode( $blob )
{
$blobid = fbird_blob_create( $this->_connectionID);
fbird_blob_add( $blobid, $blob );
return fbird_blob_close( $blobid );
}
- // since we auto-decode all blob's since 2.42,
- // BlobDecode should not do any transforms
- function BlobDecode($blob)
+ /**
+ * Manually decode a blob
+ *
+ * since we auto-decode all blob's since 2.42,
+ * BlobDecode should not do any transforms
+ *
+ * @param string $blob
+ *
+ * @return string the same blob
+ */
+ public function blobDecode($blob)
{
return $blob;
}
- // old blobdecode function
- // still used to auto-decode all blob's
- function _BlobDecode_old( $blob )
+ /**
+ * Auto function called on read of blob to decode
+ *
+ * @param string $blob Value to decode
+ *
+ * @return string Decoded blob
+ */
+ public function _blobDecode($blob)
{
- $blobid = fbird_blob_open($this->_connectionID, $blob );
- $realblob = fbird_blob_get( $blobid,$this->maxblobsize); // 2nd param is max size of blob -- Kevin Boillet
- while($string = fbird_blob_get($blobid, 8192)){
- $realblob .= $string;
+ if ($blob === null) {
+ return '';
}
- fbird_blob_close( $blobid );
- return( $realblob );
- }
+ $blob_data = fbird_blob_info($this->_connectionID, $blob);
+ $blobId = fbird_blob_open($this->_connectionID, $blob);
- function _BlobDecode( $blob )
- {
- $blob_data = fbird_blob_info($this->_connectionID, $blob );
- $blobid = fbird_blob_open($this->_connectionID, $blob );
-
- if( $blob_data[0] > $this->maxblobsize ) {
- $realblob = fbird_blob_get($blobid, $this->maxblobsize);
-
- while($string = fbird_blob_get($blobid, 8192)) {
- $realblob .= $string;
+ if ($blob_data[0] > $this->maxblobsize) {
+ $realBlob = fbird_blob_get($blobId, $this->maxblobsize);
+ while ($string = fbird_blob_get($blobId, 8192)) {
+ $realBlob .= $string;
}
} else {
- $realblob = fbird_blob_get($blobid, $blob_data[0]);
+ $realBlob = fbird_blob_get($blobId, $blob_data[0]);
}
- fbird_blob_close( $blobid );
- return( $realblob );
+ fbird_blob_close($blobId);
+ return $realBlob;
}
- function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
+ /**
+ * Insert blob data into a database column directly
+ * from file
+ *
+ * @param string $table table to insert
+ * @param string $column column to insert
+ * @param string $path physical file name
+ * @param string $where string to find unique record
+ * @param string $blobtype BLOB or CLOB
+ *
+ * @return bool success
+ */
+ public function updateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
{
$fd = fopen($path,'rb');
- if ($fd === false) return false;
+ if ($fd === false)
+ return false;
+
$blob_id = fbird_blob_create($this->_connectionID);
/* fill with data */
@@ -617,105 +832,106 @@ class ADODB_firebird extends ADOConnection {
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
}
- /*
- Insert a null into the blob field of the table first.
- Then use UpdateBlob to store the blob.
-
- Usage:
-
- $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
- $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
- */
- function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
- {
- $blob_id = fbird_blob_create($this->_connectionID);
-
- // fbird_blob_add($blob_id, $val);
-
- // replacement that solves the problem by which only the first modulus 64K /
- // of $val are stored at the blob field ////////////////////////////////////
- // Thx Abel Berenstein aberenstein#afip.gov.ar
- $len = strlen($val);
- $chunk_size = 32768;
- $tail_size = $len % $chunk_size;
- $n_chunks = ($len - $tail_size) / $chunk_size;
-
- for ($n = 0; $n < $n_chunks; $n++) {
- $start = $n * $chunk_size;
- $data = substr($val, $start, $chunk_size);
- fbird_blob_add($blob_id, $data);
- }
-
- if ($tail_size) {
- $start = $n_chunks * $chunk_size;
- $data = substr($val, $start, $tail_size);
- fbird_blob_add($blob_id, $data);
- }
- // end replacement /////////////////////////////////////////////////////////
-
- $blob_id_str = fbird_blob_close($blob_id);
-
- return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
-
- }
-
-
- function OldUpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
+ /**
+ * Insert blob data into a database column
+ *
+ * @param string $table table to insert
+ * @param string $column column to insert
+ * @param string $val value to insert
+ * @param string $where string to find unique record
+ * @param string $blobtype BLOB or CLOB
+ *
+ * @return bool success
+ */
+ public function updateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
$blob_id = fbird_blob_create($this->_connectionID);
- fbird_blob_add($blob_id, $val);
+
+ // fbird_blob_add($blob_id, $val);
+
+ // replacement that solves the problem by which only the first modulus 64K /
+ // of $val are stored at the blob field ////////////////////////////////////
+ // Thx Abel Berenstein aberenstein#afip.gov.ar
+ $len = strlen($val);
+ $chunk_size = 32768;
+ $tail_size = $len % $chunk_size;
+ $n_chunks = ($len - $tail_size) / $chunk_size;
+
+ for ($n = 0; $n < $n_chunks; $n++) {
+ $start = $n * $chunk_size;
+ $data = substr($val, $start, $chunk_size);
+ fbird_blob_add($blob_id, $data);
+ }
+
+ if ($tail_size) {
+ $start = $n_chunks * $chunk_size;
+ $data = substr($val, $start, $tail_size);
+ fbird_blob_add($blob_id, $data);
+ }
+ // end replacement /////////////////////////////////////////////////////////
+
$blob_id_str = fbird_blob_close($blob_id);
- return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
+
+ return $this->execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
+
}
- // Format date column in sql string given an input format that understands Y M D
- // Only since Interbase 6.0 - uses EXTRACT
- // problem - does not zero-fill the day and month yet
- function SQLDate($fmt, $col=false)
+
+ /**
+ * Returns a portably-formatted date string from a timestamp database column.
+ *
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:sqldate
+ *
+ * Firebird does not support an AM/PM format, so the A indicator always shows AM
+ *
+ * @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 string The SQL DATE_FORMAT() string, or empty if the provided date format was empty.
+ */
+ public function sqlDate($fmt, $col=false)
{
- if (!$col) $col = $this->sysDate;
+ if (!$col)
+ $col = 'CURRENT_TIMESTAMP';
+
$s = '';
$len = strlen($fmt);
for ($i=0; $i < $len; $i++) {
if ($s) $s .= '||';
$ch = $fmt[$i];
- switch($ch) {
+ $choice = strtoupper($ch);
+ switch($choice) {
case 'Y':
- case 'y':
- $s .= "extract(year from $col)";
+ $s .= "EXTRACT(YEAR FROM $col)";
break;
case 'M':
- case 'm':
- $s .= "extract(month from $col)";
+ $s .= "RIGHT('0' || TRIM(EXTRACT(MONTH FROM $col)),2)";
break;
case 'W':
- case 'w':
// The more accurate way of doing this is with a stored procedure
// See http://wiki.firebirdsql.org/wiki/index.php?page=DATE+Handling+Functions for details
- $s .= "((extract(yearday from $col) - extract(weekday from $col - 1) + 7) / 7)";
+ $s .= "((EXTRACT(YEARDAY FROM $col) - EXTRACT(WEEKDAY FROM $col - 1) + 7) / 7)";
break;
case 'Q':
- case 'q':
- $s .= "cast(((extract(month from $col)+2) / 3) as integer)";
+ $s .= "CAST(((EXTRACT(MONTH FROM $col)+2) / 3) AS INTEGER)";
break;
case 'D':
- case 'd':
- $s .= "(extract(day from $col))";
+ $s .= "RIGHT('0' || TRIM(EXTRACT(DAY FROM $col)),2)";
break;
case 'H':
- case 'h':
- $s .= "(extract(hour from $col))";
+ $s .= "RIGHT('0' || TRIM(EXTRACT(HOUR FROM $col)),2)";
break;
case 'I':
- case 'i':
- $s .= "(extract(minute from $col))";
+ $s .= "RIGHT('0' || TRIM(EXTRACT(MINUTE FROM $col)),2)";
break;
case 'S':
- case 's':
- $s .= "CAST((extract(second from $col)) AS INTEGER)";
+ //$s .= "CAST((EXTRACT(SECOND FROM $col)) AS INTEGER)";
+ $s .= "RIGHT('0' || TRIM(EXTRACT(SECOND FROM $col)),2)";
+ break;
+ case 'A':
+ $s .= $this->qstr('AM');
break;
-
default:
if ($ch == '\\') {
$i++;
@@ -728,10 +944,44 @@ class ADODB_firebird extends ADOConnection {
return $s;
}
+ /**
+ * Creates a portable date offset field, for use in SQL statements.
+ *
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:offsetdate
+ *
+ * @param float $dayFraction A day in floating point
+ * @param string|bool $date (Optional) The date to offset. If false, uses CURDATE()
+ *
+ * @return string
+ */
+ public function offsetDate($dayFraction, $date=false)
+ {
+ if (!$date)
+ $date = $this->sysTimeStamp;
+
+ $fraction = $dayFraction * 24 * 3600;
+ return sprintf("DATEADD (second, %s, %s) FROM RDB\$DATABASE",$fraction,$date);
+ }
+
+
// Note that Interbase 6.5 uses this ROWS instead - don't you love forking wars!
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
+ /**
+ * Executes a provided SQL statement and returns a handle to the result, with the ability to supply a starting
+ * offset and record count.
+ *
+ * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:selectlimit
+ *
+ * @param string $sql The SQL to execute.
+ * @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 $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.
+ */
+ public function selectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs2cache=0)
{
$nrows = (integer) $nrows;
$offset = (integer) $offset;
@@ -740,46 +990,88 @@ class ADODB_firebird extends ADOConnection {
$str .=($offset>=0) ? "SKIP $offset " : '';
$sql = preg_replace('/^[ \t]*select/i',$str,$sql);
- if ($secs)
- $rs = $this->CacheExecute($secs,$sql,$inputarr);
+ if ($secs2cache)
+ $rs = $this->cacheExecute($secs2cache,$sql,$inputarr);
else
- $rs = $this->Execute($sql,$inputarr);
+ $rs = $this->execute($sql,$inputarr);
return $rs;
}
}
-/*--------------------------------------------------------------------------------------
- Class Name: Recordset
---------------------------------------------------------------------------------------*/
-
-class ADORecordset_firebird extends ADORecordSet
+/**
+ * Class ADORecordset_firebird
+ */
+class ADORecordset_firebird extends ADORecordSet
{
-
var $databaseType = "firebird";
- var $bind=false;
- var $_cacheType;
-
- function __construct($id,$mode=false)
- {
- global $ADODB_FETCH_MODE;
-
- $this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;
- parent::__construct($id);
- }
+ var $bind = false;
/**
- * Get column information in the Recordset object.
- * fetchField() can be used in order to obtain information about fields in
- * a certain query result. If the field offset isn't specified, the next
- * field that wasn't yet retrieved by fetchField() is retrieved.
- * @return object containing field information.
- */
- function FetchField($fieldOffset = -1)
+ * @var ADOFieldObject[] Holds a cached version of the metadata
+ */
+ private $fieldObjects = false;
+
+ /**
+ * @var bool Flags if we have retrieved the metadata
+ */
+ private $fieldObjectsRetrieved = false;
+
+ /**
+ * @var array Cross-reference the objects by name for easy access
+ */
+ private $fieldObjectsIndex = array();
+
+ /**
+ * @var bool Flag to indicate if the result has a blob
+ */
+ private $fieldObjectsHaveBlob = false;
+
+ function __construct($id, $mode = false)
{
+ global $ADODB_FETCH_MODE;
+
+ $this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;
+ parent::__construct($id);
+ }
+
+
+ /**
+ * Returns: an object containing field information.
+ *
+ * Get column information in the Recordset object. fetchField()
+ * can be used in order to obtain information about fields in a
+ * certain query result. If the field offset isn't specified,
+ * the next field that wasn't yet retrieved by fetchField()
+ * is retrieved.
+ *
+ * $param int $fieldOffset (optional default=-1 for all
+ * @return mixed an ADOFieldObject, or array of objects
+ */
+ private function _fetchField($fieldOffset = -1)
+ {
+ if ($this->fieldObjectsRetrieved) {
+ if ($this->fieldObjects) {
+ // Already got the information
+ if ($fieldOffset == -1) {
+ return $this->fieldObjects;
+ } else {
+ return $this->fieldObjects[$fieldOffset];
+ }
+ } else {
+ // No metadata available
+ return false;
+ }
+ }
+
+ // Populate the field objects cache
+ $this->fieldObjectsRetrieved = true;
+ $this->fieldObjectsHaveBlob = false;
+ $this->_numOfFields = fbird_num_fields($this->_queryID);
+ for ($fieldIndex = 0; $fieldIndex < $this->_numOfFields; $fieldIndex++) {
$fld = new ADOFieldObject;
- $ibf = fbird_field_info($this->_queryID,$fieldOffset);
+ $ibf = fbird_field_info($this->_queryID, $fieldIndex);
$name = empty($ibf['alias']) ? $ibf['name'] : $ibf['alias'];
@@ -799,23 +1091,54 @@ class ADORecordset_firebird extends ADORecordSet
$fld->type = $ibf['type'];
$fld->max_length = $ibf['length'];
- /* This needs to be populated from the metadata */
+ // This needs to be populated from the metadata
$fld->not_null = false;
$fld->has_default = false;
$fld->default_value = 'null';
- return $fld;
+
+ $this->fieldObjects[$fieldIndex] = $fld;
+ $this->fieldObjectsIndex[$fld->name] = $fieldIndex;
+
+ if ($fld->type == 'BLOB') {
+ $this->fieldObjectsHaveBlob = true;
+ }
+ }
+
+ if ($fieldOffset == -1) {
+ return $this->fieldObjects;
+ }
+
+ return $this->fieldObjects[$fieldOffset];
+ }
+
+ /**
+ * Fetchfield copies the oracle method, it loads the field information
+ * into the _fieldobjs array once, to save multiple calls to the
+ * fbird_ function
+ *
+ * @param int $fieldOffset (optional)
+ *
+ * @return adoFieldObject|false
+ */
+ public function fetchField($fieldOffset = -1)
+ {
+ if ($fieldOffset == -1) {
+ return $this->fieldObjects;
+ }
+
+ return $this->fieldObjects[$fieldOffset];
}
function _initrs()
{
$this->_numOfRows = -1;
- $this->_numOfFields = @fbird_num_fields($this->_queryID);
- // cache types for blob decode check
- for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
- $f1 = $this->FetchField($i);
- $this->_cacheType[] = $f1->type;
- }
+ /*
+ * Retrieve all of the column information first. We copy
+ * this method from oracle
+ */
+ $this->_fetchField();
+
}
function _seek($row)
@@ -823,98 +1146,171 @@ class ADORecordset_firebird extends ADORecordSet
return false;
}
- function _fetch()
+ public function _fetch()
{
- $f = @fbird_fetch_row($this->_queryID);
+ // Case conversion function for use in Closure defined below
+ $localFnCaseConv = null;
+
+ if ($this->fetchMode & ADODB_FETCH_ASSOC) {
+ // Handle either associative or fetch both
+ $localNumeric = false;
+
+ $f = @fbird_fetch_assoc($this->_queryID);
+ if (is_array($f)) {
+ // Optimally do the case_upper or case_lower
+ if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER) {
+ $f = array_change_key_case($f, CASE_LOWER);
+ $localFnCaseConv = 'strtolower';
+ } elseif (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_UPPER) {
+ $f = array_change_key_case($f, CASE_UPPER);
+ $localFnCaseConv = 'strtoupper';
+ }
+ }
+ } else {
+ // Numeric fetch mode
+ $localNumeric = true;
+ $f = @fbird_fetch_row($this->_queryID);
+ }
+
if ($f === false) {
$this->fields = false;
return false;
}
+
// OPN stuff start - optimized
// fix missing nulls and decode blobs automatically
-
global $ADODB_ANSI_PADDING_OFF;
- //$ADODB_ANSI_PADDING_OFF=1;
$rtrim = !empty($ADODB_ANSI_PADDING_OFF);
- for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
- if ($this->_cacheType[$i]=="BLOB") {
- if (isset($f[$i])) {
- $f[$i] = $this->connection->_BlobDecode($f[$i]);
+ // For optimal performance, only process if there is a possibility of something to do
+ if ($this->fieldObjectsHaveBlob || $rtrim) {
+ $localFieldObjects = $this->fieldObjects;
+ $localFieldObjectIndex = $this->fieldObjectsIndex;
+ /** @var ADODB_firebird $localConnection */
+ $localConnection = &$this->connection;
+
+ /**
+ * Closure for an efficient method of iterating over the elements.
+ * @param mixed $value
+ * @param string|int $key
+ * @return void
+ */
+ $rowTransform = function ($value, $key) use (
+ &$f,
+ $rtrim,
+ $localFieldObjects,
+ $localConnection,
+ $localNumeric,
+ $localFnCaseConv,
+ $localFieldObjectIndex
+ ) {
+ if ($localNumeric) {
+ $localKey = $key;
} else {
- $f[$i] = null;
+ // Cross-reference the associative key back to numeric
+ // with appropriate case conversion
+ $index = $localFnCaseConv ? $localFnCaseConv($key) : $key;
+ $localKey = $localFieldObjectIndex[$index];
}
- } else {
- if (!isset($f[$i])) {
- $f[$i] = null;
- } else if ($rtrim && is_string($f[$i])) {
- $f[$i] = rtrim($f[$i]);
+
+ // As we iterate the elements check for blobs and padding
+ if ($localFieldObjects[$localKey]->type == 'BLOB') {
+ $f[$key] = $localConnection->_BlobDecode($value);
+ } else {
+ if ($rtrim && is_string($value)) {
+ $f[$key] = rtrim($value);
+ }
}
- }
+
+ };
+
+ // Walk the array, applying the above closure
+ array_walk($f, $rowTransform);
+ }
+
+ if (!$localNumeric && $this->fetchMode & ADODB_FETCH_NUM) {
+ // Creates a fetch both
+ $fNum = array_values($f);
+ $f = array_merge($f, $fNum);
}
- // OPN stuff end
$this->fields = $f;
- if ($this->fetchMode == ADODB_FETCH_ASSOC) {
- $this->fields = $this->GetRowAssoc();
- } else if ($this->fetchMode == ADODB_FETCH_BOTH) {
- $this->fields = array_merge($this->fields,$this->GetRowAssoc());
- }
+
return true;
}
- /* Use associative array to get fields array */
- function Fields($colname)
+ /**
+ * Get the value of a field in the current row by column name.
+ * Will not work if ADODB_FETCH_MODE is set to ADODB_FETCH_NUM.
+ *
+ * @param string $colname is the field to access
+ *
+ * @return mixed the value of $colname column
+ */
+ public function fields($colname)
{
- if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
+ if ($this->fetchMode & ADODB_FETCH_ASSOC) {
+ return $this->fields[$colname];
+ }
+
if (!$this->bind) {
- $this->bind = array();
- for ($i=0; $i < $this->_numOfFields; $i++) {
- $o = $this->FetchField($i);
- $this->bind[strtoupper($o->name)] = $i;
- }
+ // fieldsObjectIndex populated by the recordset load
+ $this->bind = array_change_key_case($this->fieldObjectsIndex, CASE_UPPER);
}
return $this->fields[$this->bind[strtoupper($colname)]];
-
}
function _close()
{
- return @fbird_free_result($this->_queryID);
+ return @fbird_free_result($this->_queryID);
}
- function MetaType($t,$len=-1,$fieldobj=false)
+ public function metaType($t, $len = -1, $fieldObj = false)
{
if (is_object($t)) {
- $fieldobj = $t;
- $t = $fieldobj->type;
- $len = $fieldobj->max_length;
+ $fieldObj = $t;
+ $t = $fieldObj->type;
+ $len = $fieldObj->max_length;
}
- switch (strtoupper($t)) {
- case 'CHAR':
- return 'C';
- case 'TEXT':
- case 'VARCHAR':
- case 'VARYING':
- if ($len <= $this->blobSize) return 'C';
- return 'X';
- case 'BLOB':
- return 'B';
+ $t = strtoupper($t);
- case 'TIMESTAMP':
- case 'DATE': return 'D';
- case 'TIME': return 'T';
- //case 'T': return 'T';
+ if (array_key_exists($t, $this->connection->customActualTypes)) {
+ return $this->connection->customActualTypes[$t];
+ }
- //case 'L': return 'L';
- case 'INT':
- case 'SHORT':
- case 'INTEGER': return 'I';
- default: return ADODB_DEFAULT_METATYPE;
+ switch ($t) {
+ case 'CHAR':
+ return 'C';
+
+ case 'TEXT':
+ case 'VARCHAR':
+ case 'VARYING':
+ if ($len <= $this->blobSize) {
+ return 'C';
+ }
+ return 'X';
+ case 'BLOB':
+ return 'B';
+
+ case 'TIMESTAMP':
+ case 'DATE':
+ return 'D';
+ case 'TIME':
+ return 'T';
+ //case 'T': return 'T';
+
+ //case 'L': return 'L';
+ case 'INT':
+ case 'SHORT':
+ case 'INTEGER':
+ return 'I';
+ default:
+ return ADODB_DEFAULT_METATYPE;
}
}
}
+
diff --git a/lib/adodb/drivers/adodb-ibase.inc.php b/lib/adodb/drivers/adodb-ibase.inc.php
index 69de30dcca7..81ab29b56ec 100644
--- a/lib/adodb/drivers/adodb-ibase.inc.php
+++ b/lib/adodb/drivers/adodb-ibase.inc.php
@@ -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';
diff --git a/lib/adodb/drivers/adodb-informix72.inc.php b/lib/adodb/drivers/adodb-informix72.inc.php
index a9c43e2318a..79e5138a9ce 100644
--- a/lib/adodb/drivers/adodb-informix72.inc.php
+++ b/lib/adodb/drivers/adodb-informix72.inc.php
@@ -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,
diff --git a/lib/adodb/drivers/adodb-mssql.inc.php b/lib/adodb/drivers/adodb-mssql.inc.php
index 3de3f8d33ce..8fb92249ccd 100644
--- a/lib/adodb/drivers/adodb-mssql.inc.php
+++ b/lib/adodb/drivers/adodb-mssql.inc.php
@@ -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;
diff --git a/lib/adodb/drivers/adodb-mssqlnative.inc.php b/lib/adodb/drivers/adodb-mssqlnative.inc.php
index 36dc543396a..89eb42ed763 100644
--- a/lib/adodb/drivers/adodb-mssqlnative.inc.php
+++ b/lib/adodb/drivers/adodb-mssqlnative.inc.php
@@ -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);
+
+ }
+
}
/*--------------------------------------------------------------------------------------
diff --git a/lib/adodb/drivers/adodb-mysql.inc.php b/lib/adodb/drivers/adodb-mysql.inc.php
deleted file mode 100644
index f07c081b527..00000000000
--- a/lib/adodb/drivers/adodb-mysql.inc.php
+++ /dev/null
@@ -1,932 +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"
- 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"
- 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);
- }
-}
-
-}
diff --git a/lib/adodb/drivers/adodb-mysqli.inc.php b/lib/adodb/drivers/adodb-mysqli.inc.php
index 160f5fa3406..0100e7f832b 100644
--- a/lib/adodb/drivers/adodb-mysqli.inc.php
+++ b/lib/adodb/drivers/adodb-mysqli.inc.php
@@ -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 "
--- Error in type matching $t -----
";
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':
diff --git a/lib/adodb/drivers/adodb-mysqlpo.inc.php b/lib/adodb/drivers/adodb-mysqlpo.inc.php
deleted file mode 100644
index 8aa7779ad46..00000000000
--- a/lib/adodb/drivers/adodb-mysqlpo.inc.php
+++ /dev/null
@@ -1,124 +0,0 @@
-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);
- }
-}
diff --git a/lib/adodb/drivers/adodb-mysqlt.inc.php b/lib/adodb/drivers/adodb-mysqlt.inc.php
deleted file mode 100644
index cccd93f8d34..00000000000
--- a/lib/adodb/drivers/adodb-mysqlt.inc.php
+++ /dev/null
@@ -1,141 +0,0 @@
-_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);
- }
-}
diff --git a/lib/adodb/drivers/adodb-oci8.inc.php b/lib/adodb/drivers/adodb-oci8.inc.php
index e541b6b6a0a..c1f4e502053 100644
--- a/lib/adodb/drivers/adodb-oci8.inc.php
+++ b/lib/adodb/drivers/adodb-oci8.inc.php
@@ -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':
diff --git a/lib/adodb/drivers/adodb-odbc_mssql.inc.php b/lib/adodb/drivers/adodb-odbc_mssql.inc.php
index 37185aac32d..9f53d3d7c3d 100644
--- a/lib/adodb/drivers/adodb-odbc_mssql.inc.php
+++ b/lib/adodb/drivers/adodb-odbc_mssql.inc.php
@@ -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;
diff --git a/lib/adodb/drivers/adodb-odbtp.inc.php b/lib/adodb/drivers/adodb-odbtp.inc.php
index bd167a1c8c8..41bd0873bac 100644
--- a/lib/adodb/drivers/adodb-odbtp.inc.php
+++ b/lib/adodb/drivers/adodb-odbtp.inc.php
@@ -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;
diff --git a/lib/adodb/drivers/adodb-pdo.inc.php b/lib/adodb/drivers/adodb-pdo.inc.php
index cf8e4e2644b..e0e6c729724 100644
--- a/lib/adodb/drivers/adodb-pdo.inc.php
+++ b/lib/adodb/drivers/adodb-pdo.inc.php
@@ -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
*/
diff --git a/lib/adodb/drivers/adodb-pdo_oci.inc.php b/lib/adodb/drivers/adodb-pdo_oci.inc.php
index 9a05ee6a9cb..20b47deffe1 100644
--- a/lib/adodb/drivers/adodb-pdo_oci.inc.php
+++ b/lib/adodb/drivers/adodb-pdo_oci.inc.php
@@ -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);
+ }
}
diff --git a/lib/adodb/drivers/adodb-pdo_pgsql.inc.php b/lib/adodb/drivers/adodb-pdo_pgsql.inc.php
index 0212d4fda64..6c06ac10319 100644
--- a/lib/adodb/drivers/adodb-pdo_pgsql.inc.php
+++ b/lib/adodb/drivers/adodb-pdo_pgsql.inc.php
@@ -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);
+ }
}
diff --git a/lib/adodb/drivers/adodb-pdo_sqlite.inc.php b/lib/adodb/drivers/adodb-pdo_sqlite.inc.php
index b62ca35ed96..dab1de993fc 100644
--- a/lib/adodb/drivers/adodb-pdo_sqlite.inc.php
+++ b/lib/adodb/drivers/adodb-pdo_sqlite.inc.php
@@ -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);
+ }
}
diff --git a/lib/adodb/drivers/adodb-postgres64.inc.php b/lib/adodb/drivers/adodb-postgres64.inc.php
index 3f351f97463..290967e7b57 100644
--- a/lib/adodb/drivers/adodb-postgres64.inc.php
+++ b/lib/adodb/drivers/adodb-postgres64.inc.php
@@ -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;
}
diff --git a/lib/adodb/drivers/adodb-postgres7.inc.php b/lib/adodb/drivers/adodb-postgres7.inc.php
index 59174f67884..b5e63acface 100644
--- a/lib/adodb/drivers/adodb-postgres7.inc.php
+++ b/lib/adodb/drivers/adodb-postgres7.inc.php
@@ -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;
}
diff --git a/lib/adodb/drivers/adodb-sqlite3.inc.php b/lib/adodb/drivers/adodb-sqlite3.inc.php
index 548727d8bce..318171a8c5e 100644
--- a/lib/adodb/drivers/adodb-sqlite3.inc.php
+++ b/lib/adodb/drivers/adodb-sqlite3.inc.php
@@ -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;
diff --git a/lib/adodb/perf/perf-mysql.inc.php b/lib/adodb/perf/perf-mysql.inc.php
index dae44229d4f..ed92c8051df 100644
--- a/lib/adodb/perf/perf-mysql.inc.php
+++ b/lib/adodb/perf/perf-mysql.inc.php
@@ -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)
{
diff --git a/lib/adodb/perf/perf-postgres.inc.php b/lib/adodb/perf/perf-postgres.inc.php
index 315c17f5c28..16b767d206f 100644
--- a/lib/adodb/perf/perf-postgres.inc.php
+++ b/lib/adodb/perf/perf-postgres.inc.php
@@ -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);
diff --git a/lib/adodb/perf/perf-sqlite3.inc.php b/lib/adodb/perf/perf-sqlite3.inc.php
new file mode 100644
index 00000000000..19198d5b308
--- /dev/null
+++ b/lib/adodb/perf/perf-sqlite3.inc.php
@@ -0,0 +1,40 @@
+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;
+ }
+}
diff --git a/lib/adodb/phpdoc.dist.xml b/lib/adodb/phpdoc.dist.xml
new file mode 100644
index 00000000000..bbddd3db705
--- /dev/null
+++ b/lib/adodb/phpdoc.dist.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ docs/cache
+
+
+
+
+
+
+ scripts
+ tests
+ vendor/**/*
+ xsl
+
+
+
+
diff --git a/lib/adodb/readme_moodle.txt b/lib/adodb/readme_moodle.txt
index 7c64f5d3ce7..be981c8fbe1 100644
--- a/lib/adodb/readme_moodle.txt
+++ b/lib/adodb/readme_moodle.txt
@@ -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
diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml
index d76d534bcc0..db1a32b40c7 100644
--- a/lib/thirdpartylibs.xml
+++ b/lib/thirdpartylibs.xml
@@ -4,7 +4,7 @@
adodbAdoDBBSD/LGPL
- 5.21.4
+ 5.22.23-Clause/2.1+