* Fields can be retrieved with $row->fieldname, with fields acting like
* member variables.
*
- * @param $res SQL result object as returned from DatabaseBase::query(), etc.
+ * @param $res ResultWrapper|object as returned from DatabaseBase::query(), etc.
* @return Row object
* @throws DBUnexpectedError Thrown if the database returns an error
*/
}
}
- /**
- * Called by unserialize. Needed to reopen DB connection, which
- * is not saved by serialize.
+ /**
+ * Called by serialize. Throw an exception when DB connection is serialized.
+ * This causes problems on some database engines because the connection is
+ * not restored on unserialize.
*/
- public function __wakeup() {
- if ( $this->isOpen() ) {
- $this->open( $this->mServer, $this->mUser,
- $this->mPassword, $this->mDBname);
- }
+ public function __sleep() {
+ throw new MWException( 'Database serialization may cause problems, since the connection is not restored on wakeup.' );
}
/**
# that would delay transaction initializations to once connection
# is really used by application
$sqlstart = substr( $sql, 0, 10 ); // very much worth it, benchmark certified(tm)
- if ( strpos( $sqlstart, "SHOW " ) !== 0 and strpos( $sqlstart, "SET " ) !== 0 )
+ if ( strpos( $sqlstart, "SHOW " ) !== 0 && strpos( $sqlstart, "SET " ) !== 0 )
$this->begin();
}
* - If the value is an array, an IN(...) clause will be constructed,
* such that the field name may match any of the elements in the
* array. The elements of the array will be quoted.
- * - If the field name ends with "!", this is taken as a flag which
- * inverts the comparison, allowing NOT IN clauses to be constructed,
- * for example: array( 'user_id!' => array( 1, 2, 3 ) )
*
* Note that expressions are often DBMS-dependent in their syntax.
* DBMS-independent wrappers are provided for constructing several types of
* Query whether a given table exists
*
* @param $table string
+ * @param $fname string
*
* @return bool
*/
- function tableExists( $table ) {
+ function tableExists( $table, $fname = __METHOD__ ) {
$table = $this->tableName( $table );
$old = $this->ignoreErrors( true );
- $res = $this->query( "SELECT 1 FROM $table LIMIT 1", __METHOD__ );
+ $res = $this->query( "SELECT 1 FROM $table LIMIT 1", $fname );
$this->ignoreErrors( $old );
return (bool)$res;
/**
* UPDATE wrapper. Takes a condition array and a SET array.
*
- * @param $table String name of the table to UPDATE. This will be passed through
+ * @param $table String|array name of the table to UPDATE. This will be passed through
* DatabaseBase::tableName().
*
- * @param $values Array: An array of values to SET. For each array element,
+ * @param $values Array An array of values to SET. For each array element,
* the key gives the field name, and the value gives the data
* to set that field to. The data will be quoted by
* DatabaseBase::addQuotes().
*
- * @param $conds Array: An array of conditions (WHERE). See
+ * @param $conds Array An array of conditions (WHERE). See
* DatabaseBase::select() for the details of the format of
* condition arrays. Use '*' to update all rows.
*
- * @param $fname String: The function name of the caller (from __METHOD__),
+ * @param $fname String The function name of the caller (from __METHOD__),
* for logging and profiling.
*
- * @param $options Array: An array of UPDATE options, can be:
+ * @param $options Array An array of UPDATE options, can be:
* - IGNORE: Ignore unique key conflicts
* - LOW_PRIORITY: MySQL-specific, see MySQL manual.
* @return Boolean
*/
function update( $table, $values, $conds, $fname = 'DatabaseBase::update', $options = array() ) {
- $table = $this->tableName( $table );
+ if ( is_array( $table ) ) {
+ $table = implode( ',', array_map( array( $this, 'tableName' ), $table ) );
+ } else {
+ $table = $this->tableName( $table );
+ }
$opts = $this->makeUpdateOptions( $options );
$sql = "UPDATE $opts $table SET " . $this->makeList( $values, LIST_SET );
}
}
- /**
- * Build a partial where clause from a 3-d array
- * The keys on each level may be either integers or strings.
- *
- * @param $data Array: organized as 3-d array(baseKeyVal => array(middleKeyVal => array(subKeyVal => <ignored>, ...), ...), ...)
- * @param $baseKey String: field name to match the base-level keys to (eg 'gtl_to_prefix')
- * @param $middleKey String: field name to match the middle-level keys to (eg 'gtl_to_namespace')
- * @param $subKey String: field name to match the sub-level keys to (eg 'gtl_to_title')
- * @return Mixed: string SQL fragment, or false if no items in array.
- */
- function makeWhereFrom3d( $data, $baseKey, $middleKey, $subKey ) {
- $conds = array();
- foreach ( $data as $base => $subdata ) {
- foreach ( $subdata as $middle => $sub ) {
- if ( count( $sub ) ) {
- $conds[] = $this->makeList(
- array( $baseKey => $base,
- $middleKey => $middle,
- $subKey => array_keys( $sub ) ),
- LIST_AND
- );
- }
- }
- }
-
- if ( $conds ) {
- return $this->makeList( $conds, LIST_OR );
- } else {
- // Nothing to search for...
- return false;
- }
- }
-
/**
* Bitwise operations
*/
* Returns an appropriately quoted sequence value for inserting a new row.
* MySQL has autoincrement fields, so this is just NULL. But the PostgreSQL
* subclass will return an integer, and save the value for insertId()
+ *
+ * Any implementation of this function should *not* involve reusing
+ * sequence numbers created for rolled-back transactions.
+ * See http://bugs.mysql.com/bug.php?id=30767 for details.
*/
function nextSequenceValue( $seqName ) {
return null;
" FROM $srcTable $useIndex ";
if ( $conds != '*' ) {
- $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
+ if ( is_array( $conds ) ) {
+ $conds = $this->makeList( $conds, LIST_AND );
+ }
+ $sql .= " WHERE $conds";
}
$sql .= " $tailOpts";
/**
* Get schema variables. If none have been set via setSchemaVars(), then
* use some defaults from the current object.
+ *
+ * @return array
*/
protected function getSchemaVars() {
if ( $this->mSchemaVars ) {
* @param $tableName string
* @param $fName string
* @return bool|ResultWrapper
+ * @since 1.18
*/
public function dropTable( $tableName, $fName = 'DatabaseBase::dropTable' ) {
- if( !$this->tableExists( $tableName ) ) {
+ if( !$this->tableExists( $tableName, $fName ) ) {
return false;
}
$sql = "DROP TABLE " . $this->tableName( $tableName );