Initial Commit

merge-requests/1/head 1.1.4
Abel Hoogeveen 4 years ago
commit f12557f7ea
  1. 5
      .gitattributes
  2. 5
      .gitignore
  3. 21
      LICENSE
  4. 28
      composer.json
  5. 207
      src/Database/DB.php
  6. 220
      src/Database/DB_cache.php
  7. 2001
      src/Database/DB_driver.php
  8. 1036
      src/Database/DB_forge.php
  9. 2785
      src/Database/DB_query_builder.php
  10. 670
      src/Database/DB_result.php
  11. 438
      src/Database/DB_utility.php
  12. 405
      src/Database/drivers/cubrid/cubrid_driver.php
  13. 228
      src/Database/drivers/cubrid/cubrid_forge.php
  14. 178
      src/Database/drivers/cubrid/cubrid_result.php
  15. 80
      src/Database/drivers/cubrid/cubrid_utility.php
  16. 396
      src/Database/drivers/ibase/ibase_driver.php
  17. 252
      src/Database/drivers/ibase/ibase_forge.php
  18. 162
      src/Database/drivers/ibase/ibase_result.php
  19. 70
      src/Database/drivers/ibase/ibase_utility.php
  20. 547
      src/Database/drivers/mysqli/mysqli_driver.php
  21. 244
      src/Database/drivers/mysqli/mysqli_forge.php
  22. 186
      src/Database/drivers/mysqli/mysqli_result.php
  23. 213
      src/Database/drivers/mysqli/mysqli_utility.php
  24. 684
      src/Database/drivers/oci8/oci8_driver.php
  25. 150
      src/Database/drivers/oci8/oci8_forge.php
  26. 230
      src/Database/drivers/oci8/oci8_result.php
  27. 69
      src/Database/drivers/oci8/oci8_utility.php
  28. 378
      src/Database/drivers/odbc/odbc_driver.php
  29. 86
      src/Database/drivers/odbc/odbc_forge.php
  30. 268
      src/Database/drivers/odbc/odbc_result.php
  31. 63
      src/Database/drivers/odbc/odbc_utility.php
  32. 375
      src/Database/drivers/pdo/pdo_driver.php
  33. 65
      src/Database/drivers/pdo/pdo_forge.php
  34. 198
      src/Database/drivers/pdo/pdo_result.php
  35. 63
      src/Database/drivers/pdo/pdo_utility.php
  36. 200
      src/Database/drivers/pdo/subdrivers/pdo_4d_driver.php
  37. 218
      src/Database/drivers/pdo/subdrivers/pdo_4d_forge.php
  38. 250
      src/Database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
  39. 228
      src/Database/drivers/pdo/subdrivers/pdo_cubrid_forge.php
  40. 332
      src/Database/drivers/pdo/subdrivers/pdo_dblib_driver.php
  41. 145
      src/Database/drivers/pdo/subdrivers/pdo_dblib_forge.php
  42. 263
      src/Database/drivers/pdo/subdrivers/pdo_firebird_driver.php
  43. 238
      src/Database/drivers/pdo/subdrivers/pdo_firebird_forge.php
  44. 244
      src/Database/drivers/pdo/subdrivers/pdo_ibm_driver.php
  45. 155
      src/Database/drivers/pdo/subdrivers/pdo_ibm_forge.php
  46. 309
      src/Database/drivers/pdo/subdrivers/pdo_informix_driver.php
  47. 164
      src/Database/drivers/pdo/subdrivers/pdo_informix_forge.php
  48. 339
      src/Database/drivers/pdo/subdrivers/pdo_mysql_driver.php
  49. 257
      src/Database/drivers/pdo/subdrivers/pdo_mysql_forge.php
  50. 326
      src/Database/drivers/pdo/subdrivers/pdo_oci_driver.php
  51. 150
      src/Database/drivers/pdo/subdrivers/pdo_oci_forge.php
  52. 284
      src/Database/drivers/pdo/subdrivers/pdo_odbc_driver.php
  53. 71
      src/Database/drivers/pdo/subdrivers/pdo_odbc_forge.php
  54. 384
      src/Database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
  55. 211
      src/Database/drivers/pdo/subdrivers/pdo_pgsql_forge.php
  56. 219
      src/Database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
  57. 239
      src/Database/drivers/pdo/subdrivers/pdo_sqlite_forge.php
  58. 369
      src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
  59. 145
      src/Database/drivers/pdo/subdrivers/pdo_sqlsrv_forge.php
  60. 622
      src/Database/drivers/postgre/postgre_driver.php
  61. 205
      src/Database/drivers/postgre/postgre_forge.php
  62. 182
      src/Database/drivers/postgre/postgre_result.php
  63. 78
      src/Database/drivers/postgre/postgre_utility.php
  64. 332
      src/Database/drivers/sqlite/sqlite_driver.php
  65. 206
      src/Database/drivers/sqlite/sqlite_forge.php
  66. 165
      src/Database/drivers/sqlite/sqlite_result.php
  67. 62
      src/Database/drivers/sqlite/sqlite_utility.php
  68. 353
      src/Database/drivers/sqlite3/sqlite3_driver.php
  69. 226
      src/Database/drivers/sqlite3/sqlite3_forge.php
  70. 195
      src/Database/drivers/sqlite3/sqlite3_result.php
  71. 62
      src/Database/drivers/sqlite3/sqlite3_utility.php
  72. 542
      src/Database/drivers/sqlsrv/sqlsrv_driver.php
  73. 145
      src/Database/drivers/sqlsrv/sqlsrv_forge.php
  74. 194
      src/Database/drivers/sqlsrv/sqlsrv_result.php
  75. 78
      src/Database/drivers/sqlsrv/sqlsrv_utility.php
  76. 288
      src/FuzeWorks/Database.php
  77. 56
      src/FuzeWorks/DatabaseComponent.php
  78. 146
      src/FuzeWorks/DatabaseTracyBridge.php
  79. 85
      src/FuzeWorks/Event/DatabaseLoadDriverEvent.php
  80. 77
      src/FuzeWorks/Event/DatabaseLoadForgeEvent.php
  81. 77
      src/FuzeWorks/Event/DatabaseLoadUtilEvent.php
  82. 49
      src/FuzeWorks/Exception/DatabaseException.php
  83. 63
      test/autoload.php
  84. 58
      test/bootstrap.php
  85. 67
      test/database/DatabaseTest.php
  86. 68
      test/database/DatabaseTestAbstract.php
  87. 34
      test/phpunit.xml
  88. 0
      test/temp/placeholder

