Spade

Mini Shell

Directory:~$ /home/lmsyaran/public_html/joomla4/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/public_html/joomla4/query.tar

element.php000064400000005204151156424730006717 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Query Element Class.
 *
 * @property-read    string  $name      The name of the element.
 * @property-read    array   $elements  An array of elements.
 * @property-read    string  $glue      Glue piece.
 *
 * @since  1.7.0
 */
class JDatabaseQueryElement
{
	/**
	 * @var    string  The name of the element.
	 * @since  1.7.0
	 */
	protected $name = null;

	/**
	 * @var    array  An array of elements.
	 * @since  1.7.0
	 */
	protected $elements = null;

	/**
	 * @var    string  Glue piece.
	 * @since  1.7.0
	 */
	protected $glue = null;

	/**
	 * Constructor.
	 *
	 * @param   string  $name      The name of the element.
	 * @param   mixed   $elements  String or array.
	 * @param   string  $glue      The glue for elements.
	 *
	 * @since   1.7.0
	 */
	public function __construct($name, $elements, $glue = ',')
	{
		$this->elements = array();
		$this->name = $name;
		$this->glue = $glue;

		$this->append($elements);
	}

	/**
	 * Magic function to convert the query element to a string.
	 *
	 * @return  string
	 *
	 * @since   1.7.0
	 */
	public function __toString()
	{
		if (substr($this->name, -2) == '()')
		{
			return PHP_EOL . substr($this->name, 0, -2) . '(' .
implode($this->glue, $this->elements) . ')';
		}
		else
		{
			return PHP_EOL . $this->name . ' ' .
implode($this->glue, $this->elements);
		}
	}

	/**
	 * Appends element parts to the internal list.
	 *
	 * @param   mixed  $elements  String or array.
	 *
	 * @return  void
	 *
	 * @since   1.7.0
	 */
	public function append($elements)
	{
		if (is_array($elements))
		{
			$this->elements = array_merge($this->elements, $elements);
		}
		else
		{
			$this->elements[] = $elements;
		}
	}

	/**
	 * Gets the elements of this element.
	 *
	 * @return  array
	 *
	 * @since   1.7.0
	 */
	public function getElements()
	{
		return $this->elements;
	}

	/**
	 * Sets the name of this element.
	 *
	 * @param   string  $name  Name of the element.
	 *
	 * @return  JDatabaseQueryElement  Returns this object to allow chaining.
	 *
	 * @since   3.6
	 */
	public function setName($name)
	{
		$this->name = $name;

		return $this;
	}

	/**
	 * Method to provide deep copy support to nested objects and arrays
	 * when cloning.
	 *
	 * @return  void
	 *
	 * @since   1.7.3
	 */
	public function __clone()
	{
		foreach ($this as $k => $v)
		{
			if (is_object($v) || is_array($v))
			{
				$this->{$k} = unserialize(serialize($v));
			}
		}
	}
}
limitable.php000064400000003236151156424730007233 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Joomla Database Query Limitable Interface.
 * Adds bind/unbind methods as well as a getBounded() method
 * to retrieve the stored bounded variables on demand prior to
 * query execution.
 *
 * @since  3.0.0
 */
interface JDatabaseQueryLimitable
{
	/**
	 * Method to modify a query already in string format with the needed
	 * additions to make the query limited to a particular number of
	 * results, or start at a particular offset. This method is used
	 * automatically by the __toString() method if it detects that the
	 * query implements the JDatabaseQueryLimitable interface.
	 *
	 * @param   string   $query   The query in string format
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  string
	 *
	 * @since   3.0.0
	 */
	public function processLimit($query, $limit, $offset = 0);

	/**
	 * Sets the offset and limit for the result set, if the database driver
supports it.
	 *
	 * Usage:
	 * $query->setLimit(100, 0); (retrieve 100 rows, starting at first
record)
	 * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th
record)
	 *
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   3.0.0
	 */
	public function setLimit($limit = 0, $offset = 0);
}
mysql.php000064400000000674151156424730006441 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Query Building Class.
 *
 * @since       1.7.0
 * @deprecated  4.0  Use MySQLi or PDO MySQL instead
 */
class JDatabaseQueryMysql extends JDatabaseQueryMysqli
{
}
mysqli.php000064400000012315151156424730006605 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Query Building Class.
 *
 * @since  1.7.0
 */
class JDatabaseQueryMysqli extends JDatabaseQuery implements
JDatabaseQueryLimitable
{
	/**
	 * @var    integer  The offset for the result set.
	 * @since  3.0.0
	 */
	protected $offset;

	/**
	 * @var    integer  The limit for the result set.
	 * @since  3.0.0
	 */
	protected $limit;

	/**
	 * Magic function to convert the query to a string.
	 *
	 * @return  string  The completed query.
	 *
	 * @since   1.7.0
	 */
	public function __toString()
	{
		switch ($this->type)
		{
			case 'select':
				if ($this->selectRowNumber)
				{
					$orderBy      = $this->selectRowNumber['orderBy'];
					$tmpOffset    = $this->offset;
					$tmpLimit     = $this->limit;
					$this->offset = 0;
					$this->limit  = 0;
					$tmpOrder     = $this->order;
					$this->order  = null;
					$query        = parent::__toString();
					$this->order  = $tmpOrder;
					$this->offset = $tmpOffset;
					$this->limit  = $tmpLimit;

					// Add support for second order by, offset and limit
					$query = PHP_EOL . 'SELECT * FROM (' . $query . PHP_EOL .
"ORDER BY $orderBy" . PHP_EOL . ') w';

					if ($this->order)
					{
						$query .= (string) $this->order;
					}

					return $this->processLimit($query, $this->limit,
$this->offset);
				}
		}

		return parent::__toString();
	}

	/**
	 * Method to modify a query already in string format with the needed
	 * additions to make the query limited to a particular number of
	 * results, or start at a particular offset.
	 *
	 * @param   string   $query   The query in string format
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return string
	 *
	 * @since 3.0.0
	 */
	public function processLimit($query, $limit, $offset = 0)
	{
		if ($limit > 0 && $offset > 0)
		{
			$query .= ' LIMIT ' . $offset . ', ' . $limit;
		}
		elseif ($limit > 0)
		{
			$query .= ' LIMIT ' . $limit;
		}

		return $query;
	}

	/**
	 * Concatenates an array of column names or values.
	 *
	 * @param   array   $values     An array of values to concatenate.
	 * @param   string  $separator  As separator to place between each value.
	 *
	 * @return  string  The concatenated values.
	 *
	 * @since   1.7.0
	 */
	public function concatenate($values, $separator = null)
	{
		if ($separator)
		{
			$concat_string = 'CONCAT_WS(' . $this->quote($separator);

			foreach ($values as $value)
			{
				$concat_string .= ', ' . $value;
			}

			return $concat_string . ')';
		}
		else
		{
			return 'CONCAT(' . implode(',', $values) .
')';
		}
	}

	/**
	 * Sets the offset and limit for the result set, if the database driver
supports it.
	 *
	 * Usage:
	 * $query->setLimit(100, 0); (retrieve 100 rows, starting at first
record)
	 * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th
record)
	 *
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   3.0.0
	 */
	public function setLimit($limit = 0, $offset = 0)
	{
		$this->limit  = (int) $limit;
		$this->offset = (int) $offset;

		return $this;
	}

	/**
	 * Return correct regexp operator for mysqli.
	 *
	 * Ensure that the regexp operator is mysqli compatible.
	 *
	 * Usage:
	 * $query->where('field ' . $query->regexp($search));
	 *
	 * @param   string  $value  The regex pattern.
	 *
	 * @return  string  Returns the regex operator.
	 *
	 * @since   1.7.3
	 */
	public function regexp($value)
	{
		return ' REGEXP ' . $value;
	}

	/**
	 * Return correct rand() function for Mysql.
	 *
	 * Ensure that the rand() function is Mysql compatible.
	 * 
	 * Usage:
	 * $query->Rand();
	 * 
	 * @return  string  The correct rand function.
	 *
	 * @since   3.5
	 */
	public function Rand()
	{
		return ' RAND() ';
	}

	/**
	 * Return the number of the current row.
	 *
	 * @param   string  $orderBy           An expression of ordering for
window function.
	 * @param   string  $orderColumnAlias  An alias for new ordering column.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   3.7.0
	 * @throws  RuntimeException
	 */
	public function selectRowNumber($orderBy, $orderColumnAlias)
	{
		$this->validateRowNumber($orderBy, $orderColumnAlias);
		$this->select("(SELECT @rownum := @rownum + 1 FROM (SELECT
@rownum := 0) AS r) AS $orderColumnAlias");

		return $this;
	}

	/**
	 * Casts a value to a char.
	 *
	 * Ensure that the value is properly quoted before passing to the method.
	 *
	 * Usage:
	 * $query->select($query->castAsChar('a'));
	 * $query->select($query->castAsChar('a', 40));
	 *
	 * @param   string  $value  The value to cast as a char.
	 *
	 * @param   string  $len    The length of the char.
	 *
	 * @return  string  Returns the cast value.
	 *
	 * @since   3.7.0
	 */
	public function castAsChar($value, $len = null)
	{
		if (!$len)
		{
			return $value;
		}
		else
		{
			return ' CAST(' . $value . ' AS CHAR(' . $len .
'))';
		}
	}
}
oracle.php000064400000012367151156424730006543 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Oracle Query Building Class.
 *
 * @since  3.0.0
 */
