getFlag( DBO_DEBUG ); if ( $debug !== null ) { $debug ? $this->setFlag( DBO_DEBUG ) : $this->clearFlag( DBO_DEBUG ); } return $res; } /** * @return string Command delimiter used by this database engine */ public function getDelimiter() { return $this->delimiter; } /** * Returns true if this database supports (and uses) cascading deletes * * @return bool */ public function cascadingDeletes() { return false; } /** * Returns true if this database supports (and uses) triggers (e.g. on the page table) * * @return bool */ public function cleanupTriggers() { return false; } /** * Returns true if this database is strict about what can be put into an IP field. * Specifically, it uses a NULL value instead of an empty string. * * @return bool */ public function strictIPs() { return false; } /** * Returns true if this database can do a native search on IP columns * e.g. this works as expected: .. WHERE rc_ip = '127.42.12.102/32'; * * @return bool */ public function searchableIPs() { return false; } /** * Returns true if this database uses timestamps rather than integers * * @return bool */ public function realTimestamps() { return false; } /** * Returns true if this database can use functional indexes * * @return bool */ public function functionalIndexes() { return false; } /** * Intended to be compatible with the PEAR::DB wrapper functions. * http://pear.php.net/manual/en/package.database.db.intro-execute.php * * ? = scalar value, quoted as necessary * ! = raw SQL bit (a function for instance) * & = filename; reads the file and inserts as a blob * (we don't use this though...) * * @param string $sql * @param string $func * * @return array */ protected function prepare( $sql, $func = __METHOD__ ) { /* MySQL doesn't support prepared statements (yet), so just * pack up the query for reference. We'll manually replace * the bits later. */ return [ 'query' => $sql, 'func' => $func ]; } /** * Free a prepared query, generated by prepare(). * @param string $prepared */ protected function freePrepared( $prepared ) { /* No-op by default */ } /** * Execute a prepared query with the various arguments * @param string $prepared The prepared sql * @param mixed $args Either an array here, or put scalars as varargs * * @return ResultWrapper */ public function execute( $prepared, $args = null ) { if ( !is_array( $args ) ) { # Pull the var args $args = func_get_args(); array_shift( $args ); } $sql = $this->fillPrepared( $prepared['query'], $args ); return $this->query( $sql, $prepared['func'] ); } /** * For faking prepared SQL statements on DBs that don't support it directly. * * @param string $preparedQuery A 'preparable' SQL statement * @param array $args Array of Arguments to fill it with * @return string Executable SQL */ public function fillPrepared( $preparedQuery, $args ) { reset( $args ); $this->preparedArgs =& $args; return preg_replace_callback( '/(\\\\[?!&]|[?!&])/', [ &$this, 'fillPreparedArg' ], $preparedQuery ); } /** * preg_callback func for fillPrepared() * The arguments should be in $this->preparedArgs and must not be touched * while we're doing this. * * @param array $matches * @throws DBUnexpectedError * @return string */ protected function fillPreparedArg( $matches ) { switch ( $matches[1] ) { case '\\?': return '?'; case '\\!': return '!'; case '\\&': return '&'; } list( /* $n */, $arg ) = each( $this->preparedArgs ); switch ( $matches[1] ) { case '?': return $this->addQuotes( $arg ); case '!': return $arg; case '&': # return $this->addQuotes( file_get_contents( $arg ) ); throw new DBUnexpectedError( $this, '& mode is not implemented. If it\'s really needed, uncomment the line above.' ); default: throw new DBUnexpectedError( $this, 'Received invalid match. This should never happen!' ); } } /** * Get search engine class. All subclasses of this need to implement this * if they wish to use searching. * * @return string */ public function getSearchEngine() { return 'SearchEngineDummy'; } }