5
.gitattributes vendored

@ -0,0 +1,5 @@
.gitattributes export-ignore
.gitignore export-ignore
.gitlab-ci.yml export-ignore
tests/ export-ignore
CI/ export-ignore

5
.gitignore vendored

@ -0,0 +1,5 @@
composer.phar
composer.lock
.idea/
build/
vendor/

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013-2018 TechFuze
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,28 @@
{
"name": "fuzeworks/database",
"description": "FuzeWorks Framework Database Component",
"homepage": "https://techfuze.net/fuzeworks",
"license": ["MIT"],
"authors": [
{
"name": "TechFuze",
"homepage": "https://techfuze.net"
},
{
"name": "FuzeWorks Community",
"homepage": "https://techfuze.net/fuzeworks/contributors"
}
],
"require": {
"php": ">=7.1.0"
},
"require-dev": {
"phpunit/phpunit": "^7",
"fuzeworks/core": "1.2.0-BETA"
},
"autoload": {
"psr-4": {
"FuzeWorks\\": "src/FuzeWorks/"
}
}
}

@ -0,0 +1,207 @@
<?php
/**
* FuzeWorks Framework Database Component.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2018 TechFuze
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author TechFuze
* @copyright Copyright (c) 2013 - 2018, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 1.1.4
*
* @version Version 1.1.4
*/
use FuzeWorks\Factory;
use FuzeWorks\Database;
use FuzeWorks\Exception\DatabaseException;
use FuzeWorks\Core;
/**
* Initialize the database
*
* Converted from CodeIgniter.
*
* @package FuzeWorks
* @category Database
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
* @license http://opensource.org/licenses/MIT MIT License
*
* @param string|string[] $params
* @param bool $query_builder_override
* Determines if query builder should be used or not
* @return mixed
* @throws DatabaseException
*/
function &DB($params = '', $query_builder_override = NULL)
{
// Load the DB config file if a DSN string wasn't passed
if (is_string($params) && strpos($params, '://') === FALSE)
{
// First retrieve the config file
try {
$config = Factory::getInstance()->config->get('database');
} catch (ConfigException $e) {
throw new DatabaseException($e->getMessage(), 1);
}
// Determine if there are actually settings in the config file
if ( ! isset($config->databases) OR count($config->databases) === 0)
{
throw new DatabaseException('No database connection settings were found in the database config file.', 1);
}
// Define the active group
$active_group = ($params !== '' ? $params : $config->active_group);
if ( ! isset($active_group))
{
throw new DatabaseException('You have not specified a database connection group via $active_group in your config.database.php file.', 1);
}
elseif ( ! isset($config->databases[$active_group]))
{
throw new DatabaseException('You have specified an invalid database connection group ('.$active_group.') in your config.database.php file.', 1);
}
$params = $config->databases[$active_group];
}
elseif (is_string($params))
{
/**
* Parse the URL from the DSN string
* Database settings can be passed as discreet
* parameters or as a data source name in the first
* parameter. DSNs must have this prototype:
* $dsn = 'driver://username:password@hostname/database';
*/
if (($dsn = @parse_url($params)) === FALSE)
{
throw new DatabaseException('Invalid DB Connection String', 1);
}
$params = array(
'dbdriver' => $dsn['scheme'],
'hostname' => isset($dsn['host']) ? rawurldecode($dsn['host']) : '',
'port' => isset($dsn['port']) ? rawurldecode($dsn['port']) : '',
'username' => isset($dsn['user']) ? rawurldecode($dsn['user']) : '',
'password' => isset($dsn['pass']) ? rawurldecode($dsn['pass']) : '',
'database' => isset($dsn['path']) ? rawurldecode(substr($dsn['path'], 1)) : ''
);
// Were additional config items set?
if (isset($dsn['query']))
{
parse_str($dsn['query'], $extra);
foreach ($extra as $key => $val)
{
if (is_string($val) && in_array(strtoupper($val), array('TRUE', 'FALSE', 'NULL')))
{
$val = var_export($val, TRUE);
}
$params[$key] = $val;
}
}
}
// No DB specified yet? Beat them senseless...
if (empty($params['dbdriver']))
{
throw new DatabaseException('You have not selected a database type to connect to.', 1);
}
// Load the DB classes. Note: Since the query builder class is optional
// we need to dynamically create a class that extends proper parent class
// based on whether we're using the query builder class or not.
if ($query_builder_override !== NULL)
{
$query_builder = $query_builder_override;
}
// Backwards compatibility work-around for keeping the
// $active_record config variable working. Should be
// removed in v3.1
elseif ( ! isset($query_builder) && isset($active_record))
{
$query_builder = $active_record;
}
require_once(dirname(__DIR__) . DS . 'Database'.DS.'DB_driver.php');
if ( ! isset($query_builder) OR $query_builder === TRUE)
{
require_once(dirname(__DIR__) . DS . 'Database'.DS.'DB_query_builder.php');
if ( ! class_exists('FW_DB', FALSE))
{
/**
* FW_DB
*
* Acts as an alias for both FW_DB_driver and FW_DB_query_builder.
*
* @see FW_DB_query_builder
* @see FW_DB_driver
*/
class FW_DB extends FW_DB_query_builder { }
}
}
elseif ( ! class_exists('FW_DB', FALSE))
{
/**
* @ignore
*/
class FW_DB extends FW_DB_driver { }
}
// Load the DB driver
$driver_file = dirname(__DIR__) . DS . 'Database'.DS.'drivers'.DS.$params['dbdriver'].DS.$params['dbdriver'].'_driver.php';
if (!file_exists($driver_file))
{
throw new DatabaseException("Invalid DB Driver", 1);
}
require_once($driver_file);
// Instantiate the DB adapter
$driver = 'FW_DB_'.$params['dbdriver'].'_driver';
$DB = new $driver($params);
// Check for a subdriver
if ( ! empty($DB->subdriver))
{
$driver_file = dirname(__DIR__) . DS . 'Database'.DS.'drivers'.DS.$DB->dbdriver.DS.'subdrivers'.DS.$DB->dbdriver.'_'.$DB->subdriver.'_driver.php';
if (file_exists($driver_file))
{
require_once($driver_file);
$driver = 'FW_DB_'.$DB->dbdriver.'_'.$DB->subdriver.'_driver';
$DB = new $driver($params);
}
}
$DB->initialize();
return $DB;
}