class JDatabaseQueryOracle extends JDatabaseQueryPdo implements
JDatabaseQueryPreparable, JDatabaseQueryLimitable
{
	/**
	 * @var    integer  The offset for the result set.
	 * @since  3.0.0
	 */
	protected $offset;

	/**
	 * @var    integer  The limit for the result set.
	 * @since  3.0.0
	 */
	protected $limit;

	/**
	 * @var    array  Bounded object array
	 * @since  3.0.0
	 */
	protected $bounded = array();

	/**
	 * Method to add a variable to an internal array that will be bound to a
prepared SQL statement before query execution. Also
	 * removes a variable that has been bounded from the internal bounded
array when the passed in value is null.
	 *
	 * @param   string|integer  $key            The key that will be used in
your SQL query to reference the value. Usually of
	 *                                          the form ':key', but
can also be an integer.
	 * @param   mixed           &$value         The value that will be
bound. The value is passed by reference to support output
	 *                                          parameters such as those
possible with stored procedures.
	 * @param   integer         $dataType       Constant corresponding to a
SQL datatype.
	 * @param   integer         $length         The length of the variable.
Usually required for OUTPUT parameters.
	 * @param   array           $driverOptions  Optional driver options to be
used.
	 *
	 * @return  JDatabaseQueryOracle
	 *
	 * @since   3.0.0
	 */
	public function bind($key = null, &$value = null, $dataType =
PDO::PARAM_STR, $length = 0, $driverOptions = array())
	{
		// Case 1: Empty Key (reset $bounded array)
		if (empty($key))
		{
			$this->bounded = array();

			return $this;
		}

		// Case 2: Key Provided, null value (unset key from $bounded array)
		if (is_null($value))
		{
			if (isset($this->bounded[$key]))
			{
				unset($this->bounded[$key]);
			}

			return $this;
		}

		$obj = new stdClass;

		$obj->value = &$value;
		$obj->dataType = $dataType;
		$obj->length = $length;
		$obj->driverOptions = $driverOptions;

		// Case 3: Simply add the Key/Value into the bounded array
		$this->bounded[$key] = $obj;

		return $this;
	}

	/**
	 * Retrieves the bound parameters array when key is null and returns it by
reference. If a key is provided then that item is
	 * returned.
	 *
	 * @param   mixed  $key  The bounded variable key to retrieve.
	 *
	 * @return  mixed
	 *
	 * @since   3.0.0
	 */
	public function &getBounded($key = null)
	{
		if (empty($key))
		{
			return $this->bounded;
		}
		else
		{
			if (isset($this->bounded[$key]))
			{
				return $this->bounded[$key];
			}
		}
	}

	/**
	 * Clear data from the query or a specific clause of the query.
	 *
	 * @param   string  $clause  Optionally, the name of the clause to clear,
or nothing to clear the whole query.
	 *
	 * @return  JDatabaseQueryOracle  Returns this object to allow chaining.
	 *
	 * @since   3.0.0
	 */
	public function clear($clause = null)
	{
		switch ($clause)
		{
			case null:
				$this->bounded = array();
				break;
		}

		parent::clear($clause);

		return $this;
	}

	/**
	 * Method to modify a query already in string format with the needed
	 * additions to make the query limited to a particular number of
	 * results, or start at a particular offset. This method is used
	 * automatically by the __toString() method if it detects that the
	 * query implements the JDatabaseQueryLimitable interface.
	 *
	 * @param   string   $query   The query in string format
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  string
	 *
	 * @since   3.0.0
	 */
	public function processLimit($query, $limit, $offset = 0)
	{
		// Check if we need to mangle the query.
		if ($limit || $offset)
		{
			$query = 'SELECT joomla2.*
		              FROM (
		                  SELECT joomla1.*, ROWNUM AS joomla_db_rownum
		                  FROM (
		                      ' . $query . '
		                  ) joomla1
		              ) joomla2';

			// Check if the limit value is greater than zero.
			if ($limit > 0)
			{
				$query .= ' WHERE joomla2.joomla_db_rownum BETWEEN ' .
($offset + 1) . ' AND ' . ($offset + $limit);
			}
			else
			{
				// Check if there is an offset and then use this.
				if ($offset)
				{
					$query .= ' WHERE joomla2.joomla_db_rownum > ' . ($offset
+ 1);
				}
			}
		}

		return $query;
	}

	/**
	 * Sets the offset and limit for the result set, if the database driver
supports it.
	 *
	 * Usage:
	 * $query->setLimit(100, 0); (retrieve 100 rows, starting at first
record)
	 * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th
record)
	 *
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  JDatabaseQueryOracle  Returns this object to allow chaining.
	 *
	 * @since   3.0.0
	 */
	public function setLimit($limit = 0, $offset = 0)
	{
		$this->limit = (int) $limit;
		$this->offset = (int) $offset;

		return $this;
	}
}
pdo.php000064400000001706151156424730006053 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * PDO Query Building Class.
 *
 * @since  3.0.0
 */
class JDatabaseQueryPdo extends JDatabaseQuery
{
	/**
	 * Casts a value to a char.
	 *
	 * Ensure that the value is properly quoted before passing to the method.
	 *
	 * Usage:
	 * $query->select($query->castAsChar('a'));
	 * $query->select($query->castAsChar('a', 40));
	 *
	 * @param   string  $value  The value to cast as a char.
	 *
	 * @param   string  $len    The length of the char.
	 *
	 * @return  string  Returns the cast value.
	 *
	 * @since   1.7.0
	 */
	public function castAsChar($value, $len = null)
	{
		if (!$len)
		{
			return $value;
		}
		else
		{
			return ' CAST(' . $value . ' AS CHAR(' . $len .
'))';
		}
	}
}
pdomysql.php000064400000000701151156424730007133 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Query Building Class.
 *
 * @package     Joomla.Platform
 * @subpackage  Database
 * @since       3.4
 */
class JDatabaseQueryPdomysql extends JDatabaseQueryMysqli
{
}
pgsql.php000064400000006175151156424730006424 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * PDO PostgreSQL Query Building Class.
 *
 * @since  3.9.0
 */
class JDatabaseQueryPgsql extends JDatabaseQueryPostgresql implements
JDatabaseQueryPreparable
{
	/**
	 * Holds key / value pair of bound objects.
	 *
	 * @var    mixed
	 * @since  3.9.0
	 */
	protected $bounded = array();

	/**
	 * Method to add a variable to an internal array that will be bound to a
prepared SQL statement before query execution. Also
	 * removes a variable that has been bounded from the internal bounded
array when the passed in value is null.
	 *
	 * @param   string|integer  $key            The key that will be used in
your SQL query to reference the value. Usually of
	 *                                          the form ':key', but
can also be an integer.
	 * @param   mixed           &$value         The value that will be
bound. The value is passed by reference to support output
	 *                                          parameters such as those
possible with stored procedures.
	 * @param   integer         $dataType       Constant corresponding to a
SQL datatype.
	 * @param   integer         $length         The length of the variable.
Usually required for OUTPUT parameters.
	 * @param   array           $driverOptions  Optional driver options to be
used.
	 *
	 * @return  JDatabaseQueryPgsql
	 *
	 * @since   3.9.0
	 */
	public function bind($key = null, &$value = null, $dataType =
PDO::PARAM_STR, $length = 0, $driverOptions = array())
	{
		// Case 1: Empty Key (reset $bounded array)
		if (empty($key))
		{
			$this->bounded = array();

			return $this;
		}

		// Case 2: Key Provided, null value (unset key from $bounded array)
		if (is_null($value))
		{
			if (isset($this->bounded[$key]))
			{
				unset($this->bounded[$key]);
			}

			return $this;
		}

		$obj = new stdClass;

		$obj->value = &$value;
		$obj->dataType = $dataType;
		$obj->length = $length;
		$obj->driverOptions = $driverOptions;

		// Case 3: Simply add the Key/Value into the bounded array
		$this->bounded[$key] = $obj;

		return $this;
	}

	/**
	 * Retrieves the bound parameters array when key is null and returns it by
reference. If a key is provided then that item is
	 * returned.
	 *
	 * @param   mixed  $key  The bounded variable key to retrieve.
	 *
	 * @return  mixed
	 *
	 * @since   3.9.0
	 */
	public function &getBounded($key = null)
	{
		if (empty($key))
		{
			return $this->bounded;
		}

		if (isset($this->bounded[$key]))
		{
			return $this->bounded[$key];
		}
	}

	/**
	 * Clear data from the query or a specific clause of the query.
	 *
	 * @param   string  $clause  Optionally, the name of the clause to clear,
or nothing to clear the whole query.
	 *
	 * @return  JDatabaseQueryPgsql  Returns this object to allow chaining.
	 *
	 * @since   3.9.0
	 */
	public function clear($clause = null)
	{
		switch ($clause)
		{
			case null:
				$this->bounded = array();
				break;
		}

		return parent::clear($clause);
	}
}
postgresql.php000064400000041030151156424730007466 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Query Building Class.
 *
 * @since       1.7.3
 * @deprecated  4.0  Use PDO PostgreSQL instead
 */
