/libraries/joomla/database/database.php
PHP | 812 lines | 560 code | 60 blank | 192 comment | 26 complexity | db84406c03465831fd804e6571e15ac9 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
- <?php
- /**
- * @version $Id$
- * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
- * @license GNU General Public License version 2 or later; see LICENSE.txt
- */
- // No direct access
- defined('JPATH_BASE') or die;
- /**
- * Database connector class
- *
- * @package Joomla.Framework
- * @subpackage Database
- * @since 1.0
- */
- abstract class JDatabase extends JObject
- {
- /**
- * The database driver name
- *
- * @var string
- */
- public $name = '';
- /**
- * The query sql string
- *
- * @var string
- **/
- protected $_sql = '';
- /**
- * The database error number
- *
- * @var int
- **/
- protected $_errorNum = 0;
- /**
- * The database error message
- *
- * @var string
- */
- protected $_errorMsg = '';
- /**
- * The prefix used on all database tables
- *
- * @var string
- */
- protected $_table_prefix = '';
- /**
- * The database link identifier.
- *
- * @var mixed
- */
- protected $_connection = '';
- /**
- * The last query cursor
- *
- * @var resource
- */
- protected $_cursor = null;
- /**
- * Debug option
- *
- * @var boolean
- */
- protected $_debug = 0;
- /**
- * The limit for the query
- *
- * @var int
- */
- protected $_limit = 0;
- /**
- * The for offset for the limit
- *
- * @var int
- */
- protected $_offset = 0;
- /**
- * The number of queries performed by the object instance
- *
- * @var int
- */
- protected $_ticker = 0;
- /**
- * A log of queries
- *
- * @var array
- */
- protected $_log = null;
- /**
- * The null/zero date string
- *
- * @var string
- */
- protected $_nullDate = null;
- /**
- * Quote for named objects
- *
- * @var string
- */
- protected $_nameQuote = null;
- /**
- * UTF-8 support
- *
- * @var boolean
- * @since 1.5
- */
- protected $_utf = 0;
- /**
- * The fields that are to be quote
- *
- * @var array
- * @since 1.5
- */
- protected $_quoted = null;
- /**
- * Legacy compatibility
- *
- * @var bool
- * @since 1.5
- */
- protected $_hasQuoted = null;
- /**
- * Database object constructor
- *
- * @param array List of options used to configure the connection
- * @since 1.5
- */
- public function __construct($options)
- {
- $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : 'jos_';
- // Determine utf-8 support.
- $this->_utf = $this->hasUTF();
- // Set charactersets (needed for MySQL 4.1.2+).
- if ($this->_utf){
- $this->setUTF();
- }
- $this->_table_prefix = $prefix;
- $this->_ticker = 0;
- $this->_errorNum = 0;
- $this->_log = array();
- $this->_quoted = array();
- $this->_hasQuoted = false;
- }
- /**
- * Returns the global Database object, only creating it
- * if it doesn't already exist.
- *
- * The 'driver' entry in the parameters array specifies the database driver
- * to be used (defaults to 'mysql' if omitted). All other parameters are
- * database driver dependent.
- *
- * @param array Parameters to be passed to the database driver
- * @return JDatabase A database object
- * @since 1.5
- */
- public static function getInstance($options = array())
- {
- static $instances;
- if (!isset($instances)) {
- $instances = array();
- }
- $signature = serialize($options);
- if (empty($instances[$signature])) {
- $driver = array_key_exists('driver', $options) ? $options['driver'] : 'mysql';
- $select = array_key_exists('select', $options) ? $options['select'] : true;
- $database = array_key_exists('database', $options) ? $options['database'] : null;
- $driver = preg_replace('/[^A-Z0-9_\.-]/i', '', $driver);
- $path = dirname(__FILE__).DS.'database'.DS.$driver.'.php';
- if (file_exists($path)) {
- require_once $path;
- } else {
- JError::setErrorHandling(E_ERROR, 'die'); //force error type to die
- return JError::raiseError(500, JTEXT::_('UNABLE_TO_LOAD_DATABASE_DRIVER:') .$driver);
- }
- $adapter = 'JDatabase'.$driver;
- $instance = new $adapter($options);
- if ($error = $instance->getErrorMsg()) {
- JError::setErrorHandling(E_ERROR, 'ignore'); //force error type to die
- return JError::raiseError(500, JTEXT::_('UNABLE_TO_CONNECT_TO_THE_DATABASE') .$error);
- }
- $instances[$signature] = & $instance;
- }
- return $instances[$signature];
- }
- /**
- * Database object destructor
- *
- * @return boolean
- * @since 1.5
- */
- public function __destruct()
- {
- return true;
- }
- /**
- * Get the database connectors
- *
- * @return array An array of available session handlers
- */
- public function getConnectors()
- {
- jimport('joomla.filesystem.folder');
- $handlers = JFolder::files(dirname(__FILE__).DS.'database', '.php$');
- $names = array();
- foreach($handlers as $handler) {
- $name = substr($handler, 0, strrpos($handler, '.'));
- $class = 'JDatabase'.ucfirst($name);
- if (!class_exists($class)) {
- require_once dirname(__FILE__).DS.'database'.DS.$name.'.php';
- }
- if (call_user_func_array(array(trim($class), 'test'), array())) {
- $names[] = $name;
- }
- }
- return $names;
- }
- /**
- * Test to see if the MySQLi connector is available
- *
- * @return boolean True on success, false otherwise.
- */
- abstract public function test();
- /**
- * Determines if the connection to the server is active.
- *
- * @return boolean
- * @since 1.5
- */
- abstract public function connected();
- /**
- * Determines UTF support
- *
- * @return boolean
- * @since 1.5
- */
- abstract public function hasUTF();
- /**
- * Custom settings for UTF support
- *
- * @since 1.5
- */
- abstract public function setUTF();
- /**
- * Adds a field or array of field names to the list that are to be quoted
- *
- * @param mixed Field name or array of names
- * @since 1.5
- */
- public function addQuoted($quoted)
- {
- if (is_string($quoted)) {
- $this->_quoted[] = $quoted;
- } else {
- $this->_quoted = array_merge($this->_quoted, (array)$quoted);
- }
- $this->_hasQuoted = true;
- }
- /**
- * Splits a string of queries into an array of individual queries
- *
- * @param string The queries to split
- * @return array queries
- */
- public function splitSql($queries)
- {
- $start = 0;
- $open = false;
- $open_char = '';
- $end = strlen($queries);
- $query_split = array();
- for ($i = 0; $i < $end; $i++) {
- $current = substr($queries,$i,1);
- if (($current == '"' || $current == '\'')) {
- $n = 2;
- while(substr($queries,$i - $n + 1, 1) == '\\' && $n < $i) {
- $n ++;
- }
- if ($n%2==0) {
- if ($open) {
- if ($current == $open_char) {
- $open = false;
- $open_char = '';
- }
- } else {
- $open = true;
- $open_char = $current;
- }
- }
- }
- if (($current == ';' && !$open)|| $i == $end - 1) {
- $query_split[] = substr($queries, $start, ($i - $start + 1));
- $start = $i + 1;
- }
- }
- return $query_split;
- }
- /**
- * Checks if field name needs to be quoted
- *
- * @param string The field name
- * @return bool
- */
- public function isQuoted($fieldName)
- {
- if ($this->_hasQuoted) {
- return in_array($fieldName, $this->_quoted);
- } else {
- return true;
- }
- }
- /**
- * Sets the debug level on or off
- *
- * @param int 0 = off, 1 = on
- */
- public function debug($level)
- {
- $this->_debug = intval($level);
- }
- /**
- * Get the database UTF-8 support
- *
- * @return boolean
- * @since 1.5
- */
- public function getUTFSupport()
- {
- return $this->_utf;
- }
- /**
- * Get the error number
- *
- * @return int The error number for the most recent query
- */
- public function getErrorNum()
- {
- return $this->_errorNum;
- }
- /**
- * Get the error message
- *
- * @return string The error message for the most recent query
- */
- public function getErrorMsg($escaped = false)
- {
- if ($escaped) {
- return addslashes($this->_errorMsg);
- } else {
- return $this->_errorMsg;
- }
- }
- /**
- * Get a database escaped string
- *
- * @param string The string to be escaped
- * @param boolean Optional parameter to provide extra escaping
- * @return string
- */
- abstract public function getEscaped($text, $extra = false);
- /**
- * Get a database error log
- *
- * @return array
- */
- public function getLog()
- {
- return $this->_log;
- }
- /**
- * Get the total number of queries made
- *
- * @return array
- */
- public function getTicker()
- {
- return $this->_ticker;
- }
- /**
- * Quote an identifier name (field, table, etc)
- *
- * @param string The name
- * @return string The quoted name
- */
- public function nameQuote($s)
- {
- // Only quote if the name is not using dot-notation
- if (strpos($s, '.') === false) {
- $q = $this->_nameQuote;
- if (strlen($q) == 1) {
- return $q . $s . $q;
- } else {
- return $q{0} . $s . $q{1};
- }
- } else {
- return $s;
- }
- }
- /**
- * Get the database table prefix
- *
- * @return string The database prefix
- */
- public function getPrefix()
- {
- return $this->_table_prefix;
- }
- /**
- * Get the connection
- *
- * Provides access to the underlying database connection. Useful for when
- * you need to call a proprietary method such as postgresql's lo_* methods
- *
- * @return resource
- */
- public function getConnection()
- {
- return $this->_connection;
- }
- /**
- * Get the database null date
- *
- * @return string Quoted null/zero date string
- */
- public function getNullDate()
- {
- return $this->_nullDate;
- }
- /**
- * Sets the SQL query string for later execution.
- *
- * This function replaces a string identifier <var>$prefix</var> with the
- * string held is the <var>_table_prefix</var> class variable.
- *
- * @param string The SQL query
- * @param string The offset to start selection
- * @param string The number of results to return
- * @param string The common table prefix
- *
- * @return object This object to support chaining.
- */
- public function setQuery($sql, $offset = 0, $limit = 0, $prefix='#__')
- {
- $this->_sql = $this->replacePrefix((string)$sql, $prefix);
- $this->_limit = (int) $limit;
- $this->_offset = (int) $offset;
- return $this;
- }
- /**
- * This function replaces a string identifier <var>$prefix</var> with the
- * string held is the <var>_table_prefix</var> class variable.
- *
- * @param string The SQL query
- * @param string The common table prefix
- */
- public function replacePrefix($sql, $prefix='#__')
- {
- $sql = trim($sql);
- $escaped = false;
- $quoteChar = '';
- $n = strlen($sql);
- $startPos = 0;
- $literal = '';
- while ($startPos < $n) {
- $ip = strpos($sql, $prefix, $startPos);
- if ($ip === false) {
- break;
- }
- $j = strpos($sql, "'", $startPos);
- $k = strpos($sql, '"', $startPos);
- if (($k !== FALSE) && (($k < $j) || ($j === FALSE))) {
- $quoteChar = '"';
- $j = $k;
- } else {
- $quoteChar = "'";
- }
- if ($j === false) {
- $j = $n;
- }
- $literal .= str_replace($prefix, $this->_table_prefix,substr($sql, $startPos, $j - $startPos));
- $startPos = $j;
- $j = $startPos + 1;
- if ($j >= $n) {
- break;
- }
- // quote comes first, find end of quote
- while (TRUE) {
- $k = strpos($sql, $quoteChar, $j);
- $escaped = false;
- if ($k === false) {
- break;
- }
- $l = $k - 1;
- while ($l >= 0 && $sql{$l} == '\\') {
- $l--;
- $escaped = !$escaped;
- }
- if ($escaped) {
- $j = $k+1;
- continue;
- }
- break;
- }
- if ($k === FALSE) {
- // error in the query - no end quote; ignore it
- break;
- }
- $literal .= substr($sql, $startPos, $k - $startPos + 1);
- $startPos = $k+1;
- }
- if ($startPos < $n) {
- $literal .= substr($sql, $startPos, $n - $startPos);
- }
- return $literal;
- }
- /**
- * Get the active query
- *
- * @return string The current value of the internal SQL vairable
- */
- public function getQuery()
- {
- return $this->_sql;
- }
- /**
- * Execute the query
- *
- * @return mixed A database resource if successful, FALSE if not.
- */
- abstract public function query();
- /**
- * Get the affected rows by the most recent query
- *
- * @return int The number of affected rows in the previous operation
- * @since 1.0.5
- */
- abstract public function getAffectedRows();
- /**
- * Execute a batch query
- *
- * @return mixed A database resource if successful, FALSE if not.
- */
- abstract public function queryBatch($abort_on_error=true, $p_transaction_safe = false);
- /**
- * Diagnostic function
- */
- abstract public function explain();
- /**
- * Get the number of rows returned by the most recent query
- *
- * @param object Database resource
- * @return int The number of rows
- */
- abstract public function getNumRows($cur=null);
- /**
- * This method loads the first field of the first row returned by the query.
- *
- * @return mixed The value returned in the query or null if the query failed.
- */
- abstract public function loadResult();
- /**
- * Load an array of single field results into an array
- */
- abstract public function loadResultArray($numinarray = 0);
- /**
- * Fetch a result row as an associative array
- */
- abstract public function loadAssoc();
- /**
- * Load a associactive list of database rows
- *
- * @param string The field name of a primary key
- * @param string An optional column name. Instead of the whole row, only this column value will be in the return array.
- * @return array If key is empty as sequential list of returned records.
- */
- abstract public function loadAssocList($key = null, $column = null);
- /**
- * This global function loads the first row of a query into an object
- *
- * @return object
- */
- abstract public function loadObject();
- /**
- * Load a list of database objects
- *
- * @param string The field name of a primary key
- * @return array If <var>key</var> is empty as sequential list of returned records.
- * If <var>key</var> is not empty then the returned array is indexed by the value
- * the database key. Returns <var>null</var> if the query fails.
- */
- abstract public function loadObjectList($key='');
- /**
- * Load the first row returned by the query
- *
- * @return mixed The first row of the query.
- */
- abstract public function loadRow();
- /**
- * Load a list of database rows (numeric column indexing)
- *
- * If <var>key</var> is not empty then the returned array is indexed by the value
- * the database key. Returns <var>null</var> if the query fails.
- *
- * @param string The field name of a primary key
- * @return array
- */
- abstract public function loadRowList($key='');
- /**
- * Load the next row returned by the query.
- *
- * @return mixed The result of the query as an array, false if there are no more rows, or null on an error.
- *
- * @since 1.6.0
- */
- abstract public function loadNextRow();
- /**
- * Load the next row returned by the query.
- *
- * @return mixed The result of the query as an object, false if there are no more rows, or null on an error.
- *
- * @since 1.6.0
- */
- abstract public function loadNextObject();
- /**
- * Inserts a row into a table based on an objects properties
- * @param string The name of the table
- * @param object An object whose properties match table fields
- * @param string The name of the primary key. If provided the object property is updated.
- */
- abstract public function insertObject($table, &$object, $keyName = NULL);
- /**
- * Update an object in the database
- *
- * @param string
- * @param object
- * @param string
- * @param boolean
- */
- abstract public function updateObject($table, &$object, $keyName, $updateNulls=true);
- /**
- * Print out an error statement
- *
- * @param boolean If TRUE, displays the last SQL statement sent to the database
- * @return string A standised error message
- * @deprecated 1.6.0 - Jul 2, 2009
- */
- public function stderr($showSQL = false)
- {
- if ($this->_errorNum != 0) {
- return "DB function failed with error number $this->_errorNum"
- ."<br /><font color=\"red\">$this->_errorMsg</font>"
- .($showSQL ? "<br />SQL = <pre>$this->_sql</pre>" : '');
- } else {
- return "DB function reports no errors";
- }
- }
- /**
- * Get the ID generated from the previous INSERT operation
- *
- * @return mixed
- */
- abstract public function insertid();
- /**
- * Get the database collation
- *
- * @return string Collation in use
- */
- abstract public function getCollation();
- /**
- * Get the version of the database connector
- */
- public function getVersion()
- {
- return 'Not available for this connector';
- }
- /**
- * List tables in a database
- *
- * @return array A list of all the tables in the database
- */
- abstract public function getTableList();
- /**
- * Shows the CREATE TABLE statement that creates the given tables
- *
- * @param array|string A table name or a list of table names
- * @return array A list the create SQL for the tables
- */
- abstract public function getTableCreate($tables);
- /**
- * Retrieves information about the given tables
- *
- * @param array|string A table name or a list of table names
- * @param boolean Only return field types, default true
- * @return array An array of fields by table
- */
- abstract public function getTableFields($tables, $typeonly = true);
- /**
- * Get a quoted database escaped string
- *
- * @param string A string
- * @param boolean Default true to escape string, false to leave the string unchanged
- * @return string
- */
- public function quote($text, $escaped = true)
- {
- return '\''.($escaped ? $this->getEscaped($text) : $text).'\'';
- }
- }