@ -0,0 +1,220 @@
<?php
/**
* FuzeWorks Framework Database Component.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2018 TechFuze
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author TechFuze
* @copyright Copyright (c) 2013 - 2018, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 1.1.4
*
* @version Version 1.1.4
*/
use FuzeWorks\Logger;
use Fuzeworks\Factory;
use FuzeWorks\Core;
/**
* Database Cache Class
*
* Converted from CodeIgniter.
*
* @package FuzeWorks
* @category Database
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
* @license http://opensource.org/licenses/MIT MIT License
*/
class FW_DB_Cache {
/**
* Database object
*
* Allows passing of DB object so that multiple database connections
* and returned DB objects can be supported.
*
* @var object
*/
public $db;
/**
* The FuzeWorks factory class
*
* @var Fuzeworks\Factory;
*/
private $factory;
// --------------------------------------------------------------------
/**
* Constructor
*
* @param object &$db
* @return void
*/
public function __construct(&$db)
{
$this->db =& $db;
$this->factory = Factory::getInstance();
$this->factory->helpers->load('file');
$this->check_path();
}
// --------------------------------------------------------------------
/**
* Set Cache Directory Path
*
* @param string $path Path to the cache directory
* @return bool
*/
public function check_path($path = '')
{
$path = ($path === '' ? Core::$tempDir . DS . 'Database' : $path);
// Add a trailing slash to the path if needed
$path = realpath($path)
? rtrim(realpath($path), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR
: rtrim($path, '/').'/';
if ( ! is_dir($path))
{
if (!mkdir($path, 0777, false))
{
Logger::logDebug('DB cache path error: '.$path);
// If the path is wrong we'll turn off caching
return $this->db->cache_off();
}
}
if ( ! Core::isReallyWritable($path))
{
Logger::logDebug('DB cache dir not writable: '.$path);
// If the path is not really writable we'll turn off caching
return $this->db->cache_off();
}
$this->db->cachedir = $path;
return TRUE;
}
// --------------------------------------------------------------------
/**
* Retrieve a cached query
*
* The URI being requested will become the name of the cache sub-folder.
* An MD5 hash of the SQL statement will become the cache file name.
*
* @param string $sql
* @return string
*/
public function read($sql)
{
$segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1);
$segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2);
$filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql);
if (FALSE === ($cachedata = @file_get_contents($filepath)))
{
return FALSE;
}
return unserialize($cachedata);
}
// --------------------------------------------------------------------
/**
* Write a query to a cache file
*
* @param string $sql
* @param object $object
* @return bool
*/
public function write($sql, $object)
{
$segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1);
$segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2);
$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
$filename = md5($sql);
if ( ! is_dir($dir_path) && ! @mkdir($dir_path, 0750))
{
return FALSE;
}
if (write_file($dir_path.$filename, serialize($object)) === FALSE)
{
return FALSE;
}
chmod($dir_path.$filename, 0640);
return TRUE;
}
// --------------------------------------------------------------------
/**
* Delete cache files within a particular directory
*
* @param string $segment_one
* @param string $segment_two
* @return void
*/
public function delete($segment_one = '', $segment_two = '')
{
if ($segment_one === '')
{
$segment_one = ($this->factory->uri->segment(1) == FALSE) ? 'default' : $this->factory->uri->segment(1);
}
if ($segment_two === '')
{
$segment_two = ($this->factory->uri->segment(2) == FALSE) ? 'index' : $this->factory->uri->segment(2);
}
$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
delete_files($dir_path, TRUE);
}
// --------------------------------------------------------------------
/**
* Delete all existing cache files
*
* @return void
*/
public function delete_all()
{
delete_files($this->db->cachedir, TRUE, TRUE);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,670 @@
<?php
/**
* FuzeWorks Framework Database Component.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2018 TechFuze
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author TechFuze
* @copyright Copyright (c) 2013 - 2018, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 1.1.4
*
* @version Version 1.1.4
*/
use FuzeWorks\Logger;
use FuzeWorks\Exception\DatabaseException;
/**
* Database Result Class
*
* This is the platform-independent result class.
* This class will not be called directly. Rather, the adapter
* class for the specific database will extend and instantiate it.
*
* Converted from CodeIgniter.
*
* @package FuzeWorks
* @category Database
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
* @license http://opensource.org/licenses/MIT MIT License
*/
class FW_DB_result {
/**
* Connection ID
*
* @var resource|object
*/
public $conn_id;
/**
* Result ID
*
* @var resource|object
*/
public $result_id;
/**
* Result Array
*
* @var array[]
*/
public $result_array = array();
/**
* Result Object
*
* @var object[]
*/
public $result_object = array();
/**
* Custom Result Object
*
* @var object[]
*/
public $custom_result_object = array();
/**
* Current Row index
*
* @var int
*/
public $current_row = 0;
/**
* Number of rows
*
* @var int
*/
public $num_rows;
/**
* Row data
*
* @var array
*/
public $row_data;
// --------------------------------------------------------------------
/**
* Constructor
*
* @param object $driver_object
* @return void
*/
public function __construct(&$driver_object)
{
$this->conn_id = $driver_object->conn_id;
$this->result_id = $driver_object->result_id;
}
// --------------------------------------------------------------------
/**
* Number of rows in the result set
*
* @return int
*/
public function num_rows()
{
if (is_int($this->num_rows))
{
return $this->num_rows;
}
elseif (count($this->result_array) > 0)
{
return $this->num_rows = count($this->result_array);
}
elseif (count($this->result_object) > 0)
{
return $this->num_rows = count($this->result_object);
}
return $this->num_rows = count($this->result_array());
}
// --------------------------------------------------------------------
/**
* Query result. Acts as a wrapper function for the following functions.
*
* @param string $type 'object', 'array' or a custom class name
* @return array
*/
public function result($type = 'object')
{
if ($type === 'array')
{
return $this->result_array();
}
elseif ($type === 'object')
{
return $this->result_object();
}
else
{
return $this->custom_result_object($type);
}
}
// --------------------------------------------------------------------
/**
* Custom query result.
*
* @param string $class_name
* @return array
*/
public function custom_result_object($class_name)
{
if (isset($this->custom_result_object[$class_name]))
{
return $this->custom_result_object[$class_name];
}
elseif ( ! $this->result_id OR $this->num_rows === 0)
{
return array();
}
// Don't fetch the result set again if we already have it
$_data = NULL;
if (($c = count($this->result_array)) > 0)
{
$_data = 'result_array';
}
elseif (($c = count($this->result_object)) > 0)
{
$_data = 'result_object';
}
if ($_data !== NULL)
{
for ($i = 0; $i < $c; $i++)
{
$this->custom_result_object[$class_name][$i] = new $class_name();
foreach ($this->{$_data}[$i] as $key => $value)
{
$this->custom_result_object[$class_name][$i]->$key = $value;
}
}
return $this->custom_result_object[$class_name];
}
is_null($this->row_data) OR $this->data_seek(0);
$this->custom_result_object[$class_name] = array();
while ($row = $this->_fetch_object($class_name))
{
$this->custom_result_object[$class_name][] = $row;
}
return $this->custom_result_object[$class_name];
}
// --------------------------------------------------------------------
/**
* Query result. "object" version.
*
* @return array
*/
public function result_object()
{
if (count($this->result_object) > 0)
{
return $this->result_object;
}
// In the event that query caching is on, the result_id variable
// will not be a valid resource so we'll simply return an empty
// array.
if ( ! $this->result_id OR $this->num_rows === 0)
{
return array();
}
if (($c = count($this->result_array)) > 0)
{
for ($i = 0; $i < $c; $i++)
{
$this->result_object[$i] = (object) $this->result_array[$i];
}
return $this->result_object;
}
is_null($this->row_data) OR $this->data_seek(0);
while ($row = $this->_fetch_object())
{
$this->result_object[] = $row;
}
return $this->result_object;
}
// --------------------------------------------------------------------
/**
* Query result. "array" version.
*
* @return array
*/
public function result_array()
{
if (count($this->result_array) > 0)
{
return $this->result_array;
}
// In the event that query caching is on, the result_id variable
// will not be a valid resource so we'll simply return an empty
// array.
if ( ! $this->result_id OR $this->num_rows === 0)
{
return array();
}
if (($c = count($this->result_object)) > 0)
{
for ($i = 0; $i < $c; $i++)
{
$this->result_array[$i] = (array) $this->result_object[$i];
}
return $this->result_array;
}
is_null($this->row_data) OR $this->data_seek(0);
while ($row = $this->_fetch_assoc())
{
$this->result_array[] = $row;
}
return $this->result_array;
}
// --------------------------------------------------------------------
/**
* Row
*
* A wrapper method.
*
* @param mixed $n
* @param string $type 'object' or 'array'
* @return mixed
*/
public function row($n = 0, $type = 'object')
{
if ( ! is_numeric($n))
{
// We cache the row data for subsequent uses
is_array($this->row_data) OR $this->row_data = $this->row_array(0);
// array_key_exists() instead of isset() to allow for NULL values
if (empty($this->row_data) OR ! array_key_exists($n, $this->row_data))
{
return NULL;
}
return $this->row_data[$n];
}
if ($type === 'object') return $this->row_object($n);
elseif ($type === 'array') return $this->row_array($n);
else return $this->custom_row_object($n, $type);
}
// --------------------------------------------------------------------
/**
* Assigns an item into a particular column slot
*
* @param mixed $key
* @param mixed $value
* @return void
*/
public function set_row($key, $value = NULL)
{
// We cache the row data for subsequent uses
if ( ! is_array($this->row_data))
{
$this->row_data = $this->row_array(0);
}
if (is_array($key))
{
foreach ($key as $k => $v)
{
$this->row_data[$k] = $v;
}
return;
}
if ($key !== '' && $value !== NULL)
{
$this->row_data[$key] = $value;
}
}
// --------------------------------------------------------------------
/**
* Returns a single result row - custom object version
*
* @param int $n
* @param string $type
* @return object
*/
public function custom_row_object($n, $type)
{
isset($this->custom_result_object[$type]) OR $this->custom_result_object($type);
if (count($this->custom_result_object[$type]) === 0)
{
return NULL;
}
if ($n !== $this->current_row && isset($this->custom_result_object[$type][$n]))
{
$this->current_row = $n;
}
return $this->custom_result_object[$type][$this->current_row];
}
// --------------------------------------------------------------------
/**
* Returns a single result row - object version
*
* @param int $n
* @return object
*/
public function row_object($n = 0)
{
$result = $this->result_object();
if (count($result) === 0)
{
return NULL;
}
if ($n !== $this->current_row && isset($result[$n]))
{
$this->current_row = $n;
}
return $result[$this->current_row];
}
// --------------------------------------------------------------------
/**
* Returns a single result row - array version
*
* @param int $n
* @return array
*/
public function row_array($n = 0)
{
$result = $this->result_array();
if (count($result) === 0)
{
return NULL;
}
if ($n !== $this->current_row && isset($result[$n]))
{
$this->current_row = $n;
}
return $result[$this->current_row];
}
// --------------------------------------------------------------------
/**
* Returns the "first" row
*
* @param string $type
* @return mixed
*/
public function first_row($type = 'object')
{
$result = $this->result($type);
return (count($result) === 0) ? NULL : $result[0];
}
// --------------------------------------------------------------------
/**
* Returns the "last" row
*
* @param string $type
* @return mixed
*/
public function last_row($type = 'object')
{
$result = $this->result($type);
return (count($result) === 0) ? NULL : $result[count($result) - 1];
}
// --------------------------------------------------------------------
/**
* Returns the "next" row
*
* @param string $type
* @return mixed
*/
public function next_row($type = 'object')
{
$result = $this->result($type);
if (count($result) === 0)
{
return NULL;
}
return isset($result[$this->current_row + 1])
? $result[++$this->current_row]
: NULL;
}
// --------------------------------------------------------------------
/**
* Returns the "previous" row
*
* @param string $type
* @return mixed
*/
public function previous_row($type = 'object')
{
$result = $this->result($type);
if (count($result) === 0)
{
return NULL;
}
if (isset($result[$this->current_row - 1]))
{
--$this->current_row;
}
return $result[$this->current_row];
}
// --------------------------------------------------------------------
/**
* Returns an unbuffered row and move pointer to next row
*
* @param string $type 'array', 'object' or a custom class name
* @return mixed
*/
public function unbuffered_row($type = 'object')
{
if ($type === 'array')
{
return $this->_fetch_assoc();
}
elseif ($type === 'object')
{
return $this->_fetch_object();
}
return $this->_fetch_object($type);
}
// --------------------------------------------------------------------
/**
* The following methods are normally overloaded by the identically named
* methods in the platform-specific driver -- except when query caching
* is used. When caching is enabled we do not load the other driver.
* These functions are primarily here to prevent undefined function errors
* when a cached result object is in use. They are not otherwise fully
* operational due to the unavailability of the database resource IDs with
* cached results.
*/
// --------------------------------------------------------------------
/**
* Number of fields in the result set
*
* Overridden by driver result classes.
*
* @return int
*/
public function num_fields()
{
return 0;
}
// --------------------------------------------------------------------
/**
* Fetch Field Names
*
* Generates an array of column names.
*
* Overridden by driver result classes.
*
* @return array
*/
public function list_fields()
{
return array();
}
// --------------------------------------------------------------------
/**
* Field data
*
* Generates an array of objects containing field meta-data.
*
* Overridden by driver result classes.
*
* @return array
*/
public function field_data()
{
return array();
}
// --------------------------------------------------------------------
/**
* Free the result
*
* Overridden by driver result classes.
*
* @return void
*/
public function free_result()
{
$this->result_id = FALSE;
}
// --------------------------------------------------------------------
/**
* Data Seek
*
* Moves the internal pointer to the desired offset. We call
* this internally before fetching results to make sure the
* result set starts at zero.
*
* Overridden by driver result classes.
*
* @param int $n
* @return bool
*/
public function data_seek($n = 0)
{
return FALSE;
}
// --------------------------------------------------------------------
/**
* Result - associative array
*
* Returns the result set as an array.
*
* Overridden by driver result classes.
*
* @return array
*/
protected function _fetch_assoc()
{
return array();
}
// --------------------------------------------------------------------
/**
* Result - object
*
* Returns the result set as an object.
*
* Overridden by driver result classes.
*
* @param string $class_name
* @return object
*/
protected function _fetch_object($class_name = 'stdClass')
{
return array();
}
}

@ -0,0 +1,438 @@
<?php
/**
* FuzeWorks Framework Database Component.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2018 TechFuze
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author TechFuze
* @copyright Copyright (c) 2013 - 2018, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 1.1.4
*
* @version Version 1.1.4
*/
use FuzeWorks\Logger;
use FuzeWorks\Helpers;
use FuzeWorks\Libraries;
use Fuzeworks\Factory;
use FuzeWorks\Exception\DatabaseException;
/**
* Database Utility Class
*
* Converted from CodeIgniter.
*
* @package FuzeWorks
* @category Database
* @author EllisLab Dev Team
* @link https://codeigniter.com/user_guide/database/
* @license http://opensource.org/licenses/MIT MIT License
*/
abstract class FW_DB_utility {
/**
* Database object
*
* @var object
*/
protected $db;
// --------------------------------------------------------------------
/**
* List databases statement
*
* @var string
*/
protected $_list_databases = FALSE;
/**
* OPTIMIZE TABLE statement
*
* @var string
*/
protected $_optimize_table = FALSE;
/**
* REPAIR TABLE statement
*
* @var string
*/
protected $_repair_table = FALSE;
/**
* The FuzeWorks factory class
*
* @var Fuzeworks\Factory;
*/
private $factory;
// --------------------------------------------------------------------
/**
* Class constructor
*
* @param object &$db Database object
* @return void
*/
public function __construct(&$db)
{
$this->db =& $db;
$this->factory = Factory::getInstance();
Logger::log('Database Utility Class Initialized');
}
// --------------------------------------------------------------------
/**
* List databases
*
* @return array
*/
public function list_databases()
{
// Is there a cached result?
if (isset($this->db->data_cache['db_names']))
{
return $this->db->data_cache['db_names'];
}
elseif ($this->_list_databases === FALSE)
{
return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE;
}
$this->db->data_cache['db_names'] = array();
$query = $this->db->query($this->_list_databases);
if ($query === FALSE)
{
return $this->db->data_cache['db_names'];
}
for ($i = 0, $query = $query->result_array(), $c = count($query); $i < $c; $i++)
{
$this->db->data_cache['db_names'][] = current($query[$i]);
}
return $this->db->data_cache['db_names'];
}
// --------------------------------------------------------------------
/**
* Determine if a particular database exists
*
* @param string $database_name
* @return bool
*/
public function database_exists($database_name)
{
return in_array($database_name, $this->list_databases());
}
// --------------------------------------------------------------------
/**
* Optimize Table
*
* @param string $table_name
* @return mixed
*/
public function optimize_table($table_name)
{
if ($this->_optimize_table === FALSE)
{
return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE;
}
$query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
if ($query !== FALSE)
{
$query = $query->result_array();
return current($query);
}
return FALSE;
}
// --------------------------------------------------------------------
/**
* Optimize Database
*
* @return mixed
*/
public function optimize_database()
{
if ($this->_optimize_table === FALSE)
{
return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE;
}
$result = array();
foreach ($this->db->list_tables() as $table_name)
{
$res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
if (is_bool($res))
{
return $res;
}
// Build the result array...
$res = $res->result_array();
$res = current($res);
$key = str_replace($this->db->database.'.', '', current($res));
$keys = array_keys($res);
unset($res[$keys[0]]);
$result[$key] = $res;
}
return $result;
}
// --------------------------------------------------------------------
/**
* Repair Table
*
* @param string $table_name
* @return mixed
*/
public function repair_table($table_name)
{
if ($this->_repair_table === FALSE)
{
return ($this->db->db_debug) ? $this->db->display_error('db_unsupported_feature') : FALSE;
}
$query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name)));
if (is_bool($query))
{
return $query;
}
$query = $query->result_array();
return current($query);
}
// --------------------------------------------------------------------
/**
* Generate CSV from a query result object
*
* @param object $query Query result object
* @param string $delim Delimiter (default: ,)
* @param string $newline Newline character (default: \n)
* @param string $enclosure Enclosure (default: ")
* @return string
*/
public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"')
{
if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
{
throw new DatabaseException('You must submit a valid result object', 1);
}
$out = '';
// First generate the headings from the table column names
foreach ($query->list_fields() as $name)
{
$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
}
$out = substr($out, 0, -strlen($delim)).$newline;
// Next blast through the result array and build out the rows
while ($row = $query->unbuffered_row('array'))
{
$line = array();
foreach ($row as $item)
{
$line[] = $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure;
}
$out .= implode($delim, $line).$newline;
}
return $out;
}
// --------------------------------------------------------------------
/**
* Generate XML data from a query result object
*
* @param object $query Query result object
* @param array $params Any preferences
* @return string
*/
public function xml_from_result($query, $params = array())
{
if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
{
throw new DatabaseException('You must submit a valid result object', 1);
}
// Set our default values
foreach (array('root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t") as $key => $val)
{
if ( ! isset($params[$key]))
{
$params[$key] = $val;
}
}
// Create variables for convenience
extract($params);
// Load the xml helper
$this->factory->helpers->load('xml');
// Generate the result
$xml = '<'.$root.'>'.$newline;
while ($row = $query->unbuffered_row())
{
$xml .= $tab.'<'.$element.'>'.$newline;
foreach ($row as $key => $val)
{
$xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).'</'.$key.'>'.$newline;
}
$xml .= $tab.'</'.$element.'>'.$newline;
}
return $xml.'</'.$root.'>'.$newline;
}
// --------------------------------------------------------------------
/**
* Database Backup
*
* @param array $params
* @return string
*/
public function backup($params = array())
{
// If the parameters have not been submitted as an
// array then we know that it is simply the table
// name, which is a valid short cut.
if (is_string($params))
{
$params = array('tables' => $params);
}
// Set up our default preferences
$prefs = array(
'tables' => array(),
'ignore' => array(),
'filename' => '',
'format' => 'gzip', // gzip, zip, txt
'add_drop' => TRUE,
'add_insert' => TRUE,
'newline' => "\n",
'foreign_key_checks' => TRUE
);
// Did the user submit any preferences? If so set them....
if (count($params) > 0)
{
foreach ($prefs as $key => $val)
{
if (isset($params[$key]))
{
$prefs[$key] = $params[$key];
}
}
}
// Are we backing up a complete database or individual tables?
// If no table names were submitted we'll fetch the entire table list
if (count($prefs['tables']) === 0)
{
$prefs['tables'] = $this->db->list_tables();
}
// Validate the format
if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
{
$prefs['format'] = 'txt';
}
// Is the encoder supported? If not, we'll either issue an
// error or use plain text depending on the debug settings
if (($prefs['format'] === 'gzip' && ! function_exists('gzencode'))
OR ($prefs['format'] === 'zip' && ! function_exists('gzcompress')))
{
if ($this->db->db_debug)
{
return $this->db->display_error('db_unsupported_compression');
}
$prefs['format'] = 'txt';
}
// Was a Zip file requested?
if ($prefs['format'] === 'zip')
{
// Set the filename if not provided (only needed with Zip files)
if ($prefs['filename'] === '')
{
$prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
.date('Y-m-d_H-i', time()).'.sql';
}
else
{
// If they included the .zip file extension we'll remove it
if (preg_match('|.+?\.zip$|', $prefs['filename']))
{
$prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
}
// Tack on the ".sql" file extension if needed
if ( ! preg_match('|.+?\.sql$|', $prefs['filename']))
{
$prefs['filename'] .= '.sql';
}
}
// Load the Zip class and output it
$zip = Libraries::get('zip');
$zip->add_data($prefs['filename'], $this->_backup($prefs));
return $zip->get_zip();
}
elseif ($prefs['format'] === 'txt') // Was a text file requested?
{
return $this->_backup($prefs);
}
elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested?
{
return gzencode($this->_backup($prefs));
}
return;
}
}

@ -0,0 +1,405 @@
<?php
/**
* FuzeWorks Framework Database Component.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2018 TechFuze
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*