class JDatabaseQueryPostgresql extends JDatabaseQuery implements
JDatabaseQueryLimitable
{
	/**
	 * @var    object  The FOR UPDATE element used in "FOR UPDATE" 
lock
	 * @since  1.7.3
	 */
	protected $forUpdate = null;

	/**
	 * @var    object  The FOR SHARE element used in "FOR SHARE" 
lock
	 * @since  1.7.3
	 */
	protected $forShare = null;

	/**
	 * @var    object  The NOWAIT element used in "FOR SHARE" and
"FOR UPDATE" lock
	 * @since  1.7.3
	 */
	protected $noWait = null;

	/**
	 * @var    object  The LIMIT element
	 * @since  1.7.3
	 */
	protected $limit = null;

	/**
	 * @var    object  The OFFSET element
	 * @since  1.7.3
	 */
	protected $offset = null;

	/**
	 * @var    object  The RETURNING element of INSERT INTO
	 * @since  1.7.3
	 */
	protected $returning = null;

	/**
	 * Magic function to convert the query to a string, only for postgresql
specific query
	 *
	 * @return  string	The completed query.
	 *
	 * @since   1.7.3
	 */
	public function __toString()
	{
		$query = '';

		switch ($this->type)
		{
			case 'select':
				if ($this->selectRowNumber &&
$this->selectRowNumber['native'] === false)
				{
					// Workaround for postgresql version less than 8.4.0
					try
					{
						$this->db->setQuery('CREATE TEMP SEQUENCE
ROW_NUMBER');
						$this->db->execute();
					}
					catch (JDatabaseExceptionExecuting $e)
					{
						// Do nothing, sequence exists
					}

					$orderBy          = $this->selectRowNumber['orderBy'];
					$orderColumnAlias =
$this->selectRowNumber['orderColumnAlias'];

					$columns = "nextval('ROW_NUMBER') - 1 AS
$orderColumnAlias";

					if ($this->select === null)
					{
						$query = PHP_EOL . "SELECT 1"
							. (string) $this->from
							. (string) $this->where;
					}
					else
					{
						$tmpOffset    = $this->offset;
						$tmpLimit     = $this->limit;
						$this->offset = 0;
						$this->limit  = 0;
						$tmpOrder     = $this->order;
						$this->order  = null;
						$query        = parent::__toString();
						$columns      = "w.*, $columns";
						$this->order  = $tmpOrder;
						$this->offset = $tmpOffset;
						$this->limit  = $tmpLimit;
					}

					// Add support for second order by, offset and limit
					$query = PHP_EOL . "SELECT $columns FROM (" . $query .
PHP_EOL . "ORDER BY $orderBy"
						. PHP_EOL . ") w,(SELECT setval('ROW_NUMBER', 1)) AS
r";

					if ($this->order)
					{
						$query .= (string) $this->order;
					}

					break;
				}

				$query .= (string) $this->select;
				$query .= (string) $this->from;

				if ($this->join)
				{
					// Special case for joins
					foreach ($this->join as $join)
					{
						$query .= (string) $join;
					}
				}

				if ($this->where)
				{
					$query .= (string) $this->where;
				}

				if ($this->selectRowNumber)
				{
					if ($this->order)
					{
						$query .= (string) $this->order;
					}

					break;
				}

				if ($this->group)
				{
					$query .= (string) $this->group;
				}

				if ($this->having)
				{
					$query .= (string) $this->having;
				}

				if ($this->order)
				{
					$query .= (string) $this->order;
				}

				if ($this->forUpdate)
				{
					$query .= (string) $this->forUpdate;
				}
				else
				{
					if ($this->forShare)
					{
						$query .= (string) $this->forShare;
					}
				}

				if ($this->noWait)
				{
					$query .= (string) $this->noWait;
				}

				break;

			case 'update':
				$query .= (string) $this->update;
				$query .= (string) $this->set;

				if ($this->join)
				{
					$tmpFrom     = $this->from;
					$tmpWhere    = $this->where ? clone $this->where : null;
					$this->from  = null;

					// Workaround for special case of JOIN with UPDATE
					foreach ($this->join as $join)
					{
						$joinElem = $join->getElements();

						$joinArray = preg_split('/\sON\s/i', $joinElem[0]);

						if (count($joinArray) > 2)
						{
							$condition = array_pop($joinArray);
							$joinArray = array(implode(' ON ', $joinArray),
$condition);
						}

						$this->from($joinArray[0]);

						if (isset($joinArray[1]))
						{
							$this->where($joinArray[1]);
						}
					}

					$query .= (string) $this->from;

					if ($this->where)
					{
						$query .= (string) $this->where;
					}

					$this->from  = $tmpFrom;
					$this->where = $tmpWhere;
				}
				elseif ($this->where)
				{
					$query .= (string) $this->where;
				}

				break;

			case 'insert':
				$query .= (string) $this->insert;

				if ($this->values)
				{
					if ($this->columns)
					{
						$query .= (string) $this->columns;
					}

					$elements = $this->values->getElements();

					if (!($elements[0] instanceof $this))
					{
						$query .= ' VALUES ';
					}

					$query .= (string) $this->values;

					if ($this->returning)
					{
						$query .= (string) $this->returning;
					}
				}

				break;

			default:
				$query = parent::__toString();
				break;
		}

		if ($this instanceof JDatabaseQueryLimitable)
		{
			$query = $this->processLimit($query, $this->limit,
$this->offset);
		}

		return $query;
	}

	/**
	 * Clear data from the query or a specific clause of the query.
	 *
	 * @param   string  $clause  Optionally, the name of the clause to clear,
or nothing to clear the whole query.
	 *
	 * @return  JDatabaseQueryPostgresql  Returns this object to allow
chaining.
	 *
	 * @since   1.7.3
	 */
	public function clear($clause = null)
	{
		switch ($clause)
		{
			case 'limit':
				$this->limit = null;
				break;

			case 'offset':
				$this->offset = null;
				break;

			case 'forUpdate':
				$this->forUpdate = null;
				break;

			case 'forShare':
				$this->forShare = null;
				break;

			case 'noWait':
				$this->noWait = null;
				break;

			case 'returning':
				$this->returning = null;
				break;

			case 'select':
			case 'update':
			case 'delete':
			case 'insert':
			case 'from':
			case 'join':
			case 'set':
			case 'where':
			case 'group':
			case 'having':
			case 'order':
			case 'columns':
			case 'values':
				parent::clear($clause);
				break;

			default:
				$this->type = null;
				$this->limit = null;
				$this->offset = null;
				$this->forUpdate = null;
				$this->forShare = null;
				$this->noWait = null;
				$this->returning = null;
				parent::clear($clause);
				break;
		}

		return $this;
	}

	/**
	 * Casts a value to a char.
	 *
	 * Ensure that the value is properly quoted before passing to the method.
	 *
	 * Usage:
	 * $query->select($query->castAsChar('a'));
	 * $query->select($query->castAsChar('a', 40));
	 *
	 * @param   string  $value  The value to cast as a char.
	 *
	 * @param   string  $len    The length of the char.
	 *
	 * @return  string  Returns the cast value.
	 *
	 * @since   1.7.3
	 */
	public function castAsChar($value, $len = null)
	{
		if (!$len)
		{
			return $value . '::text';
		}
		else
		{
			return ' CAST(' . $value . ' AS CHAR(' . $len .
'))';
		}
	}

	/**
	 * Concatenates an array of column names or values.
	 *
	 * Usage:
	 * $query->select($query->concatenate(array('a',
'b')));
	 *
	 * @param   array   $values     An array of values to concatenate.
	 * @param   string  $separator  As separator to place between each value.
	 *
	 * @return  string  The concatenated values.
	 *
	 * @since   1.7.3
	 */
	public function concatenate($values, $separator = null)
	{
		if ($separator)
		{
			return implode(' || ' . $this->quote($separator) . '
|| ', $values);
		}
		else
		{
			return implode(' || ', $values);
		}
	}

	/**
	 * Gets the current date and time.
	 *
	 * @return  string  Return string used in query to obtain
	 *
	 * @since   1.7.3
	 */
	public function currentTimestamp()
	{
		return 'NOW()';
	}

	/**
	 * Sets the FOR UPDATE lock on select's output row
	 *
	 * @param   string  $tableName  The table to lock
	 * @param   string  $glue       The glue by which to join the conditions.
Defaults to ',' .
	 *
	 * @return  JDatabaseQueryPostgresql  FOR UPDATE query element
	 *
	 * @since   1.7.3
	 */
	public function forUpdate($tableName, $glue = ',')
	{
		$this->type = 'forUpdate';

		if (is_null($this->forUpdate))
		{
			$glue            = strtoupper($glue);
			$this->forUpdate = new JDatabaseQueryElement('FOR UPDATE',
'OF ' . $tableName, "$glue ");
		}
		else
		{
			$this->forUpdate->append($tableName);
		}

		return $this;
	}

	/**
	 * Sets the FOR SHARE lock on select's output row
	 *
	 * @param   string  $tableName  The table to lock
	 * @param   string  $glue       The glue by which to join the conditions.
Defaults to ',' .
	 *
	 * @return  JDatabaseQueryPostgresql  FOR SHARE query element
	 *
	 * @since   1.7.3
	 */
	public function forShare($tableName, $glue = ',')
	{
		$this->type = 'forShare';

		if (is_null($this->forShare))
		{
			$glue           = strtoupper($glue);
			$this->forShare = new JDatabaseQueryElement('FOR SHARE',
'OF ' . $tableName, "$glue ");
		}
		else
		{
			$this->forShare->append($tableName);
		}

		return $this;
	}

	/**
	 * Used to get a string to extract year from date column.
	 *
	 * Usage:
	 *
$query->select($query->year($query->quoteName('dateColumn')));
	 *
	 * @param   string  $date  Date column containing year to be extracted.
	 *
	 * @return  string  Returns string to extract year from a date.
	 *
	 * @since   3.0.0
	 */
	public function year($date)
	{
		return 'EXTRACT (YEAR FROM ' . $date . ')';
	}

	/**
	 * Used to get a string to extract month from date column.
	 *
	 * Usage:
	 *
$query->select($query->month($query->quoteName('dateColumn')));
	 *
	 * @param   string  $date  Date column containing month to be extracted.
	 *
	 * @return  string  Returns string to extract month from a date.
	 *
	 * @since   3.0.0
	 */
	public function month($date)
	{
		return 'EXTRACT (MONTH FROM ' . $date . ')';
	}

	/**
	 * Used to get a string to extract day from date column.
	 *
	 * Usage:
	 *
$query->select($query->day($query->quoteName('dateColumn')));
	 *
	 * @param   string  $date  Date column containing day to be extracted.
	 *
	 * @return  string  Returns string to extract day from a date.
	 *
	 * @since   3.0.0
	 */
	public function day($date)
	{
		return 'EXTRACT (DAY FROM ' . $date . ')';
	}

	/**
	 * Used to get a string to extract hour from date column.
	 *
	 * Usage:
	 *
$query->select($query->hour($query->quoteName('dateColumn')));
	 *
	 * @param   string  $date  Date column containing hour to be extracted.
	 *
	 * @return  string  Returns string to extract hour from a date.
	 *
	 * @since   3.0.0
	 */
	public function hour($date)
	{
		return 'EXTRACT (HOUR FROM ' . $date . ')';
	}

	/**
	 * Used to get a string to extract minute from date column.
	 *
	 * Usage:
	 *
$query->select($query->minute($query->quoteName('dateColumn')));
	 *
	 * @param   string  $date  Date column containing minute to be extracted.
	 *
	 * @return  string  Returns string to extract minute from a date.
	 *
	 * @since   3.0.0
	 */
	public function minute($date)
	{
		return 'EXTRACT (MINUTE FROM ' . $date . ')';
	}

	/**
	 * Used to get a string to extract seconds from date column.
	 *
	 * Usage:
	 *
$query->select($query->second($query->quoteName('dateColumn')));
	 *
	 * @param   string  $date  Date column containing second to be extracted.
	 *
	 * @return  string  Returns string to extract second from a date.
	 *
	 * @since   3.0.0
	 */
	public function second($date)
	{
		return 'EXTRACT (SECOND FROM ' . $date . ')';
	}

	/**
	 * Sets the NOWAIT lock on select's output row
	 *
	 * @return  JDatabaseQueryPostgresql  NO WAIT query element
	 *
	 * @since   1.7.3
	 */
	public function noWait ()
	{
		$this->type = 'noWait';

		if (is_null($this->noWait))
		{
			$this->noWait = new JDatabaseQueryElement('NOWAIT', null);
		}

		return $this;
	}

	/**
	 * Set the LIMIT clause to the query
	 *
	 * @param   integer  $limit  An int of how many row will be returned
	 *
	 * @return  JDatabaseQueryPostgresql  Returns this object to allow
chaining.
	 *
	 * @since   1.7.3
	 */
	public function limit($limit = 0)
	{
		if (is_null($this->limit))
		{
			$this->limit = new JDatabaseQueryElement('LIMIT', (int)
$limit);
		}

		return $this;
	}

	/**
	 * Set the OFFSET clause to the query
	 *
	 * @param   integer  $offset  An int for skipping row
	 *
	 * @return  JDatabaseQueryPostgresql  Returns this object to allow
chaining.
	 *
	 * @since   1.7.3
	 */
	public function offset($offset = 0)
	{
		if (is_null($this->offset))
		{
			$this->offset = new JDatabaseQueryElement('OFFSET', (int)
$offset);
		}

		return $this;
	}

	/**
	 * Add the RETURNING element to INSERT INTO statement.
	 *
	 * @param   mixed  $pkCol  The name of the primary key column.
	 *
	 * @return  JDatabaseQueryPostgresql  Returns this object to allow
chaining.
	 *
	 * @since   1.7.3
	 */
	public function returning($pkCol)
	{
		if (is_null($this->returning))
		{
			$this->returning = new JDatabaseQueryElement('RETURNING',
$pkCol);
		}

		return $this;
	}

	/**
	 * Sets the offset and limit for the result set, if the database driver
supports it.
	 *
	 * Usage:
	 * $query->setLimit(100, 0); (retrieve 100 rows, starting at first
record)
	 * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th
record)
	 *
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  JDatabaseQueryPostgresql  Returns this object to allow
chaining.
	 *
	 * @since   3.0.0
	 */
	public function setLimit($limit = 0, $offset = 0)
	{
		$this->limit  = (int) $limit;
		$this->offset = (int) $offset;

		return $this;
	}

	/**
	 * Method to modify a query already in string format with the needed
	 * additions to make the query limited to a particular number of
	 * results, or start at a particular offset.
	 *
	 * @param   string   $query   The query in string format
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  string
	 *
	 * @since   3.0.0
	 */
	public function processLimit($query, $limit, $offset = 0)
	{
		if ($limit > 0)
		{
			$query .= ' LIMIT ' . $limit;
		}

		if ($offset > 0)
		{
			$query .= ' OFFSET ' . $offset;
		}

		return $query;
	}

	/**
	 * Add to the current date and time in Postgresql.
	 * Usage:
	 * $query->select($query->dateAdd());
	 * Prefixing the interval with a - (negative sign) will cause subtraction
to be used.
	 *
	 * @param   string  $date      The db quoted string representation of the
date to add to
	 * @param   string  $interval  The string representation of the
appropriate number of units
	 * @param   string  $datePart  The part of the date to perform the
addition on
	 *
	 * @return  string  The string with the appropriate sql for addition of
dates
	 *
	 * @since   3.2.0
	 * @note    Not all drivers support all units. Check appropriate
references
	 * @link   
http://www.postgresql.org/docs/9.0/static/functions-datetime.html.
	 */
	public function dateAdd($date, $interval, $datePart)
	{
		if (substr($interval, 0, 1) != '-')
		{
			return "timestamp " . $date . " + interval '" .
$interval . " " . $datePart . "'";
		}
		else
		{
			return "timestamp " . $date . " - interval '" .
ltrim($interval, '-') . " " . $datePart .
"'";
		}
	}

	/**
	 * Return correct regexp operator for Postgresql.
	 *
	 * Ensure that the regexp operator is Postgresql compatible.
	 *
	 * Usage:
	 * $query->where('field ' . $query->regexp($search));
	 *
	 * @param   string  $value  The regex pattern.
	 *
	 * @return  string  Returns the regex operator.
	 *
	 * @since   1.7.3
	 */
	public function regexp($value)
	{
		return ' ~* ' . $value;
	}

	/**
	 * Return correct rand() function for Postgresql.
	 *
	 * Ensure that the rand() function is Postgresql compatible.
	 *
	 * Usage:
	 * $query->Rand();
	 *
	 * @return  string  The correct rand function.
	 *
	 * @since   3.5
	 */
	public function Rand()
	{
		return ' RANDOM() ';
	}

	/**
	 * Return the number of the current row.
	 *
	 * @param   string  $orderBy           An expression of ordering for
window function.
	 * @param   string  $orderColumnAlias  An alias for new ordering column.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   3.7.0
	 * @throws  RuntimeException
	 */
	public function selectRowNumber($orderBy, $orderColumnAlias)
	{
		$this->validateRowNumber($orderBy, $orderColumnAlias);

		if (version_compare($this->db->getVersion(), '8.4.0')
>= 0)
		{
			$this->selectRowNumber['native'] = true;
			$this->select("ROW_NUMBER() OVER (ORDER BY $orderBy) AS
$orderColumnAlias");
		}
		else
		{
			$this->selectRowNumber['native'] = false;
		}

		return $this;
	}
}
preparable.php000064400000003705151156424730007407 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Joomla Database Query Preparable Interface.
 * Adds bind/unbind methods as well as a getBounded() method
 * to retrieve the stored bounded variables on demand prior to
 * query execution.
 *
 * @since  3.0.0
 */
interface JDatabaseQueryPreparable
{
	/**
	 * Method to add a variable to an internal array that will be bound to a
prepared SQL statement before query execution. Also
	 * removes a variable that has been bounded from the internal bounded
array when the passed in value is null.
	 *
	 * @param   string|integer  $key            The key that will be used in
your SQL query to reference the value. Usually of
	 *                                          the form ':key', but
can also be an integer.
	 * @param   mixed           &$value         The value that will be
bound. The value is passed by reference to support output
	 *                                          parameters such as those
possible with stored procedures.
	 * @param   integer         $dataType       Constant corresponding to a
SQL datatype.
	 * @param   integer         $length         The length of the variable.
Usually required for OUTPUT parameters.
	 * @param   array           $driverOptions  Optional driver options to be
used.
	 *
	 * @return  JDatabaseQuery
	 *
	 * @since   3.0.0
	 */
	public function bind($key = null, &$value = null, $dataType =
PDO::PARAM_STR, $length = 0, $driverOptions = array());

	/**
	 * Retrieves the bound parameters array when key is null and returns it by
reference. If a key is provided then that item is
	 * returned.
	 *
	 * @param   mixed  $key  The bounded variable key to retrieve.
	 *
	 * @return  mixed
	 *
	 * @since   3.0.0
	 */
	public function &getBounded($key = null);
}
sqlazure.php000064400000001470151156424730007135 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Query Building Class.
 *
 * @since  1.7.0
 */
class JDatabaseQuerySqlazure extends JDatabaseQuerySqlsrv
{
	/**
	 * 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.
	 *
	 * @var    string
	 *
	 * @since  1.7.0
	 */
	protected $name_quotes = '';
}
sqlite.php000064400000024343151156424730006574 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * SQLite Query Building Class.
 *
 * @since  3.0.0
 */
class JDatabaseQuerySqlite extends JDatabaseQueryPdo implements
JDatabaseQueryPreparable, JDatabaseQueryLimitable
{
	/**
	 * @var    integer  The offset for the result set.
	 * @since  3.0.0
	 */
	protected $offset;

	/**
	 * @var    integer  The limit for the result set.
	 * @since  3.0.0
	 */
	protected $limit;

	/**
	 * @var    array  Bounded object array
	 * @since  3.0.0
	 */
	protected $bounded = array();

	/**
	 * Method to add a variable to an internal array that will be bound to a
prepared SQL statement before query execution. Also
	 * removes a variable that has been bounded from the internal bounded
array when the passed in value is null.
	 *
	 * @param   string|integer  $key            The key that will be used in
your SQL query to reference the value. Usually of
	 *                                          the form ':key', but
can also be an integer.
	 * @param   mixed           &$value         The value that will be
bound. The value is passed by reference to support output
	 *                                          parameters such as those
possible with stored procedures.
	 * @param   integer         $dataType       Constant corresponding to a
SQL datatype.
	 * @param   integer         $length         The length of the variable.
Usually required for OUTPUT parameters.
	 * @param   array           $driverOptions  Optional driver options to be
used.
	 *
	 * @return  JDatabaseQuerySqlite
	 *
	 * @since   3.0.0
	 */
	public function bind($key = null, &$value = null, $dataType =
PDO::PARAM_STR, $length = 0, $driverOptions = array())
	{
		// Case 1: Empty Key (reset $bounded array)
		if (empty($key))
		{
			$this->bounded = array();

			return $this;
		}

		// Case 2: Key Provided, null value (unset key from $bounded array)
		if (is_null($value))
		{
			if (isset($this->bounded[$key]))
			{
				unset($this->bounded[$key]);
			}

			return $this;
		}

		$obj = new stdClass;

		$obj->value = &$value;
		$obj->dataType = $dataType;
		$obj->length = $length;
		$obj->driverOptions = $driverOptions;

		// Case 3: Simply add the Key/Value into the bounded array
		$this->bounded[$key] = $obj;

		return $this;
	}

	/**
	 * Retrieves the bound parameters array when key is null and returns it by
reference. If a key is provided then that item is
	 * returned.
	 *
	 * @param   mixed  $key  The bounded variable key to retrieve.
	 *
	 * @return  mixed
	 *
	 * @since   3.0.0
	 */
	public function &getBounded($key = null)
	{
		if (empty($key))
		{
			return $this->bounded;
		}
		else
		{
			if (isset($this->bounded[$key]))
			{
				return $this->bounded[$key];
			}
		}
	}

	/**
	 * Gets the number of characters in a string.
	 *
	 * Note, use 'length' to find the number of bytes in a string.
	 *
	 * Usage:
	 * $query->select($query->charLength('a'));
	 *
	 * @param   string  $field      A value.
	 * @param   string  $operator   Comparison operator between charLength
integer value and $condition
	 * @param   string  $condition  Integer value to compare charLength with.
	 *
	 * @return  string  The required char length call.
	 *
	 * @since   3.2.0
	 */
	public function charLength($field, $operator = null, $condition = null)
	{
		return 'length(' . $field . ')' . (isset($operator)
&& isset($condition) ? ' ' . $operator . ' ' .
$condition : '');
	}

	/**
	 * Clear data from the query or a specific clause of the query.
	 *
	 * @param   string  $clause  Optionally, the name of the clause to clear,
or nothing to clear the whole query.
	 *
	 * @return  JDatabaseQuerySqlite  Returns this object to allow chaining.
	 *
	 * @since   3.0.0
	 */
	public function clear($clause = null)
	{
		switch ($clause)
		{
			case null:
				$this->bounded = array();
				break;
		}

		parent::clear($clause);

		return $this;
	}

	/**
	 * Concatenates an array of column names or values.
	 *
	 * Usage:
	 * $query->select($query->concatenate(array('a',
'b')));
	 *
	 * @param   array   $values     An array of values to concatenate.
	 * @param   string  $separator  As separator to place between each value.
	 *
	 * @return  string  The concatenated values.
	 *
	 * @since   1.7.0
	 */
	public function concatenate($values, $separator = null)
	{
		if ($separator)
		{
			return implode(' || ' . $this->quote($separator) . '
|| ', $values);
		}
		else
		{
			return implode(' || ', $values);
		}
	}

	/**
	 * Method to modify a query already in string format with the needed
	 * additions to make the query limited to a particular number of
	 * results, or start at a particular offset. This method is used
	 * automatically by the __toString() method if it detects that the
	 * query implements the JDatabaseQueryLimitable interface.
	 *
	 * @param   string   $query   The query in string format
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  string
	 *
	 * @since   3.0.0
	 */
	public function processLimit($query, $limit, $offset = 0)
	{
		if ($limit > 0 || $offset > 0)
		{
			$query .= ' LIMIT ' . $offset . ', ' . $limit;
		}

		return $query;
	}

	/**
	 * Sets the offset and limit for the result set, if the database driver
supports it.
	 *
	 * Usage:
	 * $query->setLimit(100, 0); (retrieve 100 rows, starting at first
record)
	 * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th
record)
	 *
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  JDatabaseQuerySqlite  Returns this object to allow chaining.
	 *
	 * @since   3.0.0
	 */
	public function setLimit($limit = 0, $offset = 0)
	{
		$this->limit = (int) $limit;
		$this->offset = (int) $offset;

		return $this;
	}

	/**
	 * Add to the current date and time.
	 * Usage:
	 * $query->select($query->dateAdd());
	 * Prefixing the interval with a - (negative sign) will cause subtraction
to be used.
	 *
	 * @param   datetime  $date      The date or datetime to add to
	 * @param   string    $interval  The string representation of the
appropriate number of units
	 * @param   string    $datePart  The part of the date to perform the
addition on
	 *
	 * @return  string  The string with the appropriate sql for addition of
dates
	 *
	 * @since   3.2.0
	 * @link    http://www.sqlite.org/lang_datefunc.html
	 */
	public function dateAdd($date, $interval, $datePart)
	{
		// SQLite does not support microseconds as a separate unit. Convert the
interval to seconds
		if (strcasecmp($datePart, 'microseconds') == 0)
		{
			// Force the dot as a decimal point
			$interval = str_replace(',', '.', .001 * $interval);

			$datePart = 'seconds';
		}

		if (substr($interval, 0, 1) != '-')
		{
			return "datetime('" . $date . "', '+"
. $interval . " " . $datePart . "')";
		}
		else
		{
			return "datetime('" . $date . "', '"
. $interval . " " . $datePart . "')";
		}
	}

	/**
	 * Gets the current date and time.
	 *
	 * Usage:
	 * $query->where('published_up <
'.$query->currentTimestamp());
	 *
	 * @return  string
	 *
	 * @since   3.4
	 */
	public function currentTimestamp()
	{
		return 'CURRENT_TIMESTAMP';
	}

	/**
	 * Magic function to convert the query to a string.
	 *
	 * @return  string  The completed query.
	 *
	 * @since   1.7.0
	 */
	public function __toString()
	{
		switch ($this->type)
		{
			case 'select':
				if ($this->selectRowNumber)
				{
					$orderBy          = $this->selectRowNumber['orderBy'];
					$orderColumnAlias =
$this->selectRowNumber['orderColumnAlias'];

					$column = "ROW_NUMBER() AS $orderColumnAlias";

					if ($this->select === null)
					{
						$query = PHP_EOL . "SELECT 1"
							. (string) $this->from
							. (string) $this->where;
					}
					else
					{
						$tmpOffset    = $this->offset;
						$tmpLimit     = $this->limit;
						$this->offset = 0;
						$this->limit  = 0;
						$tmpOrder    = $this->order;
						$this->order = null;
						$query       = parent::__toString();
						$column      = "w.*, $column";
						$this->order = $tmpOrder;
						$this->offset = $tmpOffset;
						$this->limit  = $tmpLimit;
					}

					// Special sqlite query to count ROW_NUMBER
					$query = PHP_EOL . "SELECT $column"
						. PHP_EOL . "FROM ($query" . PHP_EOL . "ORDER BY
$orderBy"
						. PHP_EOL . ") AS w,(SELECT ROW_NUMBER(0)) AS r"
						// Forbid to flatten subqueries.
						. ((string) $this->order ?: PHP_EOL . 'ORDER BY NULL');

					return $this->processLimit($query, $this->limit,
$this->offset);
				}

				break;

			case 'update':
				if ($this->join)
				{
					$table = $this->update->getElements();
					$table = $table[0];

					$tableName = explode(' ', $table);
					$tableName = $tableName[0];

					if ($this->columns === null)
					{
						$fields = $this->db->getTableColumns($tableName);

						foreach ($fields as $key => $value)
						{
							$fields[$key] = $key;
						}

						$this->columns = new JDatabaseQueryElement('()',
$fields);
					}

					$fields   = $this->columns->getElements();
					$elements = $this->set->getElements();

					foreach ($elements as $nameValue)
					{
						$setArray = explode(' = ', $nameValue, 2);

						if ($setArray[0][0] === '`')
						{
							// Unquote column name
							$setArray[0] = substr($setArray[0], 1, -1);
						}

						$fields[$setArray[0]] = $setArray[1];
					}

					$select = new JDatabaseQuerySqlite($this->db);
					$select->select(array_values($fields))
						->from($table);

					$select->join  = $this->join;
					$select->where = $this->where;

					return 'INSERT OR REPLACE INTO ' . $tableName
						. ' (' . implode(',', array_keys($fields)) .
')'
						. (string) $select;
				}
		}

		return parent::__toString();
	}

	/**
	 * Return the number of the current row.
	 *
	 * @param   string  $orderBy           An expression of ordering for
window function.
	 * @param   string  $orderColumnAlias  An alias for new ordering column.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   3.7.0
	 * @throws  RuntimeException
	 */
	public function selectRowNumber($orderBy, $orderColumnAlias)
	{
		$this->validateRowNumber($orderBy, $orderColumnAlias);

		return $this;
	}
}
sqlsrv.php000064400000056775151156424730006643 0ustar00<?php
/**
 * @package     Joomla.Platform
 * @subpackage  Database
 *
 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All
rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */

defined('JPATH_PLATFORM') or die;

/**
 * Query Building Class.
 *
 * @since  1.7.0
 */
class JDatabaseQuerySqlsrv extends JDatabaseQuery implements
JDatabaseQueryLimitable
{
	/**
	 * 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.
	 *
	 * @var    string
	 * @since  1.7.0
	 */
	protected $name_quotes = '`';

	/**
	 * 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.
	 *
	 * @var    string
	 * @since  1.7.0
	 */
	protected $null_date = '1900-01-01 00:00:00';

	/**
	 * @var    integer  The affected row limit for the current SQL statement.
	 * @since  3.2
	 */
	protected $limit = 0;

	/**
	 * @var    integer  The affected row offset to apply for the current SQL
statement.
	 * @since  3.2
	 */
	protected $offset = 0;

	/**
	 * Magic function to convert the query to a string.
	 *
	 * @return  string	The completed query.
	 *
	 * @since   1.7.0
	 */
	public function __toString()
	{
		$query = '';

		switch ($this->type)
		{
			case 'select':
				// Add required aliases for offset or fixGroupColumns method
				$columns = $this->fixSelectAliases();

				$query = (string) $this->select;

				if ($this->group)
				{
					$this->fixGroupColumns($columns);
				}

				$query .= (string) $this->from;

				if ($this->join)
				{
					// Special case for joins
					foreach ($this->join as $join)
					{
						$query .= (string) $join;
					}
				}

				if ($this->where)
				{
					$query .= (string) $this->where;
				}

				if ($this->selectRowNumber === null)
				{
					if ($this->group)
					{
						$query .= (string) $this->group;
					}

					if ($this->having)
					{
						$query .= (string) $this->having;
					}
				}

				if ($this->order)
				{
					$query .= (string) $this->order;
				}

				if ($this instanceof JDatabaseQueryLimitable &&
($this->limit > 0 || $this->offset > 0))
				{
					$query = $this->processLimit($query, $this->limit,
$this->offset);
				}

				break;

			case 'insert':
				$query .= (string) $this->insert;

				// Set method
				if ($this->set)
				{
					$query .= (string) $this->set;
				}
				// Columns-Values method
				elseif ($this->values)
				{
					if ($this->columns)
					{
						$query .= (string) $this->columns;
					}

					$elements = $this->insert->getElements();
					$tableName = array_shift($elements);

					$query .= 'VALUES ';
					$query .= (string) $this->values;

					if ($this->autoIncrementField)
					{
						$query = 'SET IDENTITY_INSERT ' . $tableName . '
ON;' . $query . 'SET IDENTITY_INSERT ' . $tableName . '
OFF;';
					}

					if ($this->where)
					{
						$query .= (string) $this->where;
					}
				}

				break;

			case 'delete':
				$query .= (string) $this->delete;
				$query .= (string) $this->from;

				if ($this->join)
				{
					// Special case for joins
					foreach ($this->join as $join)
					{
						$query .= (string) $join;
					}
				}

				if ($this->where)
				{
					$query .= (string) $this->where;
				}

				if ($this->order)
				{
					$query .= (string) $this->order;
				}

				break;

			case 'update':
				if ($this->join)
				{
					$tmpUpdate    = $this->update;
					$tmpFrom      = $this->from;
					$this->update = null;
					$this->from   = null;

					$updateElem  = $tmpUpdate->getElements();
					$updateArray = explode(' ', $updateElem[0]);

					// Use table alias if exists
					$this->update(end($updateArray));
					$this->from($updateElem[0]);

					$query .= (string) $this->update;
					$query .= (string) $this->set;
					$query .= (string) $this->from;

					$this->update = $tmpUpdate;
					$this->from   = $tmpFrom;

					// Special case for joins
					foreach ($this->join as $join)
					{
						$query .= (string) $join;
					}
				}
				else
				{
					$query .= (string) $this->update;
					$query .= (string) $this->set;
				}

				if ($this->where)
				{
					$query .= (string) $this->where;
				}

				if ($this->order)
				{
					$query .= (string) $this->order;
				}

				break;

			default:
				$query = parent::__toString();

				break;
		}

		return $query;
	}

	/**
	 * Casts a value to a char.
	 *
	 * Ensure that the value is properly quoted before passing to the method.
	 *
	 * @param   string  $value  The value to cast as a char.
	 *
	 * @param   string  $len    The length of the char.
	 *
	 * @return  string  Returns the cast value.
	 *
	 * @since   1.7.0
	 */
	public function castAsChar($value, $len = null)
	{
		if (!$len)
		{
			return 'CAST(' . $value . ' as NVARCHAR(30))';
		}
		else
		{
			return 'CAST(' . $value . ' as NVARCHAR(' . $len .
'))';
		}
	}

	/**
	 * Gets the function to determine the length of a character string.
	 *
	 * @param   string  $field      A value.
	 * @param   string  $operator   Comparison operator between charLength
integer value and $condition
	 * @param   string  $condition  Integer value to compare charLength with.
	 *
	 * @return  string  The required char length call.
	 *
	 * @since   1.7.0
	 */
	public function charLength($field, $operator = null, $condition = null)
	{
		return 'DATALENGTH(' . $field . ')' .
(isset($operator) && isset($condition) ? ' ' . $operator
. ' ' . $condition : '');
	}

	/**
	 * Concatenates an array of column names or values.
	 *
	 * @param   array   $values     An array of values to concatenate.
	 * @param   string  $separator  As separator to place between each value.
	 *
	 * @return  string  The concatenated values.
	 *
	 * @since   1.7.0
	 */
	public function concatenate($values, $separator = null)
	{
		if ($separator)
		{
			return '(' . implode('+' .
$this->quote($separator) . '+', $values) . ')';
		}
		else
		{
			return '(' . implode('+', $values) . ')';
		}
	}

	/**
	 * Gets the current date and time.
	 *
	 * @return  string
	 *
	 * @since   1.7.0
	 */
	public function currentTimestamp()
	{
		return 'GETDATE()';
	}

	/**
	 * Get the length of a string in bytes.
	 *
	 * @param   string  $value  The string to measure.
	 *
	 * @return  integer
	 *
	 * @since   1.7.0
	 */
	public function length($value)
	{
		return 'LEN(' . $value . ')';
	}

	/**
	 * Add to the current date and time.
	 * Usage:
	 * $query->select($query->dateAdd());
	 * Prefixing the interval with a - (negative sign) will cause subtraction
to be used.
	 *
	 * @param   datetime  $date      The date to add to; type may be time or
datetime.
	 * @param   string    $interval  The string representation of the
appropriate number of units
	 * @param   string    $datePart  The part of the date to perform the
addition on
	 *
	 * @return  string  The string with the appropriate sql for addition of
dates
	 *
	 * @since   3.2.0
	 * @note    Not all drivers support all units.
	 * @link    http://msdn.microsoft.com/en-us/library/ms186819.aspx for more
information
	 */
	public function dateAdd($date, $interval, $datePart)
	{
		return 'DATEADD(' . $datePart . ', ' . $interval .
', ' . $date . ')';
	}

	/**
	 * Method to modify a query already in string format with the needed
	 * additions to make the query limited to a particular number of
	 * results, or start at a particular offset.
	 *
	 * @param   string   $query   The query in string format
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  string
	 *
	 * @since   3.0.0
	 */
	public function processLimit($query, $limit, $offset = 0)
	{
		if ($limit)
		{
			$total = $offset + $limit;

			$position = stripos($query, 'SELECT');
			$distinct = stripos($query, 'SELECT DISTINCT');

			if ($position === $distinct)
			{
				$query = substr_replace($query, 'SELECT DISTINCT TOP ' .
(int) $total, $position, 15);
			}
			else
			{
				$query = substr_replace($query, 'SELECT TOP ' . (int) $total,
$position, 6);
			}
		}

		if (!$offset)
		{
			return $query;
		}

		return PHP_EOL
			. 'SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0))
AS RowNumber FROM ('
			. $query
			. PHP_EOL . ') AS A) AS A WHERE RowNumber > ' . (int)
$offset;
	}

	/**
	 * Sets the offset and limit for the result set, if the database driver
supports it.
	 *
	 * Usage:
	 * $query->setLimit(100, 0); (retrieve 100 rows, starting at first
record)
	 * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th
record)
	 *
	 * @param   integer  $limit   The limit for the result set
	 * @param   integer  $offset  The offset for the result set
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   3.0.0
	 */
	public function setLimit($limit = 0, $offset = 0)
	{
		$this->limit  = (int) $limit;
		$this->offset = (int) $offset;

		return $this;
	}

	/**
	 * Split a string of sql expression into an array of individual columns.
	 * Single line or line end comments and multi line comments are stripped
off.
	 * Always return at least one column.
	 *
	 * @param   string  $string  Input string of sql expression like select
expression.
	 *
	 * @return  array[]  The columns from the input string separated into an
array.
	 *
	 * @since   3.7.0
	 */
	protected function splitSqlExpression($string)
	{
		// Append whitespace as equivalent to the last comma
		$string .= ' ';

		$colIdx    = 0;
		$start     = 0;
		$open      = false;
		$openC     = 0;
		$comment   = false;
		$endString = '';
		$length    = strlen($string);
		$columns   = array();
		$column    = array();
		$current   = '';
		$previous  = null;
		$operators = array(
			'+' => '',
			'-' => '',
			'*' => '',
			'/' => '',
			'%' => '',
			'&' => '',
			'|' => '',
			'~' => '',
			'^' => '',
		);

		$addBlock = function ($block) use (&$column, &$colIdx)
		{
			if (isset($column[$colIdx]))
			{
				$column[$colIdx] .= $block;
			}
			else
			{
				$column[$colIdx] = $block;
			}
		};

		for ($i = 0; $i < $length; $i++)
		{
			$current      = substr($string, $i, 1);
			$current2     = substr($string, $i, 2);
			$current3     = substr($string, $i, 3);
			$lenEndString = strlen($endString);
			$testEnd      = substr($string, $i, $lenEndString);

			if ($current == '[' || $current == '"' ||
$current == "'" || $current2 == '--'
				|| ($current2 == '/*') || ($current == '#'
&& $current3 != '#__')
				|| ($lenEndString && $testEnd == $endString))
			{
				if ($open)
				{
					if ($testEnd === $endString)
					{
						if ($comment)
						{
							if ($lenEndString > 1)
							{
								$i += ($lenEndString - 1);
							}

							// Move cursor after close tag of comment
							$start = $i + 1;
							$comment = false;
						}
						elseif ($current == "'" || $current == ']'
|| $current == '"')
						{
							// Check for escaped quote like '', ]] or ""
							$n = 1;

							while ($i + $n < $length && $string[$i + $n] == $current)
							{
								$n++;
							}

							// Jump to the last quote
							$i += $n - 1;

							if ($n % 2 === 0)
							{
								// There is only escaped quote
								continue;
							}
							elseif ($n > 2)
							{
								// The last right close quote is not escaped
								$current = $string[$i];
							}
						}

						$open = false;
						$endString = '';
					}
				}
				else
				{
					$open = true;

					if ($current == '#' || $current2 == '--')
					{
						$endString = "\n";
						$comment = true;
					}
					elseif ($current2 == '/*')
					{
						$endString = '*/';
						$comment = true;
					}
					elseif ($current == '[')
					{
						$endString = ']';
					}
					else
					{
						$endString = $current;
					}

					if ($comment && $start < $i)
					{
						// Add string exists before comment
						$addBlock(substr($string, $start, $i - $start));
						$previous = $string[$i - 1];
						$start = $i;
					}
				}
			}
			elseif (!$open)
			{
				if ($current == '(')
				{
					$openC++;
					$previous = $current;
				}
				elseif ($current == ')')
				{
					$openC--;
					$previous = $current;
				}
				elseif ($current == '.')
				{
					if ($i === $start && $colIdx > 0 &&
!isset($column[$colIdx]))
					{
						// Remove whitepace placed before dot
						$colIdx--;
					}

					$previous = $current;
				}
				elseif ($openC === 0)
				{
					if (ctype_space($current))
					{
						// Normalize whitepace
						$string[$i] = ' ';

						if ($start < $i)
						{
							// Add text placed before whitespace
							$addBlock(substr($string, $start, $i - $start));
							$colIdx++;
							$previous = $string[$i - 1];
						}
						elseif (isset($column[$colIdx]))
						{
							if ($colIdx > 1 || !isset($operators[$previous]))
							{
								// There was whitespace after comment
								$colIdx++;
							}
						}

						// Move cursor forward
						$start = $i + 1;
					}
					elseif (isset($operators[$current]) && ($current !==
'*' || $previous !== '.'))
					{
						if ($start < $i)
						{
							// Add text before operator
							$addBlock(substr($string, $start, $i - $start));
							$colIdx++;
						}
						elseif (!isset($column[$colIdx]) &&
isset($operators[$previous]))
						{
							// Do not create whitespace between operators
							$colIdx--;
						}

						// Add operator
						$addBlock($current);
						$previous = $current;
						$colIdx++;

						// Move cursor forward
						$start = $i + 1;
					}
					else
					{
						$previous = $current;
					}
				}
			}

			if (($current == ',' && !$open && $openC == 0)
|| $i == $length - 1)
			{
				if ($start < $i && !$comment)
				{
					// Save remaining text
					$addBlock(substr($string, $start, $i - $start));
				}

				$columns[] = $column;

				// Reset values
				$column   = array();
				$colIdx   = 0;
				$previous = null;

				// Column saved, move cursor forward after comma
				$start = $i + 1;
			}
		}

		return $columns;
	}

	/**
	 * Add required aliases to columns for select statement in subquery.
	 *
	 * @return  array[]  Array of columns with added missing aliases.
	 *
	 * @since   3.7.0
	 */
	protected function fixSelectAliases()
	{
		$operators = array(
			'+' => '',
			'-' => '',
			'*' => '',
			'/' => '',
			'%' => '',
			'&' => '',
			'|' => '',
			'~' => '',
			'^' => '',
		);

		// Split into array and remove comments
		$columns = $this->splitSqlExpression(implode(',',
$this->select->getElements()));

		foreach ($columns as $i => $column)
		{
			$size = count($column);

			if ($size == 0)
			{
				continue;
			}

			if ($size > 2 && strcasecmp($column[$size - 2],
'AS') === 0)
			{
				// Alias exists, replace it to uppercase
				$columns[$i][$size - 2] = 'AS';
				continue;
			}

			if ($i == 0 && stripos(' DISTINCT ALL ', "
$column[0] ") !== false)
			{
				// This words are reserved, they are not column names
				array_shift($column);
				$size--;
			}

			$lastWord = strtoupper($column[$size - 1]);
			$length   = strlen($lastWord);
			$lastChar = $lastWord[$length - 1];

			if ($lastChar == '*')
			{
				// Skip on wildcard
				continue;
			}

			if ($lastChar == ')'
				|| ($size == 1 && $lastChar == "'")
				|| $lastWord[0] == '@'
				|| $lastWord == 'NULL'
				|| $lastWord == 'END'
				|| is_numeric($lastWord))
			{
				/* Ends with:
				 * - SQL function
				 * - single static value like 'only '+'string'
				 * - @@var
				 * - NULL
				 * - CASE ... END
				 * - Numeric
				 */
				$columns[$i][] = 'AS';
				$columns[$i][] = $this->quoteName('columnAlias' . $i);
				continue;
			}

			if ($size == 1)
			{
				continue;
			}

			$lastChar2 = substr($column[$size - 2], -1);

			// Check if column ends with  '- a.x' or '- a. x'
			if (isset($operators[$lastChar2])
				|| ($size > 2 && $lastChar2 === '.' &&
isset($operators[substr($column[$size - 3], -1)])))
			{
				// Ignore plus signs if column start with them
				if ($size != 2 || ltrim($column[0], '+') !== '' ||
$column[1][0] === "'")
				{
					// If operator exists before last word then alias is required for
subquery
					$columns[$i][] = 'AS';
					$columns[$i][] = $this->quoteName('columnAlias' . $i);
					continue;
				}
			}
			elseif ($column[$size - 1][0] !== '.' && $lastChar2
!== '.')
			{
				// If columns is like name name2 then second word is alias.
				// Add missing AS before the alias, exception for 'a. x' and
'a .x'
				array_splice($columns[$i], -1, 0, 'AS');
			}
		}

		$selectColumns = array();

		foreach ($columns as $i => $column)
		{
			$selectColumns[$i] = implode(' ', $column);
		}

		$this->select = new JDatabaseQueryElement('SELECT',
$selectColumns);

		return $columns;
	}

	/**
	 * Add missing columns names to GROUP BY clause.
	 *
	 * @param   array[]  $selectColumns  Array of columns from
splitSqlExpression method.
	 *
	 * @return  JDatabaseQuery  Returns this object to allow chaining.
	 *
	 * @since   3.7.0
	 */
	protected function fixGroupColumns($selectColumns)
	{
		// Cache tables columns
		static $cacheCols = array();

		// Known columns of all included tables
		$knownColumnsByAlias = array();

		$iquotes  = array('"' => '', '['
=> '', "'" => '');
		$nquotes = array('"', '[', ']');

		// Aggregate functions
		$aFuncs = array(
			'AVG(',
			'CHECKSUM_AGG(',
			'COUNT(',
			'COUNT_BIG(',
			'GROUPING(',
			'GROUPING_ID(',
			'MIN(',
			'MAX(',
			'SUM(',
			'STDEV(',
			'STDEVP(',
			'VAR(',
			'VARP(',
		);

		// Aggregated columns
		$filteredColumns = array();

		// Aliases found in SELECT statement
		$knownAliases = array();
		$wildcardTables = array();

		foreach ($selectColumns as $i => $column)
		{
			$size = count($column);

			if ($size === 0)
			{
				continue;
			}

			if ($i == 0 && stripos(' DISTINCT ALL ', "
$column[0] ") !== false)
			{
				// These words are reserved, they are not column names
				array_shift($selectColumns[0]);
				array_shift($column);
				$size--;
			}

			if ($size > 2 && $column[$size - 2] === 'AS')
			{
				// Save and remove AS alias
				$alias = $column[$size - 1];

				if (isset($iquotes[$alias[0]]))
				{
					$alias = substr($alias, 1, -1);
				}

				// Remove alias
				$selectColumns[$i] = $column = array_slice($column, 0, -2);

				if ($size === 3 || ($size === 4 &&
strpos('+-*/%&|~^', $column[0][0]) !== false))
				{
					$lastWord = $column[$size - 3];

					if ($lastWord[0] === "'" || $lastWord ===
'NULL' || is_numeric($lastWord))
					{
						unset($selectColumns[$i]);

						continue;
					}
				}

				// Remember pair alias => column expression
				$knownAliases[$alias] = implode(' ', $column);
			}

			$aggregated = false;

			foreach ($column as $j => $block)
			{
				if (substr($block, -2) === '.*')
				{
					// Found column ends with .*
					if (isset($iquotes[$block[0]]))
					{
						// Quoted table
						$wildcardTables[] = substr($block, 1, -3);
					}
					else
					{
						$wildcardTables[] = substr($block, 0, -2);
					}
				}
				elseif (str_ireplace($aFuncs, '', $block) != $block)
				{
					$aggregated = true;
				}

				if ($block[0] === "'")
				{
					// Shrink static strings which could contain column name
					$column[$j] = "''";
				}
			}

			if (!$aggregated)
			{
				// Without aggregated columns and aliases
				$filteredColumns[] = implode(' ', $selectColumns[$i]);
			}

			// Without aliases and static strings
			$selectColumns[$i] = implode(' ', $column);
		}

		// If select statement use table.* expression
		if ($wildcardTables)
		{
			// Split FROM statement into list of tables
			$tables = $this->splitSqlExpression(implode(',',
$this->from->getElements()));

			foreach ($tables as $i => $table)
			{
				$table = implode(' ', $table);

				// Exclude subquery from the FROM clause
				if (strpos($table, '(') === false)
				{
					// Unquote
					$table = str_replace($nquotes, '', $table);
					$table = str_replace('#__', $this->db->getPrefix(),
$table);
					$table = explode(' ', $table);
					$alias = end($table);
					$table = $table[0];

					// Chek if exists a wildcard with current alias table?
					if (in_array($alias, $wildcardTables, true))
					{
						if (!isset($cacheCols[$table]))
						{
							$cacheCols[$table] = $this->db->getTableColumns($table);
						}

						if ($this->join || $table != $alias)
						{
							foreach ($cacheCols[$table] as $name => $type)
							{
								$knownColumnsByAlias[$alias][] = $alias . '.' . $name;
							}
						}
						else
						{
							foreach ($cacheCols[$table] as $name => $type)
							{
								$knownColumnsByAlias[$alias][] = $name;
							}
						}
					}
				}
			}

			// Now we need to get all tables from any joins
			// Go through all joins and add them to the tables array
			if ($this->join)
			{
				foreach ($this->join as $join)
				{
					// Unquote and replace prefix
					$joinTbl = str_replace($nquotes, '', (string) $join);
					$joinTbl = str_replace("#__", $this->db->getPrefix(),
$joinTbl);

					// Exclude subquery
					if (preg_match('/JOIN\s+(\w+)(?:\s+AS)?(?:\s+(\w+))?/i',
$joinTbl, $matches))
					{
						$table = $matches[1];
						$alias = isset($matches[2]) ? $matches[2] : $table;

						// Chek if exists a wildcard with current alias table?
						if (in_array($alias, $wildcardTables, true))
						{
							if (!isset($cacheCols[$table]))
							{
								$cacheCols[$table] = $this->db->getTableColumns($table);
							}

							foreach ($cacheCols[$table] as $name => $type)
							{
								$knownColumnsByAlias[$alias][] = $alias . '.' . $name;
							}
						}
					}
				}
			}
		}

		$selectExpression = implode(',', $selectColumns);

		// Split into the right columns
		$groupColumns = $this->splitSqlExpression(implode(',',
$this->group->getElements()));

		// Remove column aliases from GROUP statement - SQLSRV does not support
it
		foreach ($groupColumns as $i => $column)
		{
			$groupColumns[$i] = implode(' ', $column);
			$column = str_replace($nquotes, '', $groupColumns[$i]);

			if (isset($knownAliases[$column]))
			{
				// Be sure that this is not a valid column name
				if (!preg_match('/\b' . preg_quote($column, '/') .
'\b/', $selectExpression))
				{
					// Replace column alias by column expression
					$groupColumns[$i] = $knownAliases[$column];
				}
			}
		}

		// Find all alias.* and fill with proper table column names
		foreach ($filteredColumns as $i => $column)
		{
			if (substr($column, -2) === '.*')
			{
				unset($filteredColumns[$i]);

				// Extract alias.* columns into GROUP BY statement
				$groupColumns = array_merge($groupColumns,
$knownColumnsByAlias[substr($column, 0, -2)]);
			}
		}

		$groupColumns = array_merge($groupColumns, $filteredColumns);

		if ($this->order)
		{
			// Remove direction suffixes
			$dir = array(" DESC\v", " ASC\v");

			$orderColumns = $this->splitSqlExpression(implode(',',
$this->order->getElements()));

			foreach ($orderColumns as $i => $column)
			{
				$column = implode(' ', $column);
				$orderColumns[$i] = $column = trim(str_ireplace($dir, '',
"$column\v"), "\v");

				if (isset($knownAliases[str_replace($nquotes, '', $column)]))
				{
					unset($orderColumns[$i]);
				}

				if (str_ireplace($aFuncs, '', $column) != $column)
				{
					// Do not add aggregate expression
					unset($orderColumns[$i]);
				}
			}

			$groupColumns = array_merge($groupColumns, $orderColumns);
		}

		// Get a unique string of all column names that need to be included in
the group statement
		$this->group = new JDatabaseQueryElement('GROUP BY',
array_unique($groupColumns));

		return $this;
	}

	/**
	 * Return correct rand() function for MSSQL.
	 *
	 * Ensure that the rand() function is MSSQL compatible.
	 *
	 * Usage:
	 * $query->Rand();
	 *
	 * @return  string  The correct rand function.
	 *
	 * @since   3.5
	 */
	public function Rand()
	{
		return ' NEWID() ';
	}
}
abstract.php000064400000001761151160642700007067 0ustar00<?php
/**
 * @package     FrameworkOnFramework
 * @subpackage  query
 * @copyright   Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba
Ltd. All rights reserved.
 * @license     GNU General Public License version 2 or later; see
LICENSE.txt
 */
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;

/**
 * FrameworkOnFramework query base class; for compatibility purposes
 *
 * @package     FrameworkOnFramework
 * @since       2.1
 * @deprecated  2.1
 */
abstract class FOFQueryAbstract
{
	/**
	 * Returns a new database query class
	 *
	 * @param   FOFDatabaseDriver  $db  The DB driver which will provide us
with a query object
	 *
	 * @return FOFQueryAbstract
	 */
	public static function &getNew($db = null)
	{
		FOFPlatform::getInstance()->logDeprecated('FOFQueryAbstract is
deprecated. Use FOFDatabaseQuery instead.');

		if (is_null($db))
		{
			$ret = FOFPlatform::getInstance()->getDbo()->getQuery(true);
		}
		else
		{
			$ret = $db->getQuery(true);
		}

		return $ret;
	}
}