mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
efef025027
BUG Fix incorrect method visibility on SS_Database BUG Fix obvious PHPDoc errors in SilverStripe\ORM\FieldType BUG Fix incorrect case on some method invocations API Remove some deprecated code
1059 lines
33 KiB
PHP
1059 lines
33 KiB
PHP
<?php
|
|
|
|
namespace SilverStripe\ORM\Connect;
|
|
|
|
use Director;
|
|
use Debug;
|
|
use BadMethodCallException;
|
|
use Exception;
|
|
use Deprecation;
|
|
use SilverStripe\ORM\Queries\SQLUpdate;
|
|
use SilverStripe\ORM\Queries\SQLInsert;
|
|
use SilverStripe\ORM\Queries\SQLExpression;
|
|
|
|
/**
|
|
* Abstract database connectivity class.
|
|
* Sub-classes of this implement the actual database connection libraries
|
|
*
|
|
* @package framework
|
|
* @subpackage orm
|
|
*/
|
|
abstract class SS_Database {
|
|
|
|
/**
|
|
* Database connector object
|
|
*
|
|
* @var DBConnector
|
|
*/
|
|
protected $connector = null;
|
|
|
|
/**
|
|
* Amount of queries executed, for debugging purposes.
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $queryCount = 0;
|
|
|
|
/**
|
|
* 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) {
|
|
// Check if we should only preview this query
|
|
if ($this->previewWrite($sql)) {
|
|
return;
|
|
}
|
|
|
|
// Benchmark query
|
|
$connector = $this->connector;
|
|
return $this->benchmarkQuery(
|
|
$sql,
|
|
function($sql) use($connector, $errorLevel) {
|
|
return $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) {
|
|
// Check if we should only preview this query
|
|
if ($this->previewWrite($sql)) {
|
|
return;
|
|
}
|
|
|
|
// Benchmark query
|
|
$connector = $this->connector;
|
|
return $this->benchmarkQuery(
|
|
$sql,
|
|
function($sql) use($connector, $parameters, $errorLevel) {
|
|
return $connector->preparedQuery($sql, $parameters, $errorLevel);
|
|
},
|
|
$parameters
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Determines if the query should be previewed, and thus interrupted silently.
|
|
* If so, this function also displays the query via the debuging system.
|
|
* Subclasess should respect the results of this call for each query, and not
|
|
* execute any queries that generate a true response.
|
|
*
|
|
* @param string $sql The query to be executed
|
|
* @return boolean Flag indicating that the query was previewed
|
|
*/
|
|
protected function previewWrite($sql) {
|
|
// Only preview if previewWrite is set, we are in dev mode, and
|
|
// the query is mutable
|
|
if (isset($_REQUEST['previewwrite'])
|
|
&& Director::isDev()
|
|
&& $this->connector->isQueryMutable($sql)
|
|
) {
|
|
// output preview message
|
|
Debug::message("Will execute: $sql");
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Allows the display and benchmarking of queries as they are being run
|
|
*
|
|
* @param string $sql Query to run, and single parameter to callback
|
|
* @param callable $callback Callback to execute code
|
|
* @param array $parameters Parameters to display
|
|
* @return mixed Result of query
|
|
*/
|
|
protected function benchmarkQuery($sql, $callback, $parameters = null) {
|
|
if (isset($_REQUEST['showqueries']) && Director::isDev()) {
|
|
$this->queryCount++;
|
|
$starttime = microtime(true);
|
|
$result = $callback($sql);
|
|
$endtime = round(microtime(true) - $starttime, 4);
|
|
$message = $sql;
|
|
if($parameters) {
|
|
$message .= "\nparams: \"" . implode('", "', $parameters) . '"';
|
|
}
|
|
Debug::message("\n$this->queryCount: {$message}\n{$endtime}s\n", false);
|
|
|
|
return $result;
|
|
} else {
|
|
return $callback($sql);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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|array $value The identifier to escape or list of split components
|
|
* @param string $separator Splitter for each component
|
|
* @return string
|
|
*/
|
|
public function escapeIdentifier($value, $separator = '.') {
|
|
// Split string into components
|
|
if(!is_array($value)) {
|
|
$value = explode($separator, $value);
|
|
}
|
|
|
|
// Implode quoted column
|
|
return '"' . implode('"'.$separator.'"', $value) . '"';
|
|
}
|
|
|
|
/**
|
|
* 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\"");
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
/**
|
|
* 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();
|
|
|
|
/**
|
|
* Invoke $callback within a transaction
|
|
*
|
|
* @param callable $callback Callback to run
|
|
* @param callable $errorCallback Optional callback to run after rolling back transaction.
|
|
* @param bool|string $transactionMode Optional transaction mode to use
|
|
* @param bool $errorIfTransactionsUnsupported If true, this method will fail if transactions are unsupported.
|
|
* Otherwise, the $callback will potentially be invoked outside of a transaction.
|
|
* @throws Exception
|
|
*/
|
|
public function withTransaction(
|
|
$callback, $errorCallback = null, $transactionMode = false, $errorIfTransactionsUnsupported = false
|
|
) {
|
|
$supported = $this->supportsTransactions();
|
|
if(!$supported && $errorIfTransactionsUnsupported) {
|
|
throw new BadMethodCallException("Transactions not supported by this database.");
|
|
}
|
|
if($supported) {
|
|
$this->transactionStart($transactionMode);
|
|
}
|
|
try {
|
|
call_user_func($callback);
|
|
} catch (Exception $ex) {
|
|
if($supported) {
|
|
$this->transactionRollback();
|
|
}
|
|
if($errorCallback) {
|
|
call_user_func($errorCallback);
|
|
}
|
|
throw $ex;
|
|
}
|
|
if($supported) {
|
|
$this->transactionEnd();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 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
|
|
*/
|
|
public 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 4.0 Use DB::get_schema()->dbDataType($type) instead
|
|
*/
|
|
public function dbDataType($type){
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->dbDataType($type) instead');
|
|
return $this->getSchemaManager()->dbDataType($type);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use selectDatabase('dbname', true) instead
|
|
*/
|
|
public function createDatabase() {
|
|
Deprecation::notice('4.0', 'Use selectDatabase(\'dbname\',true) instead');
|
|
$database = $this->connector->getSelectedDatabase();
|
|
$this->selectDatabase($database, true);
|
|
return $this->isActive();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 SS_Database::getConnect was never implemented and is obsolete
|
|
*/
|
|
public function getConnect($parameters) {
|
|
Deprecation::notice('4.0', 'SS_Database::getConnect was never implemented and is obsolete');
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use Convert::raw2sql($string, true) instead
|
|
*/
|
|
public function prepStringForDB($string) {
|
|
Deprecation::notice('4.0', 'Use Convert::raw2sql($string, true) instead');
|
|
return $this->quoteString($string);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use dropSelectedDatabase instead
|
|
*/
|
|
public function dropDatabase() {
|
|
Deprecation::notice('4.0', 'Use dropSelectedDatabase instead');
|
|
$this->dropSelectedDatabase();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use databaseList instead
|
|
*/
|
|
public function allDatabaseNames() {
|
|
Deprecation::notice('4.0', 'Use databaseList instead');
|
|
return $this->databaseList();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::create_table instead
|
|
*/
|
|
public function createTable($table, $fields = null, $indexes = null, $options = null, $advancedOptions = null) {
|
|
Deprecation::notice('4.0', 'Use DB::create_table instead');
|
|
return $this->getSchemaManager()->createTable($table, $fields, $indexes, $options, $advancedOptions);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->alterTable() instead
|
|
*/
|
|
public function alterTable($table, $newFields = null, $newIndexes = null,
|
|
$alteredFields = null, $alteredIndexes = null, $alteredOptions = null,
|
|
$advancedOptions = null
|
|
) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->alterTable() instead');
|
|
return $this->getSchemaManager()->alterTable(
|
|
$table, $newFields, $newIndexes, $alteredFields,
|
|
$alteredIndexes, $alteredOptions, $advancedOptions
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->renameTable() instead
|
|
*/
|
|
public function renameTable($oldTableName, $newTableName) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->renameTable() instead');
|
|
$this->getSchemaManager()->renameTable($oldTableName, $newTableName);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::create_field() instead
|
|
*/
|
|
public function createField($table, $field, $spec) {
|
|
Deprecation::notice('4.0', 'Use DB::create_field() instead');
|
|
$this->getSchemaManager()->createField($table, $field, $spec);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->renameField() instead
|
|
*/
|
|
public function renameField($tableName, $oldName, $newName) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->renameField() instead');
|
|
$this->getSchemaManager()->renameField($tableName, $oldName, $newName);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use getSelectedDatabase instead
|
|
*/
|
|
public function currentDatabase() {
|
|
Deprecation::notice('4.0', 'Use getSelectedDatabase instead');
|
|
return $this->getSelectedDatabase();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::field_list instead
|
|
*/
|
|
public function fieldList($table) {
|
|
Deprecation::notice('4.0', 'Use DB::field_list instead');
|
|
return $this->getSchemaManager()->fieldList($table);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::table_list instead
|
|
*/
|
|
public function tableList() {
|
|
Deprecation::notice('4.0', 'Use DB::table_list instead');
|
|
return $this->getSchemaManager()->tableList();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->hasTable() instead
|
|
*/
|
|
public function hasTable($tableName) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->hasTable() instead');
|
|
return $this->getSchemaManager()->hasTable($tableName);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->enumValuesForField() instead
|
|
*/
|
|
public function enumValuesForField($tableName, $fieldName) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->enumValuesForField() instead');
|
|
return $this->getSchemaManager()->enumValuesForField($tableName, $fieldName);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use Convert::raw2sql instead
|
|
*/
|
|
public function addslashes($value) {
|
|
Deprecation::notice('4.0', '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 4.0 Use DB::get_schema()->cancelSchemaUpdate instead
|
|
*/
|
|
public function cancelSchemaUpdate() {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->cancelSchemaUpdate instead');
|
|
$this->getSchemaManager()->cancelSchemaUpdate();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->isSchemaUpdating() instead
|
|
*/
|
|
public function isSchemaUpdating() {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->isSchemaUpdating() instead');
|
|
return $this->getSchemaManager()->isSchemaUpdating();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->doesSchemaNeedUpdating() instead
|
|
*/
|
|
public function doesSchemaNeedUpdating() {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->doesSchemaNeedUpdating() instead');
|
|
return $this->getSchemaManager()->doesSchemaNeedUpdating();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->transCreateTable() instead
|
|
*/
|
|
public function transCreateTable($table, $options = null, $advanced_options = null) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->transCreateTable() instead');
|
|
$this->getSchemaManager()->transCreateTable($table, $options, $advanced_options);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->transAlterTable() instead
|
|
*/
|
|
public function transAlterTable($table, $options, $advanced_options) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->transAlterTable() instead');
|
|
$this->getSchemaManager()->transAlterTable($table, $index, $schema);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->transCreateField() instead
|
|
*/
|
|
public function transCreateField($table, $field, $schema) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->transCreateField() instead');
|
|
$this->getSchemaManager()->transCreateField($table, $index, $schema);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->transCreateIndex() instead
|
|
*/
|
|
public function transCreateIndex($table, $index, $schema) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->transCreateIndex() instead');
|
|
$this->getSchemaManager()->transCreateIndex($table, $index, $schema);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->transAlterField() instead
|
|
*/
|
|
public function transAlterField($table, $field, $schema) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->transAlterField() instead');
|
|
$this->getSchemaManager()->transAlterField($table, $index, $schema);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->transAlterIndex() instead
|
|
*/
|
|
public function transAlterIndex($table, $index, $schema) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->transAlterIndex() instead');
|
|
$this->getSchemaManager()->transAlterIndex($table, $index, $schema);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::require_table() instead
|
|
*/
|
|
public function requireTable($table, $fieldSchema = null, $indexSchema = null,
|
|
$hasAutoIncPK = true, $options = array(), $extensions = false
|
|
) {
|
|
Deprecation::notice('4.0', 'Use DB::require_table() instead');
|
|
return $this->getSchemaManager()->requireTable(
|
|
$table, $fieldSchema, $indexSchema, $hasAutoIncPK, $options, $extensions
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::dont_require_table() instead
|
|
*/
|
|
public function dontRequireTable($table) {
|
|
Deprecation::notice('4.0', 'Use DB::dont_require_table() instead');
|
|
$this->getSchemaManager()->dontRequireTable($table);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::require_index() instead
|
|
*/
|
|
public function requireIndex($table, $index, $spec) {
|
|
Deprecation::notice('4.0', 'Use DB::require_index() instead');
|
|
$this->getSchemaManager()->requireIndex($table, $index, $spec);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::get_schema()->hasField() instead
|
|
*/
|
|
public function hasField($tableName, $fieldName) {
|
|
Deprecation::notice('4.0', 'Use DB::get_schema()->hasField() instead');
|
|
return $this->getSchemaManager()->hasField($tableName, $fieldName);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::require_field() instead
|
|
*/
|
|
public function requireField($table, $field, $spec) {
|
|
Deprecation::notice('4.0', 'Use DB::require_field() instead');
|
|
$this->getSchemaManager()->requireField($table, $field, $spec);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::dont_require_field() instead
|
|
*/
|
|
public function dontRequireField($table, $fieldName) {
|
|
Deprecation::notice('4.0', 'Use DB::dont_require_field() instead');
|
|
$this->getSchemaManager()->dontRequireField($table, $fieldName);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since version 4.0 Use DB::build_sql() instead
|
|
*/
|
|
public function sqlQueryToString(SQLExpression $query, &$parameters = array()) {
|
|
Deprecation::notice('4.0', 'Use DB::build_sql() instead');
|
|
return $this->getQueryBuilder()->buildSQL($query, $parameters);
|
|
}
|
|
}
|