This was left over from a previous attempt at Oracle support,
which was removed in 1.10 (r19196 / ccf91e827a).
Change-Id: I5f9b82fffc0b4f84286b697be8d504020fe22547
323 lines
6.2 KiB
PHP
323 lines
6.2 KiB
PHP
<?php
|
|
/**
|
|
* This file contains database-related utility classes.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
* @file
|
|
* @ingroup Database
|
|
*/
|
|
|
|
/**
|
|
* Utility class
|
|
* @ingroup Database
|
|
*
|
|
* This allows us to distinguish a blob from a normal string and an array of strings
|
|
*/
|
|
class Blob {
|
|
/** @var string */
|
|
protected $mData;
|
|
|
|
function __construct( $data ) {
|
|
$this->mData = $data;
|
|
}
|
|
|
|
function fetch() {
|
|
return $this->mData;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Base for all database-specific classes representing information about database fields
|
|
* @ingroup Database
|
|
*/
|
|
interface Field {
|
|
/**
|
|
* Field name
|
|
* @return string
|
|
*/
|
|
function name();
|
|
|
|
/**
|
|
* Name of table this field belongs to
|
|
* @return string
|
|
*/
|
|
function tableName();
|
|
|
|
/**
|
|
* Database type
|
|
* @return string
|
|
*/
|
|
function type();
|
|
|
|
/**
|
|
* Whether this field can store NULL values
|
|
* @return bool
|
|
*/
|
|
function isNullable();
|
|
}
|
|
|
|
/**
|
|
* Result wrapper for grabbing data queried by someone else
|
|
* @ingroup Database
|
|
*/
|
|
class ResultWrapper implements Iterator {
|
|
/** @var resource */
|
|
public $result;
|
|
|
|
/** @var DatabaseBase */
|
|
protected $db;
|
|
|
|
/** @var int */
|
|
protected $pos = 0;
|
|
|
|
/** @var object|null */
|
|
protected $currentRow = null;
|
|
|
|
/**
|
|
* Create a new result object from a result resource and a Database object
|
|
*
|
|
* @param DatabaseBase $database
|
|
* @param resource|ResultWrapper $result
|
|
*/
|
|
function __construct( $database, $result ) {
|
|
$this->db = $database;
|
|
|
|
if ( $result instanceof ResultWrapper ) {
|
|
$this->result = $result->result;
|
|
} else {
|
|
$this->result = $result;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the number of rows in a result object
|
|
*
|
|
* @return int
|
|
*/
|
|
function numRows() {
|
|
return $this->db->numRows( $this );
|
|
}
|
|
|
|
/**
|
|
* Fetch the next row from the given result object, in object form.
|
|
* Fields can be retrieved with $row->fieldname, with fields acting like
|
|
* member variables.
|
|
*
|
|
* @return stdClass
|
|
* @throws DBUnexpectedError Thrown if the database returns an error
|
|
*/
|
|
function fetchObject() {
|
|
return $this->db->fetchObject( $this );
|
|
}
|
|
|
|
/**
|
|
* Fetch the next row from the given result object, in associative array
|
|
* form. Fields are retrieved with $row['fieldname'].
|
|
*
|
|
* @return array
|
|
* @throws DBUnexpectedError Thrown if the database returns an error
|
|
*/
|
|
function fetchRow() {
|
|
return $this->db->fetchRow( $this );
|
|
}
|
|
|
|
/**
|
|
* Free a result object
|
|
*/
|
|
function free() {
|
|
$this->db->freeResult( $this );
|
|
unset( $this->result );
|
|
unset( $this->db );
|
|
}
|
|
|
|
/**
|
|
* Change the position of the cursor in a result object.
|
|
* See mysql_data_seek()
|
|
*
|
|
* @param int $row
|
|
*/
|
|
function seek( $row ) {
|
|
$this->db->dataSeek( $this, $row );
|
|
}
|
|
|
|
/*
|
|
* ======= Iterator functions =======
|
|
* Note that using these in combination with the non-iterator functions
|
|
* above may cause rows to be skipped or repeated.
|
|
*/
|
|
|
|
function rewind() {
|
|
if ( $this->numRows() ) {
|
|
$this->db->dataSeek( $this, 0 );
|
|
}
|
|
$this->pos = 0;
|
|
$this->currentRow = null;
|
|
}
|
|
|
|
/**
|
|
* @return stdClass|array|bool
|
|
*/
|
|
function current() {
|
|
if ( is_null( $this->currentRow ) ) {
|
|
$this->next();
|
|
}
|
|
|
|
return $this->currentRow;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
function key() {
|
|
return $this->pos;
|
|
}
|
|
|
|
/**
|
|
* @return stdClass
|
|
*/
|
|
function next() {
|
|
$this->pos++;
|
|
$this->currentRow = $this->fetchObject();
|
|
|
|
return $this->currentRow;
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
function valid() {
|
|
return $this->current() !== false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Overloads the relevant methods of the real ResultsWrapper so it
|
|
* doesn't go anywhere near an actual database.
|
|
*/
|
|
class FakeResultWrapper extends ResultWrapper {
|
|
/** @var array */
|
|
public $result = array();
|
|
|
|
/** @var null And it's going to stay that way :D */
|
|
protected $db = null;
|
|
|
|
/** @var int */
|
|
protected $pos = 0;
|
|
|
|
/** @var array|stdClass|bool */
|
|
protected $currentRow = null;
|
|
|
|
function __construct( $array ) {
|
|
$this->result = $array;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
function numRows() {
|
|
return count( $this->result );
|
|
}
|
|
|
|
/**
|
|
* @return array|bool
|
|
*/
|
|
function fetchRow() {
|
|
if ( $this->pos < count( $this->result ) ) {
|
|
$this->currentRow = $this->result[$this->pos];
|
|
} else {
|
|
$this->currentRow = false;
|
|
}
|
|
$this->pos++;
|
|
if ( is_object( $this->currentRow ) ) {
|
|
return get_object_vars( $this->currentRow );
|
|
} else {
|
|
return $this->currentRow;
|
|
}
|
|
}
|
|
|
|
function seek( $row ) {
|
|
$this->pos = $row;
|
|
}
|
|
|
|
function free() {
|
|
}
|
|
|
|
/**
|
|
* Callers want to be able to access fields with $this->fieldName
|
|
* @return bool|stdClass
|
|
*/
|
|
function fetchObject() {
|
|
$this->fetchRow();
|
|
if ( $this->currentRow ) {
|
|
return (object)$this->currentRow;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function rewind() {
|
|
$this->pos = 0;
|
|
$this->currentRow = null;
|
|
}
|
|
|
|
/**
|
|
* @return bool|stdClass
|
|
*/
|
|
function next() {
|
|
return $this->fetchObject();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Used by DatabaseBase::buildLike() to represent characters that have special
|
|
* meaning in SQL LIKE clauses and thus need no escaping. Don't instantiate it
|
|
* manually, use DatabaseBase::anyChar() and anyString() instead.
|
|
*/
|
|
class LikeMatch {
|
|
/** @var string */
|
|
private $str;
|
|
|
|
/**
|
|
* Store a string into a LikeMatch marker object.
|
|
*
|
|
* @param string $s
|
|
*/
|
|
public function __construct( $s ) {
|
|
$this->str = $s;
|
|
}
|
|
|
|
/**
|
|
* Return the original stored string.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function toString() {
|
|
return $this->str;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An object representing a master or slave position in a replicated setup.
|
|
*
|
|
* The implementation details of this opaque type are up to the database subclass.
|
|
*/
|
|
interface DBMasterPos {
|
|
/**
|
|
* @return float UNIX timestamp
|
|
*/
|
|
public function asOfTime();
|
|
}
|