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 for any parameterised query * @return mixed Result of query */ protected function benchmarkQuery($sql, $callback, $parameters = array()) { if (isset($_REQUEST['showqueries']) && Director::isDev()) { $starttime = microtime(true); $result = $callback($sql); $endtime = round(microtime(true) - $starttime, 4); // replace parameters as closely as possible to what we'd expect the DB to put in if (strtolower($_REQUEST['showqueries']) == 'inline') { $sql = DB::inline_parameters($sql, $parameters); } Debug::message("\n$sql\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 $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\""); } /** * 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) { // In case our live environment is locked down, we can bypass a SHOW DATABASE check $canConnect = Config::inst()->get(get_class($this), 'optimistic_connect') || $this->schemaManager->databaseExists($name); if($canConnect) { return $this->connector->selectDatabase($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); } }