2013-06-21 00:32:08 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Abstract database connectivity class.
|
|
|
|
* Sub-classes of this implement the actual database connection libraries
|
|
|
|
*
|
|
|
|
* @package framework
|
|
|
|
* @subpackage model
|
|
|
|
*/
|
|
|
|
abstract class SS_Database {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Database connector object
|
|
|
|
*
|
|
|
|
* @var DBConnector
|
|
|
|
*/
|
|
|
|
protected $connector = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the current connector
|
|
|
|
*
|
|
|
|
* @return DBConnector
|
|
|
|
*/
|
|
|
|
public function getConnector() {
|
|
|
|
return $this->connector;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Injector injection point for connector dependency
|
|
|
|
*
|
|
|
|
* @param DBConnector $connector
|
|
|
|
*/
|
|
|
|
public function setConnector(DBConnector $connector) {
|
|
|
|
$this->connector = $connector;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Database schema manager object
|
|
|
|
*
|
|
|
|
* @var DBSchemaManager
|
|
|
|
*/
|
|
|
|
protected $schemaManager = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the current schema manager
|
|
|
|
*
|
|
|
|
* @return DBSchemaManager
|
|
|
|
*/
|
|
|
|
public function getSchemaManager() {
|
|
|
|
return $this->schemaManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Injector injection point for schema manager
|
|
|
|
*
|
|
|
|
* @param DBSchemaManager $schemaManager
|
|
|
|
*/
|
|
|
|
public function setSchemaManager(DBSchemaManager $schemaManager) {
|
|
|
|
$this->schemaManager = $schemaManager;
|
|
|
|
|
|
|
|
if ($this->schemaManager) {
|
|
|
|
$this->schemaManager->setDatabase($this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Query builder object
|
|
|
|
*
|
|
|
|
* @var DBQueryBuilder
|
|
|
|
*/
|
|
|
|
protected $queryBuilder = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the current query builder
|
|
|
|
*
|
|
|
|
* @return DBQueryBuilder
|
|
|
|
*/
|
|
|
|
public function getQueryBuilder() {
|
|
|
|
return $this->queryBuilder;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Injector injection point for schema manager
|
|
|
|
*
|
|
|
|
* @param DBQueryBuilder $queryBuilder
|
|
|
|
*/
|
|
|
|
public function setQueryBuilder(DBQueryBuilder $queryBuilder) {
|
|
|
|
$this->queryBuilder = $queryBuilder;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute the given SQL query.
|
|
|
|
*
|
|
|
|
* @param string $sql The SQL query to execute
|
|
|
|
* @param int $errorLevel The level of error reporting to enable for the query
|
|
|
|
* @return SS_Query
|
|
|
|
*/
|
|
|
|
public function query($sql, $errorLevel = E_USER_ERROR) {
|
|
|
|
return $this->connector->query($sql, $errorLevel);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute the given SQL parameterised query with the specified arguments
|
|
|
|
*
|
|
|
|
* @param string $sql The SQL query to execute. The ? character will denote parameters.
|
|
|
|
* @param array $parameters An ordered list of arguments.
|
|
|
|
* @param int $errorLevel The level of error reporting to enable for the query
|
|
|
|
* @return SS_Query
|
|
|
|
*/
|
|
|
|
public function preparedQuery($sql, $parameters, $errorLevel = E_USER_ERROR) {
|
|
|
|
return $this->connector->preparedQuery($sql, $parameters, $errorLevel);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the autogenerated ID from the previous INSERT query.
|
|
|
|
*
|
|
|
|
* @param string $table The name of the table to get the generated ID for
|
|
|
|
* @return integer the most recently generated ID for the specified table
|
|
|
|
*/
|
|
|
|
public function getGeneratedID($table) {
|
|
|
|
return $this->connector->getGeneratedID($table);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines if we are connected to a server AND have a valid database
|
|
|
|
* selected.
|
|
|
|
*
|
|
|
|
* @return boolean Flag indicating that a valid database is connected
|
|
|
|
*/
|
|
|
|
public function isActive() {
|
|
|
|
return $this->connector->isActive();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an escaped string. This string won't be quoted, so would be suitable
|
|
|
|
* for appending to other quoted strings.
|
|
|
|
*
|
|
|
|
* @param mixed $value Value to be prepared for database query
|
|
|
|
* @return string Prepared string
|
|
|
|
*/
|
|
|
|
public function escapeString($value) {
|
|
|
|
return $this->connector->escapeString($value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrap a string into DB-specific quotes.
|
|
|
|
*
|
|
|
|
* @param mixed $value Value to be prepared for database query
|
|
|
|
* @return string Prepared string
|
|
|
|
*/
|
|
|
|
public function quoteString($value) {
|
|
|
|
return $this->connector->quoteString($value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Escapes an identifier (table / database name). Typically the value
|
|
|
|
* is simply double quoted. Don't pass in already escaped identifiers in,
|
|
|
|
* as this will double escape the value!
|
|
|
|
*
|
|
|
|
* @param string $value The identifier to escape
|
|
|
|
* @param string $separator optional identifier splitter
|
|
|
|
*/
|
|
|
|
public function escapeIdentifier($value, $separator = '.') {
|
|
|
|
return $this->connector->escapeIdentifier($value, $separator);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Escapes unquoted columns keys in an associative array
|
|
|
|
*
|
|
|
|
* @param array $fieldValues
|
|
|
|
* @return array List of field values with the keys as escaped column names
|
|
|
|
*/
|
|
|
|
protected function escapeColumnKeys($fieldValues) {
|
|
|
|
$out = array();
|
|
|
|
foreach($fieldValues as $field => $value) {
|
|
|
|
$out[$this->escapeIdentifier($field)] = $value;
|
|
|
|
}
|
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute a complex manipulation on the database.
|
|
|
|
* A manipulation is an array of insert / or update sequences. The keys of the array are table names,
|
|
|
|
* and the values are map containing 'command' and 'fields'. Command should be 'insert' or 'update',
|
|
|
|
* and fields should be a map of field names to field values, NOT including quotes.
|
|
|
|
*
|
|
|
|
* The field values could also be in paramaterised format, such as
|
|
|
|
* array('MAX(?,?)' => array(42, 69)), allowing the use of raw SQL values such as
|
|
|
|
* array('NOW()' => array()).
|
|
|
|
*
|
|
|
|
* @see SQLWriteExpression::addAssignments for syntax examples
|
|
|
|
*
|
|
|
|
* @param array $manipulation
|
|
|
|
*/
|
|
|
|
public function manipulate($manipulation) {
|
|
|
|
if (empty($manipulation)) return;
|
|
|
|
|
|
|
|
foreach ($manipulation as $table => $writeInfo) {
|
|
|
|
if(empty($writeInfo['fields'])) continue;
|
|
|
|
// Note: keys of $fieldValues are not escaped
|
|
|
|
$fieldValues = $writeInfo['fields'];
|
|
|
|
|
|
|
|
// Switch command type
|
|
|
|
switch ($writeInfo['command']) {
|
|
|
|
case "update":
|
|
|
|
|
|
|
|
// Build update
|
|
|
|
$query = new SQLUpdate("\"$table\"", $this->escapeColumnKeys($fieldValues));
|
|
|
|
|
|
|
|
// Set best condition to use
|
|
|
|
if(!empty($writeInfo['where'])) {
|
|
|
|
$query->addWhere($writeInfo['where']);
|
|
|
|
} elseif(!empty($writeInfo['id'])) {
|
|
|
|
$query->addWhere(array('"ID"' => $writeInfo['id']));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test to see if this update query shouldn't, in fact, be an insert
|
|
|
|
if($query->toSelect()->count()) {
|
|
|
|
$query->execute();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// ...if not, we'll skip on to the insert code
|
|
|
|
|
|
|
|
case "insert":
|
|
|
|
// Ensure that the ID clause is given if possible
|
|
|
|
if (!isset($fieldValues['ID']) && isset($writeInfo['id'])) {
|
|
|
|
$fieldValues['ID'] = $writeInfo['id'];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build insert
|
|
|
|
$query = new SQLInsert("\"$table\"", $this->escapeColumnKeys($fieldValues));
|
|
|
|
|
|
|
|
$query->execute();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
user_error("SS_Database::manipulate() Can't recognise command '{$writeInfo['command']}'",
|
|
|
|
E_USER_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Enable supression of database messages.
|
|
|
|
*/
|
|
|
|
public function quiet() {
|
|
|
|
$this->schemaManager->quiet();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear all data out of the database
|
|
|
|
*/
|
|
|
|
public function clearAllData() {
|
|
|
|
$tables = $this->getSchemaManager()->tableList();
|
|
|
|
foreach ($tables as $table) {
|
|
|
|
$this->clearTable($table);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear all data in a given table
|
|
|
|
*
|
|
|
|
* @param string $table Name of table
|
|
|
|
*/
|
|
|
|
public function clearTable($table) {
|
|
|
|
$this->query("TRUNCATE \"$table\"");
|
|
|
|
}
|
|
|
|
|
2015-05-19 03:39:39 +02:00
|
|
|
/**
|
|
|
|
* Generates a WHERE clause for null comparison check
|
|
|
|
*
|
|
|
|
* @param string $field Quoted field name
|
|
|
|
* @param bool $isNull Whether to check for NULL or NOT NULL
|
|
|
|
* @return string Non-parameterised null comparison clause
|
|
|
|
*/
|
|
|
|
public function nullCheckClause($field, $isNull) {
|
|
|
|
$clause = $isNull
|
|
|
|
? "%s IS NULL"
|
|
|
|
: "%s IS NOT NULL";
|
|
|
|
return sprintf($clause, $field);
|
|
|
|
}
|
|
|
|
|
2013-06-21 00:32:08 +02:00
|
|
|
/**
|
|
|
|
* Generate a WHERE clause for text matching.
|
|
|
|
*
|
|
|
|
* @param String $field Quoted field name
|
|
|
|
* @param String $value Escaped search. Can include percentage wildcards.
|
|
|
|
* Ignored if $parameterised is true.
|
|
|
|
* @param boolean $exact Exact matches or wildcard support.
|
|
|
|
* @param boolean $negate Negate the clause.
|
|
|
|
* @param boolean $caseSensitive Enforce case sensitivity if TRUE or FALSE.
|
|
|
|
* Fallback to default collation if set to NULL.
|
|
|
|
* @param boolean $parameterised Insert the ? placeholder rather than the
|
|
|
|
* given value. If this is true then $value is ignored.
|
|
|
|
* @return String SQL
|
|
|
|
*/
|
|
|
|
abstract public function comparisonClause($field, $value, $exact = false, $negate = false, $caseSensitive = null,
|
|
|
|
$parameterised = false);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* function to return an SQL datetime expression that can be used with the adapter in use
|
|
|
|
* used for querying a datetime in a certain format
|
|
|
|
*
|
|
|
|
* @param string $date to be formated, can be either 'now', literal datetime like '1973-10-14 10:30:00' or
|
|
|
|
* field name, e.g. '"SiteTree"."Created"'
|
|
|
|
* @param string $format to be used, supported specifiers:
|
|
|
|
* %Y = Year (four digits)
|
|
|
|
* %m = Month (01..12)
|
|
|
|
* %d = Day (01..31)
|
|
|
|
* %H = Hour (00..23)
|
|
|
|
* %i = Minutes (00..59)
|
|
|
|
* %s = Seconds (00..59)
|
|
|
|
* %U = unix timestamp, can only be used on it's own
|
|
|
|
* @return string SQL datetime expression to query for a formatted datetime
|
|
|
|
*/
|
|
|
|
abstract public function formattedDatetimeClause($date, $format);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* function to return an SQL datetime expression that can be used with the adapter in use
|
|
|
|
* used for querying a datetime addition
|
|
|
|
*
|
|
|
|
* @param string $date, can be either 'now', literal datetime like '1973-10-14 10:30:00' or field name,
|
|
|
|
* e.g. '"SiteTree"."Created"'
|
|
|
|
* @param string $interval to be added, use the format [sign][integer] [qualifier], e.g. -1 Day, +15 minutes,
|
|
|
|
* +1 YEAR
|
|
|
|
* supported qualifiers:
|
|
|
|
* - years
|
|
|
|
* - months
|
|
|
|
* - days
|
|
|
|
* - hours
|
|
|
|
* - minutes
|
|
|
|
* - seconds
|
|
|
|
* This includes the singular forms as well
|
|
|
|
* @return string SQL datetime expression to query for a datetime (YYYY-MM-DD hh:mm:ss) which is the result of
|
|
|
|
* the addition
|
|
|
|
*/
|
|
|
|
abstract public function datetimeIntervalClause($date, $interval);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* function to return an SQL datetime expression that can be used with the adapter in use
|
|
|
|
* used for querying a datetime substraction
|
|
|
|
*
|
|
|
|
* @param string $date1, can be either 'now', literal datetime like '1973-10-14 10:30:00' or field name
|
|
|
|
* e.g. '"SiteTree"."Created"'
|
|
|
|
* @param string $date2 to be substracted of $date1, can be either 'now', literal datetime
|
|
|
|
* like '1973-10-14 10:30:00' or field name, e.g. '"SiteTree"."Created"'
|
|
|
|
* @return string SQL datetime expression to query for the interval between $date1 and $date2 in seconds which
|
|
|
|
* is the result of the substraction
|
|
|
|
*/
|
|
|
|
abstract public function datetimeDifferenceClause($date1, $date2);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if this database supports collations
|
|
|
|
*
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
abstract public function supportsCollations();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Can the database override timezone as a connection setting,
|
|
|
|
* or does it use the system timezone exclusively?
|
|
|
|
*
|
|
|
|
* @return Boolean
|
|
|
|
*/
|
|
|
|
abstract public function supportsTimezoneOverride();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Query for the version of the currently connected database
|
|
|
|
* @return string Version of this database
|
|
|
|
*/
|
|
|
|
public function getVersion() {
|
|
|
|
return $this->connector->getVersion();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the database server type (e.g. mysql, postgresql).
|
|
|
|
* This value is passed to the connector as the 'driver' argument when
|
|
|
|
* initiating a database connection
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
abstract public function getDatabaseServer();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the number of rows affected by the previous operation.
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
public function affectedRows() {
|
|
|
|
return $this->connector->affectedRows();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The core search engine, used by this class and its subclasses to do fun stuff.
|
|
|
|
* Searches both SiteTree and File.
|
|
|
|
*
|
|
|
|
* @param array $classesToSearch List of classes to search
|
|
|
|
* @param string $keywords Keywords as a string.
|
|
|
|
* @param integer $start Item to start returning results from
|
|
|
|
* @param integer $pageLength Number of items per page
|
|
|
|
* @param string $sortBy Sort order expression
|
|
|
|
* @param string $extraFilter Additional filter
|
|
|
|
* @param boolean $booleanSearch Flag for boolean search mode
|
|
|
|
* @param string $alternativeFileFilter
|
|
|
|
* @param boolean $invertedMatch
|
|
|
|
* @return PaginatedList Search results
|
|
|
|
*/
|
|
|
|
abstract public function searchEngine($classesToSearch, $keywords, $start, $pageLength, $sortBy = "Relevance DESC",
|
|
|
|
$extraFilter = "", $booleanSearch = false, $alternativeFileFilter = "", $invertedMatch = false);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines if this database supports transactions
|
|
|
|
*
|
|
|
|
* @return boolean Flag indicating support for transactions
|
|
|
|
*/
|
|
|
|
abstract public function supportsTransactions();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determines if the current database connection supports a given list of extensions
|
|
|
|
*
|
|
|
|
* @param array $extensions List of extensions to check for support of. The key of this array
|
|
|
|
* will be an extension name, and the value the configuration for that extension. This
|
|
|
|
* could be one of partitions, tablespaces, or clustering
|
|
|
|
* @return boolean Flag indicating support for all of the above
|
|
|
|
* @todo Write test cases
|
|
|
|
*/
|
|
|
|
protected function supportsExtensions($extensions) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start a prepared transaction
|
|
|
|
* See http://developer.postgresql.org/pgdocs/postgres/sql-set-transaction.html for details on
|
|
|
|
* transaction isolation options
|
|
|
|
*
|
|
|
|
* @param string|boolean $transactionMode Transaction mode, or false to ignore
|
|
|
|
* @param string|boolean $sessionCharacteristics Session characteristics, or false to ignore
|
|
|
|
*/
|
|
|
|
abstract public function transactionStart($transactionMode = false, $sessionCharacteristics = false);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a savepoint that you can jump back to if you encounter problems
|
|
|
|
*
|
|
|
|
* @param string $savepoint Name of savepoint
|
|
|
|
*/
|
|
|
|
abstract public function transactionSavepoint($savepoint);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Rollback or revert to a savepoint if your queries encounter problems
|
|
|
|
* If you encounter a problem at any point during a transaction, you may
|
|
|
|
* need to rollback that particular query, or return to a savepoint
|
|
|
|
*
|
|
|
|
* @param string|boolean $savepoint Name of savepoint, or leave empty to rollback
|
|
|
|
* to last savepoint
|
|
|
|
*/
|
|
|
|
abstract public function transactionRollback($savepoint = false);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Commit everything inside this transaction so far
|
|
|
|
*
|
|
|
|
* @param boolean $chain
|
|
|
|
*/
|
|
|
|
abstract public function transactionEnd($chain = false);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines if the used database supports application-level locks,
|
|
|
|
* which is different from table- or row-level locking.
|
|
|
|
* See {@link getLock()} for details.
|
|
|
|
*
|
|
|
|
* @return boolean Flag indicating that locking is available
|
|
|
|
*/
|
|
|
|
public function supportsLocks() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns if the lock is available.
|
|
|
|
* See {@link supportsLocks()} to check if locking is generally supported.
|
|
|
|
*
|
|
|
|
* @param string $name Name of the lock
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function canLock($name) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets an application-level lock so that no two processes can run at the same time,
|
|
|
|
* also called a "cooperative advisory lock".
|
|
|
|
*
|
|
|
|
* Return FALSE if acquiring the lock fails; otherwise return TRUE, if lock was acquired successfully.
|
|
|
|
* Lock is automatically released if connection to the database is broken (either normally or abnormally),
|
|
|
|
* making it less prone to deadlocks than session- or file-based locks.
|
|
|
|
* Should be accompanied by a {@link releaseLock()} call after the logic requiring the lock has completed.
|
|
|
|
* Can be called multiple times, in which case locks "stack" (PostgreSQL, SQL Server),
|
|
|
|
* or auto-releases the previous lock (MySQL).
|
|
|
|
*
|
|
|
|
* Note that this might trigger the database to wait for the lock to be released, delaying further execution.
|
|
|
|
*
|
|
|
|
* @param string $name Name of lock
|
|
|
|
* @param integer $timeout Timeout in seconds
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function getLock($name, $timeout = 5) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove an application-level lock file to allow another process to run
|
|
|
|
* (if the execution aborts (e.g. due to an error) all locks are automatically released).
|
|
|
|
*
|
|
|
|
* @param string $name Name of the lock
|
|
|
|
* @return boolean Flag indicating whether the lock was successfully released
|
|
|
|
*/
|
|
|
|
public function releaseLock($name) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Instruct the database to generate a live connection
|
|
|
|
*
|
|
|
|
* @param array $parameters An map of parameters, which should include:
|
|
|
|
* - server: The server, eg, localhost
|
|
|
|
* - username: The username to log on with
|
|
|
|
* - password: The password to log on with
|
|
|
|
* - database: The database to connect to
|
|
|
|
* - charset: The character set to use. Defaults to utf8
|
|
|
|
* - timezone: (optional) The timezone offset. For example: +12:00, "Pacific/Auckland", or "SYSTEM"
|
|
|
|
* - driver: (optional) Driver name
|
|
|
|
*/
|
|
|
|
public function connect($parameters) {
|
|
|
|
// Ensure that driver is available (required by PDO)
|
|
|
|
if(empty($parameters['driver'])) {
|
|
|
|
$parameters['driver'] = $this->getDatabaseServer();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Notify connector of parameters
|
|
|
|
$this->connector->connect($parameters);
|
|
|
|
|
|
|
|
// SS_Database subclass maintains responsibility for selecting database
|
|
|
|
// once connected in order to correctly handle schema queries about
|
|
|
|
// existence of database, error handling at the correct level, etc
|
|
|
|
if (!empty($parameters['database'])) {
|
|
|
|
$this->selectDatabase($parameters['database'], false, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine if the database with the specified name exists
|
|
|
|
*
|
|
|
|
* @param string $name Name of the database to check for
|
|
|
|
* @return boolean Flag indicating whether this database exists
|
|
|
|
*/
|
|
|
|
public function databaseExists($name) {
|
|
|
|
return $this->schemaManager->databaseExists($name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the list of all databases the user has access to
|
|
|
|
*
|
|
|
|
* @return array List of database names
|
|
|
|
*/
|
|
|
|
public function databaseList() {
|
|
|
|
return $this->schemaManager->databaseList();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Change the connection to the specified database, optionally creating the
|
|
|
|
* database if it doesn't exist in the current schema.
|
|
|
|
*
|
|
|
|
* @param string $name Name of the database
|
|
|
|
* @param boolean $create Flag indicating whether the database should be created
|
|
|
|
* if it doesn't exist. If $create is false and the database doesn't exist
|
|
|
|
* then an error will be raised
|
|
|
|
* @param int|boolean $errorLevel The level of error reporting to enable for the query, or false if no error
|
|
|
|
* should be raised
|
|
|
|
* @return boolean Flag indicating success
|
|
|
|
*/
|
|
|
|
public function selectDatabase($name, $create = false, $errorLevel = E_USER_ERROR) {
|
|
|
|
if (!$this->schemaManager->databaseExists($name)) {
|
|
|
|
// Check DB creation permisson
|
|
|
|
if (!$create) {
|
|
|
|
if ($errorLevel !== false) {
|
|
|
|
user_error("Attempted to connect to non-existing database \"$name\"", $errorLevel);
|
|
|
|
}
|
|
|
|
// Unselect database
|
|
|
|
$this->connector->unloadDatabase();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$this->schemaManager->createDatabase($name);
|
|
|
|
}
|
|
|
|
return $this->connector->selectDatabase($name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Drop the database that this object is currently connected to.
|
|
|
|
* Use with caution.
|
|
|
|
*/
|
|
|
|
public function dropSelectedDatabase() {
|
|
|
|
$databaseName = $this->connector->getSelectedDatabase();
|
|
|
|
if ($databaseName) {
|
|
|
|
$this->connector->unloadDatabase();
|
|
|
|
$this->schemaManager->dropDatabase($databaseName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the name of the currently selected database
|
|
|
|
*
|
|
|
|
* @return string|null Name of the selected database, or null if none selected
|
|
|
|
*/
|
|
|
|
public function getSelectedDatabase() {
|
|
|
|
return $this->connector->getSelectedDatabase();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return SQL expression used to represent the current date/time
|
|
|
|
*
|
|
|
|
* @return string Expression for the current date/time
|
|
|
|
*/
|
|
|
|
abstract public function now();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the database-specific version of the random() function
|
|
|
|
*
|
|
|
|
* @return string Expression for a random value
|
|
|
|
*/
|
|
|
|
abstract public function random();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->dbDataType($type) instead
|
|
|
|
*/
|
|
|
|
public function dbDataType($type){
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->dbDataType($type) instead');
|
|
|
|
return $this->getSchemaManager()->dbDataType($type);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use selectDatabase('dbname', true) instead
|
|
|
|
*/
|
|
|
|
public function createDatabase() {
|
|
|
|
Deprecation::notice('3.3', 'Use selectDatabase(\'dbname\',true) instead');
|
|
|
|
$database = $this->connector->getSelectedDatabase();
|
|
|
|
$this->selectDatabase($database, true);
|
|
|
|
return $this->isActive();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 SS_Database::getConnect was never implemented and is obsolete
|
|
|
|
*/
|
|
|
|
public function getConnect($parameters) {
|
|
|
|
Deprecation::notice('3.3', 'SS_Database::getConnect was never implemented and is obsolete');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use Convert::raw2sql($string, true) instead
|
|
|
|
*/
|
|
|
|
public function prepStringForDB($string) {
|
|
|
|
Deprecation::notice('3.3', 'Use Convert::raw2sql($string, true) instead');
|
|
|
|
return $this->quoteString($string);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use dropSelectedDatabase instead
|
|
|
|
*/
|
|
|
|
public function dropDatabase() {
|
|
|
|
Deprecation::notice('3.3', 'Use dropSelectedDatabase instead');
|
|
|
|
$this->dropSelectedDatabase();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use databaseList instead
|
|
|
|
*/
|
|
|
|
public function allDatabaseNames() {
|
|
|
|
Deprecation::notice('3.3', 'Use databaseList instead');
|
|
|
|
return $this->databaseList();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::create_table instead
|
|
|
|
*/
|
|
|
|
public function createTable($table, $fields = null, $indexes = null, $options = null, $advancedOptions = null) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::create_table instead');
|
|
|
|
return $this->getSchemaManager()->createTable($table, $fields, $indexes, $options, $advancedOptions);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->alterTable() instead
|
|
|
|
*/
|
|
|
|
public function alterTable($table, $newFields = null, $newIndexes = null,
|
|
|
|
$alteredFields = null, $alteredIndexes = null, $alteredOptions = null,
|
|
|
|
$advancedOptions = null
|
|
|
|
) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->alterTable() instead');
|
|
|
|
return $this->getSchemaManager()->alterTable(
|
|
|
|
$table, $newFields, $newIndexes, $alteredFields,
|
|
|
|
$alteredIndexes, $alteredOptions, $advancedOptions
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->renameTable() instead
|
|
|
|
*/
|
|
|
|
public function renameTable($oldTableName, $newTableName) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->renameTable() instead');
|
|
|
|
$this->getSchemaManager()->renameTable($oldTableName, $newTableName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::create_field() instead
|
|
|
|
*/
|
|
|
|
public function createField($table, $field, $spec) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::create_field() instead');
|
|
|
|
$this->getSchemaManager()->createField($table, $field, $spec);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->renameField() instead
|
|
|
|
*/
|
|
|
|
public function renameField($tableName, $oldName, $newName) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->renameField() instead');
|
|
|
|
$this->getSchemaManager()->renameField($tableName, $oldName, $newName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use getSelectedDatabase instead
|
|
|
|
*/
|
|
|
|
public function currentDatabase() {
|
|
|
|
Deprecation::notice('3.3', 'Use getSelectedDatabase instead');
|
|
|
|
return $this->getSelectedDatabase();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::field_list instead
|
|
|
|
*/
|
|
|
|
public function fieldList($table) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::field_list instead');
|
|
|
|
return $this->getSchemaManager()->fieldList($table);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::table_list instead
|
|
|
|
*/
|
|
|
|
public function tableList() {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::table_list instead');
|
|
|
|
return $this->getSchemaManager()->tableList();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->hasTable() instead
|
|
|
|
*/
|
|
|
|
public function hasTable($tableName) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->hasTable() instead');
|
|
|
|
return $this->getSchemaManager()->hasTable($tableName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->enumValuesForField() instead
|
|
|
|
*/
|
|
|
|
public function enumValuesForField($tableName, $fieldName) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->enumValuesForField() instead');
|
|
|
|
return $this->getSchemaManager()->enumValuesForField($tableName, $fieldName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use Convert::raw2sql instead
|
|
|
|
*/
|
|
|
|
public function addslashes($value) {
|
|
|
|
Deprecation::notice('3.3', 'Use Convert::raw2sql instead');
|
|
|
|
return $this->escapeString($value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.2 Use DB::get_schema()->schemaUpdate with a callback instead
|
|
|
|
*/
|
|
|
|
public function beginSchemaUpdate() {
|
|
|
|
Deprecation::notice('3.2', 'Use DB::get_schema()->schemaUpdate with a callback instead');
|
|
|
|
// Unable to recover so throw appropriate exception
|
|
|
|
throw new BadMethodCallException('Use DB::get_schema()->schemaUpdate with a callback instead');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.2 Use DB::get_schema()->schemaUpdate with a callback instead
|
|
|
|
*/
|
|
|
|
public function endSchemaUpdate() {
|
|
|
|
Deprecation::notice('3.2', 'Use DB::get_schema()->schemaUpdate with a callback instead');
|
|
|
|
// Unable to recover so throw appropriate exception
|
|
|
|
throw new BadMethodCallException('Use DB::get_schema()->schemaUpdate with a callback instead');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->cancelSchemaUpdate instead
|
|
|
|
*/
|
|
|
|
public function cancelSchemaUpdate() {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->cancelSchemaUpdate instead');
|
|
|
|
$this->getSchemaManager()->cancelSchemaUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->isSchemaUpdating() instead
|
|
|
|
*/
|
|
|
|
public function isSchemaUpdating() {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->isSchemaUpdating() instead');
|
|
|
|
return $this->getSchemaManager()->isSchemaUpdating();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->doesSchemaNeedUpdating() instead
|
|
|
|
*/
|
|
|
|
public function doesSchemaNeedUpdating() {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->doesSchemaNeedUpdating() instead');
|
|
|
|
return $this->getSchemaManager()->doesSchemaNeedUpdating();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->transCreateTable() instead
|
|
|
|
*/
|
|
|
|
public function transCreateTable($table, $options = null, $advanced_options = null) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->transCreateTable() instead');
|
|
|
|
$this->getSchemaManager()->transCreateTable($table, $options, $advanced_options);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->transAlterTable() instead
|
|
|
|
*/
|
|
|
|
public function transAlterTable($table, $options, $advanced_options) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->transAlterTable() instead');
|
|
|
|
$this->getSchemaManager()->transAlterTable($table, $index, $schema);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->transCreateField() instead
|
|
|
|
*/
|
|
|
|
public function transCreateField($table, $field, $schema) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->transCreateField() instead');
|
|
|
|
$this->getSchemaManager()->transCreateField($table, $index, $schema);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->transCreateIndex() instead
|
|
|
|
*/
|
|
|
|
public function transCreateIndex($table, $index, $schema) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->transCreateIndex() instead');
|
|
|
|
$this->getSchemaManager()->transCreateIndex($table, $index, $schema);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->transAlterField() instead
|
|
|
|
*/
|
|
|
|
public function transAlterField($table, $field, $schema) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->transAlterField() instead');
|
|
|
|
$this->getSchemaManager()->transAlterField($table, $index, $schema);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->transAlterIndex() instead
|
|
|
|
*/
|
|
|
|
public function transAlterIndex($table, $index, $schema) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->transAlterIndex() instead');
|
|
|
|
$this->getSchemaManager()->transAlterIndex($table, $index, $schema);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::require_table() instead
|
|
|
|
*/
|
|
|
|
public function requireTable($table, $fieldSchema = null, $indexSchema = null,
|
|
|
|
$hasAutoIncPK = true, $options = array(), $extensions = false
|
|
|
|
) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::require_table() instead');
|
|
|
|
return $this->getSchemaManager()->requireTable(
|
|
|
|
$table, $fieldSchema, $indexSchema, $hasAutoIncPK, $options, $extensions
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::dont_require_table() instead
|
|
|
|
*/
|
|
|
|
public function dontRequireTable($table) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::dont_require_table() instead');
|
|
|
|
$this->getSchemaManager()->dontRequireTable($table);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::require_index() instead
|
|
|
|
*/
|
|
|
|
public function requireIndex($table, $index, $spec) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::require_index() instead');
|
|
|
|
$this->getSchemaManager()->requireIndex($table, $index, $spec);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::get_schema()->hasField() instead
|
|
|
|
*/
|
|
|
|
public function hasField($tableName, $fieldName) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::get_schema()->hasField() instead');
|
|
|
|
return $this->getSchemaManager()->hasField($tableName, $fieldName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::require_field() instead
|
|
|
|
*/
|
|
|
|
public function requireField($table, $field, $spec) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::require_field() instead');
|
|
|
|
$this->getSchemaManager()->requireField($table, $field, $spec);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::dont_require_field() instead
|
|
|
|
*/
|
|
|
|
public function dontRequireField($table, $fieldName) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::dont_require_field() instead');
|
|
|
|
$this->getSchemaManager()->dontRequireField($table, $fieldName);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated since version 3.3 Use DB::build_sql() instead
|
|
|
|
*/
|
|
|
|
public function sqlQueryToString(SQLExpression $query, &$parameters = array()) {
|
|
|
|
Deprecation::notice('3.3', 'Use DB::build_sql() instead');
|
|
|
|
return $this->getQueryBuilder()->buildSQL($query, $parameters);
|
|
|
|
}
|
|
|
|
}
|