You've already forked joomla_test
							
							
		
			
	
	
		
			1872 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			1872 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
|   | <?php | ||
|  | /** | ||
|  |  * @package     Joomla.Platform | ||
|  |  * @subpackage  Database | ||
|  |  * | ||
|  |  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved. | ||
|  |  * @license     GNU General Public License version 2 or later; see LICENSE | ||
|  |  */ | ||
|  | 
 | ||
|  | defined('JPATH_PLATFORM') or die; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Joomla Platform Database Interface | ||
|  |  * | ||
|  |  * @package     Joomla.Platform | ||
|  |  * @subpackage  Database | ||
|  |  * @since       11.2 | ||
|  |  */ | ||
|  | interface JDatabaseInterface | ||
|  | { | ||
|  | 	/** | ||
|  | 	 * Test to see if the connector is available. | ||
|  | 	 * | ||
|  | 	 * @return  boolean  True on success, false otherwise. | ||
|  | 	 * | ||
|  | 	 * @since   11.2 | ||
|  | 	 */ | ||
|  | 	public static function isSupported(); | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Joomla Platform Database Driver Class | ||
|  |  * | ||
|  |  * @package     Joomla.Platform | ||
|  |  * @subpackage  Database | ||
|  |  * @since       12.1 | ||
|  |  * | ||
|  |  * @method      string  q()   q($text, $escape = true)  Alias for quote method | ||
|  |  * @method      string  qn()  qn($name, $as = null)     Alias for quoteName method | ||
|  |  */ | ||
|  | abstract class JDatabaseDriver extends JDatabase implements JDatabaseInterface | ||
|  | { | ||
|  | 	/** | ||
|  | 	 * The name of the database. | ||
|  | 	 * | ||
|  | 	 * @var    string | ||
|  | 	 * @since  11.4 | ||
|  | 	 */ | ||
|  | 	private $_database; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * The name of the database driver. | ||
|  | 	 * | ||
|  | 	 * @var    string | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	public $name; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    resource  The database connection resource. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $connection; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    integer  The number of SQL statements executed by the database driver. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $count = 0; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    resource  The database connection cursor from the last query. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $cursor; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    boolean  The database driver debugging state. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $debug = false; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    integer  The affected row limit for the current SQL statement. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $limit = 0; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    array  The log of executed SQL statements by the database driver. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $log = array(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    array  The log of executed SQL statements timings (start and stop microtimes) by the database driver. | ||
|  | 	 * @since  CMS 3.1.2 | ||
|  | 	 */ | ||
|  | 	protected $timings = array(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    array  The log of executed SQL statements timings (start and stop microtimes) by the database driver. | ||
|  | 	 * @since  CMS 3.1.2 | ||
|  | 	 */ | ||
|  | 	protected $callStacks = array(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    string  The character(s) used to quote SQL statement names such as table names or field names, | ||
|  | 	 *                 etc.  The child classes should define this as necessary.  If a single character string the | ||
|  | 	 *                 same character is used for both sides of the quoted name, else the first character will be | ||
|  | 	 *                 used for the opening quote and the second for the closing quote. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $nameQuote; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    string  The null or zero representation of a timestamp for the database driver.  This should be | ||
|  | 	 *                 defined in child classes to hold the appropriate value for the engine. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $nullDate; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    integer  The affected row offset to apply for the current SQL statement. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $offset = 0; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    array  Passed in upon instantiation and saved. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $options; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    mixed  The current SQL statement to execute. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $sql; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    string  The common database table prefix. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $tablePrefix; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    boolean  True if the database engine supports UTF-8 character encoding. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected $utf = true; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var         integer  The database error number | ||
|  | 	 * @since       11.1 | ||
|  | 	 * @deprecated  12.1 | ||
|  | 	 */ | ||
|  | 	protected $errorNum = 0; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var         string  The database error message | ||
|  | 	 * @since       11.1 | ||
|  | 	 * @deprecated  12.1 | ||
|  | 	 */ | ||
|  | 	protected $errorMsg; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    array  JDatabaseDriver instances container. | ||
|  | 	 * @since  11.1 | ||
|  | 	 */ | ||
|  | 	protected static $instances = array(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    string  The minimum supported database version. | ||
|  | 	 * @since  12.1 | ||
|  | 	 */ | ||
|  | 	protected static $dbMinimum; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    integer  The depth of the current transaction. | ||
|  | 	 * @since  12.3 | ||
|  | 	 */ | ||
|  | 	protected $transactionDepth = 0; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * @var    callable[]  List of callables to call just before disconnecting database | ||
|  | 	 * @since  CMS 3.1.2 | ||
|  | 	 */ | ||
|  | 	protected $disconnectHandlers = array(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get a list of available database connectors.  The list will only be populated with connectors that both | ||
|  | 	 * the class exists and the static test method returns true.  This gives us the ability to have a multitude | ||
|  | 	 * of connector classes that are self-aware as to whether or not they are able to be used on a given system. | ||
|  | 	 * | ||
|  | 	 * @return  array  An array of available database connectors. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public static function getConnectors() | ||
|  | 	{ | ||
|  | 		$connectors = array(); | ||
|  | 
 | ||
|  | 		// Get an iterator and loop trough the driver classes.
 | ||
|  | 		$iterator = new DirectoryIterator(__DIR__ . '/driver'); | ||
|  | 
 | ||
|  | 		foreach ($iterator as $file) | ||
|  | 		{ | ||
|  | 			$fileName = $file->getFilename(); | ||
|  | 
 | ||
|  | 			// Only load for php files.
 | ||
|  | 			// Note: DirectoryIterator::getExtension only available PHP >= 5.3.6
 | ||
|  | 			if (!$file->isFile() || substr($fileName, strrpos($fileName, '.') + 1) != 'php') | ||
|  | 			{ | ||
|  | 				continue; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Derive the class name from the type.
 | ||
|  | 			$class = str_ireplace('.php', '', 'JDatabaseDriver' . ucfirst(trim($fileName))); | ||
|  | 
 | ||
|  | 			// If the class doesn't exist we have nothing left to do but look at the next type. We did our best.
 | ||
|  | 			if (!class_exists($class)) | ||
|  | 			{ | ||
|  | 				continue; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Sweet!  Our class exists, so now we just need to know if it passes its test method.
 | ||
|  | 			if ($class::isSupported()) | ||
|  | 			{ | ||
|  | 				// Connector names should not have file extensions.
 | ||
|  | 				$connectors[] = str_ireplace('.php', '', $fileName); | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return $connectors; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to return a JDatabaseDriver instance based on the given options.  There are three global options and then | ||
|  | 	 * the rest are specific to the database driver.  The 'driver' option defines which JDatabaseDriver class is | ||
|  | 	 * used for the connection -- the default is 'mysqli'.  The 'database' option determines which database is to | ||
|  | 	 * be used for the connection.  The 'select' option determines whether the connector should automatically select | ||
|  | 	 * the chosen database. | ||
|  | 	 * | ||
|  | 	 * Instances are unique to the given options and new objects are only created when a unique options array is | ||
|  | 	 * passed into the method.  This ensures that we don't end up with unnecessary database connection resources. | ||
|  | 	 * | ||
|  | 	 * @param   array  $options  Parameters to be passed to the database driver. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseDriver  A database object. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public static function getInstance($options = array()) | ||
|  | 	{ | ||
|  | 		// Sanitize the database connector options.
 | ||
|  | 		$options['driver']   = (isset($options['driver'])) ? preg_replace('/[^A-Z0-9_\.-]/i', '', $options['driver']) : 'mysqli'; | ||
|  | 		$options['database'] = (isset($options['database'])) ? $options['database'] : null; | ||
|  | 		$options['select']   = (isset($options['select'])) ? $options['select'] : true; | ||
|  | 
 | ||
|  | 		// Get the options signature for the database connector.
 | ||
|  | 		$signature = md5(serialize($options)); | ||
|  | 
 | ||
|  | 		// If we already have a database connector instance for these options then just use that.
 | ||
|  | 		if (empty(self::$instances[$signature])) | ||
|  | 		{ | ||
|  | 
 | ||
|  | 			// Derive the class name from the driver.
 | ||
|  | 			$class = 'JDatabaseDriver' . ucfirst(strtolower($options['driver'])); | ||
|  | 
 | ||
|  | 			// If the class still doesn't exist we have nothing left to do but throw an exception.  We did our best.
 | ||
|  | 			if (!class_exists($class)) | ||
|  | 			{ | ||
|  | 				throw new RuntimeException(sprintf('Unable to load Database Driver: %s', $options['driver'])); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Create our new JDatabaseDriver connector based on the options given.
 | ||
|  | 			try | ||
|  | 			{ | ||
|  | 				$instance = new $class($options); | ||
|  | 			} | ||
|  | 			catch (RuntimeException $e) | ||
|  | 			{ | ||
|  | 				throw new RuntimeException(sprintf('Unable to connect to the Database: %s', $e->getMessage())); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Set the new connector to the global instances based on signature.
 | ||
|  | 			self::$instances[$signature] = $instance; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return self::$instances[$signature]; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Splits a string of multiple queries into an array of individual queries. | ||
|  | 	 * | ||
|  | 	 * @param   string  $sql  Input SQL string with which to split into individual queries. | ||
|  | 	 * | ||
|  | 	 * @return  array  The queries from the input string separated into an array. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public static function splitSql($sql) | ||
|  | 	{ | ||
|  | 		$start = 0; | ||
|  | 		$open = false; | ||
|  | 		$char = ''; | ||
|  | 		$end = strlen($sql); | ||
|  | 		$queries = array(); | ||
|  | 
 | ||
|  | 		for ($i = 0; $i < $end; $i++) | ||
|  | 		{ | ||
|  | 			$current = substr($sql, $i, 1); | ||
|  | 
 | ||
|  | 			if (($current == '"' || $current == '\'')) | ||
|  | 			{ | ||
|  | 				$n = 2; | ||
|  | 
 | ||
|  | 				while (substr($sql, $i - $n + 1, 1) == '\\' && $n < $i) | ||
|  | 				{ | ||
|  | 					$n++; | ||
|  | 				} | ||
|  | 
 | ||
|  | 				if ($n % 2 == 0) | ||
|  | 				{ | ||
|  | 					if ($open) | ||
|  | 					{ | ||
|  | 						if ($current == $char) | ||
|  | 						{ | ||
|  | 							$open = false; | ||
|  | 							$char = ''; | ||
|  | 						} | ||
|  | 					} | ||
|  | 					else | ||
|  | 					{ | ||
|  | 						$open = true; | ||
|  | 						$char = $current; | ||
|  | 					} | ||
|  | 				} | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if (($current == ';' && !$open) || $i == $end - 1) | ||
|  | 			{ | ||
|  | 				$queries[] = substr($sql, $start, ($i - $start + 1)); | ||
|  | 				$start = $i + 1; | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return $queries; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Magic method to provide method alias support for quote() and quoteName(). | ||
|  | 	 * | ||
|  | 	 * @param   string  $method  The called method. | ||
|  | 	 * @param   array   $args    The array of arguments passed to the method. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  The aliased method's return value or null. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function __call($method, $args) | ||
|  | 	{ | ||
|  | 		if (empty($args)) | ||
|  | 		{ | ||
|  | 			return; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		switch ($method) | ||
|  | 		{ | ||
|  | 			case 'q': | ||
|  | 				return $this->quote($args[0], isset($args[1]) ? $args[1] : true); | ||
|  | 				break; | ||
|  | 			case 'qn': | ||
|  | 				return $this->quoteName($args[0], isset($args[1]) ? $args[1] : null); | ||
|  | 				break; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Constructor. | ||
|  | 	 * | ||
|  | 	 * @param   array  $options  List of options used to configure the connection | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function __construct($options) | ||
|  | 	{ | ||
|  | 		// Initialise object variables.
 | ||
|  | 		$this->_database = (isset($options['database'])) ? $options['database'] : ''; | ||
|  | 
 | ||
|  | 		$this->tablePrefix = (isset($options['prefix'])) ? $options['prefix'] : 'jos_'; | ||
|  | 		$this->count = 0; | ||
|  | 		$this->errorNum = 0; | ||
|  | 		$this->log = array(); | ||
|  | 
 | ||
|  | 		// Set class options.
 | ||
|  | 		$this->options = $options; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Alter database's character set, obtaining query string from protected member. | ||
|  | 	 * | ||
|  | 	 * @param   string  $dbName  The database name that will be altered | ||
|  | 	 * | ||
|  | 	 * @return  string  The query that alter the database query string | ||
|  | 	 * | ||
|  | 	 * @since   12.2 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function alterDbCharacterSet($dbName) | ||
|  | 	{ | ||
|  | 		if (is_null($dbName)) | ||
|  | 		{ | ||
|  | 			throw new RuntimeException('Database name must not be null.'); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		$this->setQuery($this->getAlterDbCharacterSet($dbName)); | ||
|  | 
 | ||
|  | 		return $this->execute(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Connects to the database if needed. | ||
|  | 	 * | ||
|  | 	 * @return  void  Returns void if the database connected successfully. | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function connect(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Determines if the connection to the server is active. | ||
|  | 	 * | ||
|  | 	 * @return  boolean  True if connected to the database engine. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract public function connected(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Create a new database using information from $options object, obtaining query string | ||
|  | 	 * from protected member. | ||
|  | 	 * | ||
|  | 	 * @param   stdClass  $options  Object used to pass user and database name to database driver. | ||
|  | 	 * 									This object must have "db_name" and "db_user" set. | ||
|  | 	 * @param   boolean   $utf      True if the database supports the UTF-8 character set. | ||
|  | 	 * | ||
|  | 	 * @return  string  The query that creates database | ||
|  | 	 * | ||
|  | 	 * @since   12.2 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function createDatabase($options, $utf = true) | ||
|  | 	{ | ||
|  | 		if (is_null($options)) | ||
|  | 		{ | ||
|  | 			throw new RuntimeException('$options object must not be null.'); | ||
|  | 		} | ||
|  | 		elseif (empty($options->db_name)) | ||
|  | 		{ | ||
|  | 			throw new RuntimeException('$options object must have db_name set.'); | ||
|  | 		} | ||
|  | 		elseif (empty($options->db_user)) | ||
|  | 		{ | ||
|  | 			throw new RuntimeException('$options object must have db_user set.'); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		$this->setQuery($this->getCreateDatabaseQuery($options, $utf)); | ||
|  | 
 | ||
|  | 		return $this->execute(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Disconnects the database. | ||
|  | 	 * | ||
|  | 	 * @return  void | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 */ | ||
|  | 	abstract public function disconnect(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Adds a function callable just before disconnecting the database. Parameter of the callable is $this JDatabaseDriver | ||
|  | 	 * | ||
|  | 	 * @param   callable  $callable  Function to call in disconnect() method just before disconnecting from database | ||
|  | 	 * | ||
|  | 	 * @return  void | ||
|  | 	 * | ||
|  | 	 * @since   CMS 3.1.2 | ||
|  | 	 */ | ||
|  | 	public function addDisconnectHandler($callable) | ||
|  | 	{ | ||
|  | 		$this->disconnectHandlers[] = $callable; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Drops a table from the database. | ||
|  | 	 * | ||
|  | 	 * @param   string   $table     The name of the database table to drop. | ||
|  | 	 * @param   boolean  $ifExists  Optionally specify that the table must exist before it is dropped. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseDriver     Returns this object to support chaining. | ||
|  | 	 * | ||
|  | 	 * @since   11.4 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public abstract function dropTable($table, $ifExists = true); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Escapes a string for usage in an SQL statement. | ||
|  | 	 * | ||
|  | 	 * @param   string   $text   The string to be escaped. | ||
|  | 	 * @param   boolean  $extra  Optional parameter to provide extra escaping. | ||
|  | 	 * | ||
|  | 	 * @return  string   The escaped string. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract public function escape($text, $extra = false); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to fetch a row from the result set cursor as an array. | ||
|  | 	 * | ||
|  | 	 * @param   mixed  $cursor  The optional result set cursor from which to fetch the row. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  Either the next row from the result set or false if there are no more rows. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract protected function fetchArray($cursor = null); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to fetch a row from the result set cursor as an associative array. | ||
|  | 	 * | ||
|  | 	 * @param   mixed  $cursor  The optional result set cursor from which to fetch the row. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  Either the next row from the result set or false if there are no more rows. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract protected function fetchAssoc($cursor = null); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to fetch a row from the result set cursor as an object. | ||
|  | 	 * | ||
|  | 	 * @param   mixed   $cursor  The optional result set cursor from which to fetch the row. | ||
|  | 	 * @param   string  $class   The class name to use for the returned row object. | ||
|  | 	 * | ||
|  | 	 * @return  mixed   Either the next row from the result set or false if there are no more rows. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract protected function fetchObject($cursor = null, $class = 'stdClass'); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to free up the memory used for the result set. | ||
|  | 	 * | ||
|  | 	 * @param   mixed  $cursor  The optional result set cursor from which to fetch the row. | ||
|  | 	 * | ||
|  | 	 * @return  void | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract protected function freeResult($cursor = null); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the number of affected rows for the previous executed SQL statement. | ||
|  | 	 * | ||
|  | 	 * @return  integer  The number of affected rows. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract public function getAffectedRows(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Return the query string to alter the database character set. | ||
|  | 	 * | ||
|  | 	 * @param   string  $dbName  The database name | ||
|  | 	 * | ||
|  | 	 * @return  string  The query that alter the database query string | ||
|  | 	 * | ||
|  | 	 * @since   12.2 | ||
|  | 	 */ | ||
|  | 	protected function getAlterDbCharacterSet($dbName) | ||
|  | 	{ | ||
|  | 		return 'ALTER DATABASE ' . $this->quoteName($dbName) . ' CHARACTER SET `utf8`'; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Return the query string to create new Database. | ||
|  | 	 * Each database driver, other than MySQL, need to override this member to return correct string. | ||
|  | 	 * | ||
|  | 	 * @param   stdClass  $options  Object used to pass user and database name to database driver. | ||
|  | 	 *                   This object must have "db_name" and "db_user" set. | ||
|  | 	 * @param   boolean   $utf      True if the database supports the UTF-8 character set. | ||
|  | 	 * | ||
|  | 	 * @return  string  The query that creates database | ||
|  | 	 * | ||
|  | 	 * @since   12.2 | ||
|  | 	 */ | ||
|  | 	protected function getCreateDatabaseQuery($options, $utf) | ||
|  | 	{ | ||
|  | 		if ($utf) | ||
|  | 		{ | ||
|  | 			return 'CREATE DATABASE ' . $this->quoteName($options->db_name) . ' CHARACTER SET `utf8`'; | ||
|  | 		} | ||
|  | 		return 'CREATE DATABASE ' . $this->quoteName($options->db_name); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get the database collation in use by sampling a text field of a table in the database. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  The collation in use by the database or boolean false if not supported. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract public function getCollation(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method that 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  The underlying database connection resource. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function getConnection() | ||
|  | 	{ | ||
|  | 		return $this->connection; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the total number of SQL statements executed by the database driver. | ||
|  | 	 * | ||
|  | 	 * @return  integer | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function getCount() | ||
|  | 	{ | ||
|  | 		return $this->count; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Gets the name of the database used by this conneciton. | ||
|  | 	 * | ||
|  | 	 * @return  string | ||
|  | 	 * | ||
|  | 	 * @since   11.4 | ||
|  | 	 */ | ||
|  | 	protected function getDatabase() | ||
|  | 	{ | ||
|  | 		return $this->_database; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Returns a PHP date() function compliant date format for the database driver. | ||
|  | 	 * | ||
|  | 	 * @return  string  The format string. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function getDateFormat() | ||
|  | 	{ | ||
|  | 		return 'Y-m-d H:i:s'; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the database driver SQL statement log. | ||
|  | 	 * | ||
|  | 	 * @return  array  SQL statements executed by the database driver. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function getLog() | ||
|  | 	{ | ||
|  | 		return $this->log; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the database driver SQL statement log. | ||
|  | 	 * | ||
|  | 	 * @return  array  SQL statements executed by the database driver. | ||
|  | 	 * | ||
|  | 	 * @since   CMS 3.1.2 | ||
|  | 	 */ | ||
|  | 	public function getTimings() | ||
|  | 	{ | ||
|  | 		return $this->timings; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the database driver SQL statement log. | ||
|  | 	 * | ||
|  | 	 * @return  array  SQL statements executed by the database driver. | ||
|  | 	 * | ||
|  | 	 * @since   CMS 3.1.2 | ||
|  | 	 */ | ||
|  | 	public function getCallStacks() | ||
|  | 	{ | ||
|  | 		return $this->callStacks; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the minimum supported database version. | ||
|  | 	 * | ||
|  | 	 * @return  string  The minimum version number for the database driver. | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 */ | ||
|  | 	public function getMinimum() | ||
|  | 	{ | ||
|  | 		return static::$dbMinimum; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the null or zero representation of a timestamp for the database driver. | ||
|  | 	 * | ||
|  | 	 * @return  string  Null or zero representation of a timestamp. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function getNullDate() | ||
|  | 	{ | ||
|  | 		return $this->nullDate; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the number of returned rows for the previous executed SQL statement. | ||
|  | 	 * | ||
|  | 	 * @param   resource  $cursor  An optional database cursor resource to extract the row count from. | ||
|  | 	 * | ||
|  | 	 * @return  integer   The number of returned rows. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract public function getNumRows($cursor = null); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the common table prefix for the database driver. | ||
|  | 	 * | ||
|  | 	 * @return  string  The common database table prefix. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function getPrefix() | ||
|  | 	{ | ||
|  | 		return $this->tablePrefix; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Gets an exporter class object. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseExporter  An exporter object. | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function getExporter() | ||
|  | 	{ | ||
|  | 		// Derive the class name from the driver.
 | ||
|  | 		$class = 'JDatabaseExporter' . ucfirst($this->name); | ||
|  | 
 | ||
|  | 		// Make sure we have an exporter class for this driver.
 | ||
|  | 		if (!class_exists($class)) | ||
|  | 		{ | ||
|  | 			// If it doesn't exist we are at an impasse so throw an exception.
 | ||
|  | 			throw new RuntimeException('Database Exporter not found.'); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		$o = new $class; | ||
|  | 		$o->setDbo($this); | ||
|  | 
 | ||
|  | 		return $o; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Gets an importer class object. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseImporter  An importer object. | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function getImporter() | ||
|  | 	{ | ||
|  | 		// Derive the class name from the driver.
 | ||
|  | 		$class = 'JDatabaseImporter' . ucfirst($this->name); | ||
|  | 
 | ||
|  | 		// Make sure we have an importer class for this driver.
 | ||
|  | 		if (!class_exists($class)) | ||
|  | 		{ | ||
|  | 			// If it doesn't exist we are at an impasse so throw an exception.
 | ||
|  | 			throw new RuntimeException('Database Importer not found'); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		$o = new $class; | ||
|  | 		$o->setDbo($this); | ||
|  | 
 | ||
|  | 		return $o; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the current query object or a new JDatabaseQuery object. | ||
|  | 	 * | ||
|  | 	 * @param   boolean  $new  False to return the current query object, True to return a new JDatabaseQuery object. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseQuery  The current query object or a new object extending the JDatabaseQuery class. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function getQuery($new = false) | ||
|  | 	{ | ||
|  | 		if ($new) | ||
|  | 		{ | ||
|  | 			// Derive the class name from the driver.
 | ||
|  | 			$class = 'JDatabaseQuery' . ucfirst($this->name); | ||
|  | 
 | ||
|  | 			// Make sure we have a query class for this driver.
 | ||
|  | 			if (!class_exists($class)) | ||
|  | 			{ | ||
|  | 				// If it doesn't exist we are at an impasse so throw an exception.
 | ||
|  | 				throw new RuntimeException('Database Query Class not found.'); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return new $class($this); | ||
|  | 		} | ||
|  | 		else | ||
|  | 		{ | ||
|  | 			return $this->sql; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get a new iterator on the current query. | ||
|  | 	 * | ||
|  | 	 * @param   string  $column  An option column to use as the iterator key. | ||
|  | 	 * @param   string  $class   The class of object that is returned. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseIterator  A new database iterator. | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function getIterator($column = null, $class = 'stdClass') | ||
|  | 	{ | ||
|  | 		// Derive the class name from the driver.
 | ||
|  | 		$iteratorClass = 'JDatabaseIterator' . ucfirst($this->name); | ||
|  | 
 | ||
|  | 		// Make sure we have an iterator class for this driver.
 | ||
|  | 		if (!class_exists($iteratorClass)) | ||
|  | 		{ | ||
|  | 			// If it doesn't exist we are at an impasse so throw an exception.
 | ||
|  | 			throw new RuntimeException(sprintf('class *%s* is not defined', $iteratorClass)); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Return a new iterator
 | ||
|  | 		return new $iteratorClass($this->execute(), $column, $class); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Retrieves field information about the given tables. | ||
|  | 	 * | ||
|  | 	 * @param   string   $table     The name of the database table. | ||
|  | 	 * @param   boolean  $typeOnly  True (default) to only return field types. | ||
|  | 	 * | ||
|  | 	 * @return  array  An array of fields by table. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function getTableColumns($table, $typeOnly = true); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Shows the table CREATE statement that creates the given tables. | ||
|  | 	 * | ||
|  | 	 * @param   mixed  $tables  A table name or a list of table names. | ||
|  | 	 * | ||
|  | 	 * @return  array  A list of the create SQL for the tables. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function getTableCreate($tables); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Retrieves field information about the given tables. | ||
|  | 	 * | ||
|  | 	 * @param   mixed  $tables  A table name or a list of table names. | ||
|  | 	 * | ||
|  | 	 * @return  array  An array of keys for the table(s). | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function getTableKeys($tables); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get an array of all tables in the database. | ||
|  | 	 * | ||
|  | 	 * @return  array  An array of all the tables in the database. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function getTableList(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Determine whether or not the database engine supports UTF-8 character encoding. | ||
|  | 	 * | ||
|  | 	 * @return  boolean  True if the database engine supports UTF-8 character encoding. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @deprecated 12.3 (Platform) & 4.0 (CMS) - Use hasUTFSupport() instead | ||
|  | 	 */ | ||
|  | 	public function getUTFSupport() | ||
|  | 	{ | ||
|  | 		JLog::add('JDatabaseDriver::getUTFSupport() is deprecated. Use JDatabaseDriver::hasUTFSupport() instead.', JLog::WARNING, 'deprecated'); | ||
|  | 		return $this->hasUTFSupport(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Determine whether or not the database engine supports UTF-8 character encoding. | ||
|  | 	 * | ||
|  | 	 * @return  boolean  True if the database engine supports UTF-8 character encoding. | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 */ | ||
|  | 	public function hasUTFSupport() | ||
|  | 	{ | ||
|  | 		return $this->utf; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Get the version of the database connector | ||
|  | 	 * | ||
|  | 	 * @return  string  The database connector version. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract public function getVersion(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get the auto-incremented value from the last INSERT statement. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  The value of the auto-increment field from the last inserted row. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract public function insertid(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Inserts a row into a table based on an object's properties. | ||
|  | 	 * | ||
|  | 	 * @param   string  $table    The name of the database table to insert into. | ||
|  | 	 * @param   object  &$object  A reference to an object whose public properties match the table fields. | ||
|  | 	 * @param   string  $key      The name of the primary key. If provided the object property is updated. | ||
|  | 	 * | ||
|  | 	 * @return  boolean    True on success. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function insertObject($table, &$object, $key = null) | ||
|  | 	{ | ||
|  | 		$fields = array(); | ||
|  | 		$values = array(); | ||
|  | 
 | ||
|  | 		// Iterate over the object variables to build the query fields and values.
 | ||
|  | 		foreach (get_object_vars($object) as $k => $v) | ||
|  | 		{ | ||
|  | 			// Only process non-null scalars.
 | ||
|  | 			if (is_array($v) or is_object($v) or $v === null) | ||
|  | 			{ | ||
|  | 				continue; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Ignore any internal fields.
 | ||
|  | 			if ($k[0] == '_') | ||
|  | 			{ | ||
|  | 				continue; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Prepare and sanitize the fields and values for the database query.
 | ||
|  | 			$fields[] = $this->quoteName($k); | ||
|  | 			$values[] = $this->quote($v); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Create the base insert statement.
 | ||
|  | 		$query = $this->getQuery(true) | ||
|  | 			->insert($this->quoteName($table)) | ||
|  | 			->columns($fields) | ||
|  | 			->values(implode(',', $values)); | ||
|  | 
 | ||
|  | 		// Set the query and execute the insert.
 | ||
|  | 		$this->setQuery($query); | ||
|  | 
 | ||
|  | 		if (!$this->execute()) | ||
|  | 		{ | ||
|  | 			return false; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Update the primary key if it exists.
 | ||
|  | 		$id = $this->insertid(); | ||
|  | 
 | ||
|  | 		if ($key && $id && is_string($key)) | ||
|  | 		{ | ||
|  | 			$object->$key = $id; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return true; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to check whether the installed database version is supported by the database driver | ||
|  | 	 * | ||
|  | 	 * @return  boolean  True if the database version is supported | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 */ | ||
|  | 	public function isMinimumVersion() | ||
|  | 	{ | ||
|  | 		return version_compare($this->getVersion(), static::$dbMinimum) >= 0; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get the first row of the result set from the database query as an associative array | ||
|  | 	 * of ['field_name' => 'row_value']. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  The return value or null if the query failed. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadAssoc() | ||
|  | 	{ | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		$ret = null; | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if (!($cursor = $this->execute())) | ||
|  | 		{ | ||
|  | 			return null; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get the first row from the result set as an associative array.
 | ||
|  | 		if ($array = $this->fetchAssoc($cursor)) | ||
|  | 		{ | ||
|  | 			$ret = $array; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 
 | ||
|  | 		return $ret; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get an array of the result set rows from the database query where each row is an associative array | ||
|  | 	 * of ['field_name' => 'row_value'].  The array of rows can optionally be keyed by a field name, but defaults to | ||
|  | 	 * a sequential numeric array. | ||
|  | 	 * | ||
|  | 	 * NOTE: Chosing to key the result array by a non-unique field name can result in unwanted | ||
|  | 	 * behavior and should be avoided. | ||
|  | 	 * | ||
|  | 	 * @param   string  $key     The name of a field on which to key the result array. | ||
|  | 	 * @param   string  $column  An optional column name. Instead of the whole row, only this column value will be in | ||
|  | 	 * the result array. | ||
|  | 	 * | ||
|  | 	 * @return  mixed   The return value or null if the query failed. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadAssocList($key = null, $column = null) | ||
|  | 	{ | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		$array = array(); | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if (!($cursor = $this->execute())) | ||
|  | 		{ | ||
|  | 			return null; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get all of the rows from the result set.
 | ||
|  | 		while ($row = $this->fetchAssoc($cursor)) | ||
|  | 		{ | ||
|  | 			$value = ($column) ? (isset($row[$column]) ? $row[$column] : $row) : $row; | ||
|  | 
 | ||
|  | 			if ($key) | ||
|  | 			{ | ||
|  | 				$array[$row[$key]] = $value; | ||
|  | 			} | ||
|  | 			else | ||
|  | 			{ | ||
|  | 				$array[] = $value; | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 
 | ||
|  | 		return $array; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get an array of values from the <var>$offset</var> field in each row of the result set from | ||
|  | 	 * the database query. | ||
|  | 	 * | ||
|  | 	 * @param   integer  $offset  The row offset to use to build the result array. | ||
|  | 	 * | ||
|  | 	 * @return  mixed    The return value or null if the query failed. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadColumn($offset = 0) | ||
|  | 	{ | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		$array = array(); | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if (!($cursor = $this->execute())) | ||
|  | 		{ | ||
|  | 			return null; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get all of the rows from the result set as arrays.
 | ||
|  | 		while ($row = $this->fetchArray($cursor)) | ||
|  | 		{ | ||
|  | 			$array[] = $row[$offset]; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 
 | ||
|  | 		return $array; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get the next row in the result set from the database query as an object. | ||
|  | 	 * | ||
|  | 	 * @param   string  $class  The class name to use for the returned row object. | ||
|  | 	 * | ||
|  | 	 * @return  mixed   The result of the query as an array, false if there are no more rows. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadNextObject($class = 'stdClass') | ||
|  | 	{ | ||
|  | 		JLog::add(__METHOD__ . '() is deprecated. Use JDatabase::getIterator() instead.', JLog::WARNING, 'deprecated'); | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		static $cursor = null; | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if ( is_null($cursor) ) | ||
|  | 		{ | ||
|  | 			if (!($cursor = $this->execute())) | ||
|  | 			{ | ||
|  | 				return $this->errorNum ? null : false; | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get the next row from the result set as an object of type $class.
 | ||
|  | 		if ($row = $this->fetchObject($cursor, $class)) | ||
|  | 		{ | ||
|  | 			return $row; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 		$cursor = null; | ||
|  | 
 | ||
|  | 		return false; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get the next row in the result set from the database query as an array. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  The result of the query as an array, false if there are no more rows. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 * @deprecated  N/A (CMS)  Use JDatabaseDriver::getIterator() instead | ||
|  | 	 */ | ||
|  | 	public function loadNextRow() | ||
|  | 	{ | ||
|  | 		JLog::add('JDatabaseDriver::loadNextRow() is deprecated. Use JDatabaseDriver::getIterator() instead.', JLog::WARNING, 'deprecated'); | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		static $cursor = null; | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if ( is_null($cursor) ) | ||
|  | 		{ | ||
|  | 			if (!($cursor = $this->execute())) | ||
|  | 			{ | ||
|  | 				return $this->errorNum ? null : false; | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get the next row from the result set as an object of type $class.
 | ||
|  | 		if ($row = $this->fetchArray($cursor)) | ||
|  | 		{ | ||
|  | 			return $row; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 		$cursor = null; | ||
|  | 
 | ||
|  | 		return false; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get the first row of the result set from the database query as an object. | ||
|  | 	 * | ||
|  | 	 * @param   string  $class  The class name to use for the returned row object. | ||
|  | 	 * | ||
|  | 	 * @return  mixed   The return value or null if the query failed. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadObject($class = 'stdClass') | ||
|  | 	{ | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		$ret = null; | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if (!($cursor = $this->execute())) | ||
|  | 		{ | ||
|  | 			return null; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get the first row from the result set as an object of type $class.
 | ||
|  | 		if ($object = $this->fetchObject($cursor, $class)) | ||
|  | 		{ | ||
|  | 			$ret = $object; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 
 | ||
|  | 		return $ret; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get an array of the result set rows from the database query where each row is an object.  The array | ||
|  | 	 * of objects can optionally be keyed by a field name, but defaults to a sequential numeric array. | ||
|  | 	 * | ||
|  | 	 * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted | ||
|  | 	 * behavior and should be avoided. | ||
|  | 	 * | ||
|  | 	 * @param   string  $key    The name of a field on which to key the result array. | ||
|  | 	 * @param   string  $class  The class name to use for the returned row objects. | ||
|  | 	 * | ||
|  | 	 * @return  mixed   The return value or null if the query failed. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadObjectList($key = '', $class = 'stdClass') | ||
|  | 	{ | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		$array = array(); | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if (!($cursor = $this->execute())) | ||
|  | 		{ | ||
|  | 			return null; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get all of the rows from the result set as objects of type $class.
 | ||
|  | 		while ($row = $this->fetchObject($cursor, $class)) | ||
|  | 		{ | ||
|  | 			if ($key) | ||
|  | 			{ | ||
|  | 				$array[$row->$key] = $row; | ||
|  | 			} | ||
|  | 			else | ||
|  | 			{ | ||
|  | 				$array[] = $row; | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 
 | ||
|  | 		return $array; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get the first field of the first row of the result set from the database query. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  The return value or null if the query failed. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadResult() | ||
|  | 	{ | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		$ret = null; | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if (!($cursor = $this->execute())) | ||
|  | 		{ | ||
|  | 			return null; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get the first row from the result set as an array.
 | ||
|  | 		if ($row = $this->fetchArray($cursor)) | ||
|  | 		{ | ||
|  | 			$ret = $row[0]; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 
 | ||
|  | 		return $ret; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get the first row of the result set from the database query as an array.  Columns are indexed | ||
|  | 	 * numerically so the first column in the result set would be accessible via <var>$row[0]</var>, etc. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  The return value or null if the query failed. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadRow() | ||
|  | 	{ | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		$ret = null; | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if (!($cursor = $this->execute())) | ||
|  | 		{ | ||
|  | 			return null; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get the first row from the result set as an array.
 | ||
|  | 		if ($row = $this->fetchArray($cursor)) | ||
|  | 		{ | ||
|  | 			$ret = $row; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 
 | ||
|  | 		return $ret; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to get an array of the result set rows from the database query where each row is an array.  The array | ||
|  | 	 * of objects can optionally be keyed by a field offset, but defaults to a sequential numeric array. | ||
|  | 	 * | ||
|  | 	 * NOTE: Choosing to key the result array by a non-unique field can result in unwanted | ||
|  | 	 * behavior and should be avoided. | ||
|  | 	 * | ||
|  | 	 * @param   string  $key  The name of a field on which to key the result array. | ||
|  | 	 * | ||
|  | 	 * @return  mixed   The return value or null if the query failed. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function loadRowList($key = null) | ||
|  | 	{ | ||
|  | 		$this->connect(); | ||
|  | 
 | ||
|  | 		$array = array(); | ||
|  | 
 | ||
|  | 		// Execute the query and get the result set cursor.
 | ||
|  | 		if (!($cursor = $this->execute())) | ||
|  | 		{ | ||
|  | 			return null; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Get all of the rows from the result set as arrays.
 | ||
|  | 		while ($row = $this->fetchArray($cursor)) | ||
|  | 		{ | ||
|  | 			if ($key !== null) | ||
|  | 			{ | ||
|  | 				$array[$row[$key]] = $row; | ||
|  | 			} | ||
|  | 			else | ||
|  | 			{ | ||
|  | 				$array[] = $row; | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Free up system resources and return.
 | ||
|  | 		$this->freeResult($cursor); | ||
|  | 
 | ||
|  | 		return $array; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Locks a table in the database. | ||
|  | 	 * | ||
|  | 	 * @param   string  $tableName  The name of the table to unlock. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseDriver     Returns this object to support chaining. | ||
|  | 	 * | ||
|  | 	 * @since   11.4 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public abstract function lockTable($tableName); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Quotes and optionally escapes a string to database requirements for use in database queries. | ||
|  | 	 * | ||
|  | 	 * @param   mixed    $text    A string or an array of strings to quote. | ||
|  | 	 * @param   boolean  $escape  True (default) to escape the string, false to leave it unchanged. | ||
|  | 	 * | ||
|  | 	 * @return  string  The quoted input string. | ||
|  | 	 * | ||
|  | 	 * @note    Accepting an array of strings was added in 12.3. | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function quote($text, $escape = true) | ||
|  | 	{ | ||
|  | 		if (is_array($text)) | ||
|  | 		{ | ||
|  | 			foreach ($text as $k => $v) | ||
|  | 			{ | ||
|  | 				$text[$k] = $this->quote($v, $escape); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return $text; | ||
|  | 		} | ||
|  | 		else | ||
|  | 		{ | ||
|  | 			return '\'' . ($escape ? $this->escape($text) : $text) . '\''; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection | ||
|  | 	 * risks and reserved word conflicts. | ||
|  | 	 * | ||
|  | 	 * @param   mixed  $name  The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes. | ||
|  | 	 *                        Each type supports dot-notation name. | ||
|  | 	 * @param   mixed  $as    The AS query part associated to $name. It can be string or array, in latter case it has to be | ||
|  | 	 *                        same length of $name; if is null there will not be any AS part for string or array element. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  The quote wrapped name, same type of $name. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function quoteName($name, $as = null) | ||
|  | 	{ | ||
|  | 		if (is_string($name)) | ||
|  | 		{ | ||
|  | 			$quotedName = $this->quoteNameStr(explode('.', $name)); | ||
|  | 
 | ||
|  | 			$quotedAs = ''; | ||
|  | 
 | ||
|  | 			if (!is_null($as)) | ||
|  | 			{ | ||
|  | 				settype($as, 'array'); | ||
|  | 				$quotedAs .= ' AS ' . $this->quoteNameStr($as); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return $quotedName . $quotedAs; | ||
|  | 		} | ||
|  | 		else | ||
|  | 		{ | ||
|  | 			$fin = array(); | ||
|  | 
 | ||
|  | 			if (is_null($as)) | ||
|  | 			{ | ||
|  | 				foreach ($name as $str) | ||
|  | 				{ | ||
|  | 					$fin[] = $this->quoteName($str); | ||
|  | 				} | ||
|  | 			} | ||
|  | 			elseif (is_array($name) && (count($name) == count($as))) | ||
|  | 			{ | ||
|  | 				$count = count($name); | ||
|  | 
 | ||
|  | 				for ($i = 0; $i < $count; $i++) | ||
|  | 				{ | ||
|  | 					$fin[] = $this->quoteName($name[$i], $as[$i]); | ||
|  | 				} | ||
|  | 			} | ||
|  | 
 | ||
|  | 			return $fin; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Quote strings coming from quoteName call. | ||
|  | 	 * | ||
|  | 	 * @param   array  $strArr  Array of strings coming from quoteName dot-explosion. | ||
|  | 	 * | ||
|  | 	 * @return  string  Dot-imploded string of quoted parts. | ||
|  | 	 * | ||
|  | 	 * @since 11.3 | ||
|  | 	 */ | ||
|  | 	protected function quoteNameStr($strArr) | ||
|  | 	{ | ||
|  | 		$parts = array(); | ||
|  | 		$q = $this->nameQuote; | ||
|  | 
 | ||
|  | 		foreach ($strArr as $part) | ||
|  | 		{ | ||
|  | 			if (is_null($part)) | ||
|  | 			{ | ||
|  | 				continue; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			if (strlen($q) == 1) | ||
|  | 			{ | ||
|  | 				$parts[] = $q . $part . $q; | ||
|  | 			} | ||
|  | 			else | ||
|  | 			{ | ||
|  | 				$parts[] = $q{0} . $part . $q{1}; | ||
|  | 			} | ||
|  | 		} | ||
|  | 
 | ||
|  | 		return implode('.', $parts); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * This function replaces a string identifier <var>$prefix</var> with the string held is the | ||
|  | 	 * <var>tablePrefix</var> class variable. | ||
|  | 	 * | ||
|  | 	 * @param   string  $sql     The SQL statement to prepare. | ||
|  | 	 * @param   string  $prefix  The common table prefix. | ||
|  | 	 * | ||
|  | 	 * @return  string  The processed SQL statement. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function replacePrefix($sql, $prefix = '#__') | ||
|  | 	{ | ||
|  | 		$startPos = 0; | ||
|  | 		$literal = ''; | ||
|  | 
 | ||
|  | 		$sql = trim($sql); | ||
|  | 		$n = strlen($sql); | ||
|  | 
 | ||
|  | 		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->tablePrefix, 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; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Renames a table in the database. | ||
|  | 	 * | ||
|  | 	 * @param   string  $oldTable  The name of the table to be renamed | ||
|  | 	 * @param   string  $newTable  The new name for the table. | ||
|  | 	 * @param   string  $backup    Table prefix | ||
|  | 	 * @param   string  $prefix    For the table - used to rename constraints in non-mysql databases | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseDriver    Returns this object to support chaining. | ||
|  | 	 * | ||
|  | 	 * @since   11.4 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public abstract function renameTable($oldTable, $newTable, $backup = null, $prefix = null); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Select a database for use. | ||
|  | 	 * | ||
|  | 	 * @param   string  $database  The name of the database to select for use. | ||
|  | 	 * | ||
|  | 	 * @return  boolean  True if the database was successfully selected. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function select($database); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Sets the database debugging state for the driver. | ||
|  | 	 * | ||
|  | 	 * @param   boolean  $level  True to enable debugging. | ||
|  | 	 * | ||
|  | 	 * @return  boolean  The old debugging level. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function setDebug($level) | ||
|  | 	{ | ||
|  | 		$previous = $this->debug; | ||
|  | 		$this->debug = (bool) $level; | ||
|  | 
 | ||
|  | 		return $previous; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Sets the SQL statement string for later execution. | ||
|  | 	 * | ||
|  | 	 * @param   mixed    $query   The SQL statement to set either as a JDatabaseQuery object or a string. | ||
|  | 	 * @param   integer  $offset  The affected row offset to set. | ||
|  | 	 * @param   integer  $limit   The maximum affected rows to set. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseDriver  This object to support method chaining. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	public function setQuery($query, $offset = 0, $limit = 0) | ||
|  | 	{ | ||
|  | 		$this->sql = $query; | ||
|  | 		$this->limit = (int) max(0, $limit); | ||
|  | 		$this->offset = (int) max(0, $offset); | ||
|  | 
 | ||
|  | 		return $this; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Set the connection to use UTF-8 character encoding. | ||
|  | 	 * | ||
|  | 	 * @return  boolean  True on success. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 */ | ||
|  | 	abstract public function setUTF(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to commit a transaction. | ||
|  | 	 * | ||
|  | 	 * @param   boolean  $toSavepoint  If true, commit to the last savepoint. | ||
|  | 	 * | ||
|  | 	 * @return  void | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function transactionCommit($toSavepoint = false); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to roll back a transaction. | ||
|  | 	 * | ||
|  | 	 * @param   boolean  $toSavepoint  If true, rollback to the last savepoint. | ||
|  | 	 * | ||
|  | 	 * @return  void | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function transactionRollback($toSavepoint = false); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to initialize a transaction. | ||
|  | 	 * | ||
|  | 	 * @param   boolean  $asSavepoint  If true and a transaction is already active, a savepoint will be created. | ||
|  | 	 * | ||
|  | 	 * @return  void | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function transactionStart($asSavepoint = false); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Method to truncate a table. | ||
|  | 	 * | ||
|  | 	 * @param   string  $table  The table to truncate | ||
|  | 	 * | ||
|  | 	 * @return  void | ||
|  | 	 * | ||
|  | 	 * @since   11.3 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function truncateTable($table) | ||
|  | 	{ | ||
|  | 		$this->setQuery('TRUNCATE TABLE ' . $this->quoteName($table)); | ||
|  | 		$this->execute(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Updates a row in a table based on an object's properties. | ||
|  | 	 * | ||
|  | 	 * @param   string   $table    The name of the database table to update. | ||
|  | 	 * @param   object   &$object  A reference to an object whose public properties match the table fields. | ||
|  | 	 * @param   array    $key      The name of the primary key. | ||
|  | 	 * @param   boolean  $nulls    True to update null fields or false to ignore them. | ||
|  | 	 * | ||
|  | 	 * @return  boolean  True on success. | ||
|  | 	 * | ||
|  | 	 * @since   11.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public function updateObject($table, &$object, $key, $nulls = false) | ||
|  | 	{ | ||
|  | 		$fields = array(); | ||
|  | 		$where = array(); | ||
|  | 
 | ||
|  | 		if (is_string($key)) | ||
|  | 		{ | ||
|  | 			$key = array($key); | ||
|  | 		} | ||
|  | 
 | ||
|  | 		if (is_object($key)) | ||
|  | 		{ | ||
|  | 			$key = (array) $key; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Create the base update statement.
 | ||
|  | 		$statement = 'UPDATE ' . $this->quoteName($table) . ' SET %s WHERE %s'; | ||
|  | 
 | ||
|  | 		// Iterate over the object variables to build the query fields/value pairs.
 | ||
|  | 		foreach (get_object_vars($object) as $k => $v) | ||
|  | 		{ | ||
|  | 			// Only process scalars that are not internal fields.
 | ||
|  | 			if (is_array($v) or is_object($v) or $k[0] == '_') | ||
|  | 			{ | ||
|  | 				continue; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Set the primary key to the WHERE clause instead of a field to update.
 | ||
|  | 			if (in_array($k, $key)) | ||
|  | 			{ | ||
|  | 				$where[] = $this->quoteName($k) . '=' . $this->quote($v); | ||
|  | 				continue; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Prepare and sanitize the fields and values for the database query.
 | ||
|  | 			if ($v === null) | ||
|  | 			{ | ||
|  | 				// If the value is null and we want to update nulls then set it.
 | ||
|  | 				if ($nulls) | ||
|  | 				{ | ||
|  | 					$val = 'NULL'; | ||
|  | 				} | ||
|  | 				// If the value is null and we do not want to update nulls then ignore this field.
 | ||
|  | 				else | ||
|  | 				{ | ||
|  | 					continue; | ||
|  | 				} | ||
|  | 			} | ||
|  | 			// The field is not null so we prep it for update.
 | ||
|  | 			else | ||
|  | 			{ | ||
|  | 				$val = $this->quote($v); | ||
|  | 			} | ||
|  | 
 | ||
|  | 			// Add the field to be updated.
 | ||
|  | 			$fields[] = $this->quoteName($k) . '=' . $val; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// We don't have any fields to update.
 | ||
|  | 		if (empty($fields)) | ||
|  | 		{ | ||
|  | 			return true; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Set the query and execute the update.
 | ||
|  | 		$this->setQuery(sprintf($statement, implode(",", $fields), implode(' AND ', $where))); | ||
|  | 
 | ||
|  | 		return $this->execute(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Execute the SQL statement. | ||
|  | 	 * | ||
|  | 	 * @return  mixed  A database cursor resource on success, boolean false on failure. | ||
|  | 	 * | ||
|  | 	 * @since   12.1 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	abstract public function execute(); | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * Unlocks tables in the database. | ||
|  | 	 * | ||
|  | 	 * @return  JDatabaseDriver  Returns this object to support chaining. | ||
|  | 	 * | ||
|  | 	 * @since   11.4 | ||
|  | 	 * @throws  RuntimeException | ||
|  | 	 */ | ||
|  | 	public abstract function unlockTables(); | ||
|  | } |