databasec.php
来自「php 开发的内容管理系统」· PHP 代码 · 共 1,939 行 · 第 1/4 页
PHP
1,939 行
<?php
// Modified for mediawiki for XOOPS - by D.J.
if(defined("MEDIAWIKI_DATABASE")):
return;
else:
define("MEDIAWIKI_DATABASE", 1);
/**
* This file deals with MySQL interface functions
* and query specifics/optimisations
* @package MediaWiki
*/
/**
* Depends on the CacheManager
*/
//require_once( 'CacheManager.php' );
/** See Database::makeList() */
define( 'LIST_COMMA', 0 );
define( 'LIST_AND', 1 );
define( 'LIST_SET', 2 );
define( 'LIST_NAMES', 3);
define( 'LIST_OR', 4);
/** Number of times to re-try an operation in case of deadlock */
define( 'DEADLOCK_TRIES', 4 );
/** Minimum time to wait before retry, in microseconds */
define( 'DEADLOCK_DELAY_MIN', 500000 );
/** Maximum time to wait before retry */
define( 'DEADLOCK_DELAY_MAX', 1500000 );
class DBObject {
var $mData;
function DBObject($data) {
$this->mData = $data;
}
function isLOB() {
return false;
}
function data() {
return $this->mData;
}
};
/**
* Database abstraction object
* @package MediaWiki
*/
class mwDatabase {
#------------------------------------------------------------------------------
# Variables
#------------------------------------------------------------------------------
/**#@+
* @access private
*/
var $mLastQuery = '';
var $mServer, $mUser, $mPassword, $mConn = null, $mDBname;
var $mOut, $mOpened = false;
var $mFailFunction;
var $mTablePrefix;
var $mFlags;
var $mTrxLevel = 0;
var $mErrorCount = 0;
var $mLBInfo = array();
/**#@-*/
#------------------------------------------------------------------------------
# Accessors
#------------------------------------------------------------------------------
# These optionally set a variable and return the previous state
/**
* Fail function, takes a Database as a parameter
* Set to false for default, 1 for ignore errors
*/
function failFunction( $function = NULL ) {
return wfSetVar( $this->mFailFunction, $function );
}
/**
* Output page, used for reporting errors
* FALSE means discard output
*/
function &setOutputPage( &$out ) {
$this->mOut =& $out;
}
/**
* Boolean, controls output of large amounts of debug information
*/
function debug( $debug = NULL ) {
return wfSetBit( $this->mFlags, DBO_DEBUG, $debug );
}
/**
* Turns buffering of SQL result sets on (true) or off (false).
* Default is "on" and it should not be changed without good reasons.
*/
function bufferResults( $buffer = NULL ) {
if ( is_null( $buffer ) ) {
return !(bool)( $this->mFlags & DBO_NOBUFFER );
} else {
return !wfSetBit( $this->mFlags, DBO_NOBUFFER, !$buffer );
}
}
/**
* Turns on (false) or off (true) the automatic generation and sending
* of a "we're sorry, but there has been a database error" page on
* database errors. Default is on (false). When turned off, the
* code should use wfLastErrno() and wfLastError() to handle the
* situation as appropriate.
*/
function ignoreErrors( $ignoreErrors = NULL ) {
return wfSetBit( $this->mFlags, DBO_IGNORE, $ignoreErrors );
}
/**
* The current depth of nested transactions
* @param integer $level
*/
function trxLevel( $level = NULL ) {
return wfSetVar( $this->mTrxLevel, $level );
}
/**
* Number of errors logged, only useful when errors are ignored
*/
function errorCount( $count = NULL ) {
return wfSetVar( $this->mErrorCount, $count );
}
/**
* Properties passed down from the server info array of the load balancer
*/
function getLBInfo( $name = NULL ) {
if ( is_null( $name ) ) {
return $this->mLBInfo;
} else {
if ( array_key_exists( $name, $this->mLBInfo ) ) {
return $this->mLBInfo[$name];
} else {
return NULL;
}
}
}
function setLBInfo( $name, $value = NULL ) {
if ( is_null( $value ) ) {
$this->mLBInfo = $name;
} else {
$this->mLBInfo[$name] = $value;
}
}
/**#@+
* Get function
*/
function lastQuery() { return $this->mLastQuery; }
function isOpen() { return $this->mOpened; }
/**#@-*/
function setFlag( $flag ) {
$this->mFlags |= $flag;
}
function clearFlag( $flag ) {
$this->mFlags &= ~$flag;
}
function getFlag( $flag ) {
return !!($this->mFlags & $flag);
}
// Modified for mediawiki for XOOPS - by D.J.
/* compatible with XOOPS */
function Database( $server = false, $user = false, $password = false, $dbName = false,
$failFunction = false, $flags = 0, $tablePrefix = 'get from global' ) {
$this->mwDatabase( $server, $user, $password, $dbName, $failFunction, $flags, $tablePrefix);
}
#------------------------------------------------------------------------------
# Other functions
#------------------------------------------------------------------------------
/**#@+
* @param string $server database server host
* @param string $user database user name
* @param string $password database user password
* @param string $dbname database name
*/
/**
* @param failFunction
* @param $flags
* @param string $tablePrefix Database table prefixes. By default use the prefix gave in LocalSettings.php
*/
// Modified for mediawiki for XOOPS - by D.J.
function mwDatabase( $server = false, $user = false, $password = false, $dbName = false,
$failFunction = false, $flags = 0, $tablePrefix = 'get from global' ) {
global $wgOut, $wgDBprefix, $wgCommandLineMode;
# Can't get a reference if it hasn't been set yet
if ( !isset( $wgOut ) ) {
$wgOut = NULL;
}
$this->mOut =& $wgOut;
$this->mFailFunction = $failFunction;
$this->mFlags = $flags;
if ( $this->mFlags & DBO_DEFAULT ) {
if ( $wgCommandLineMode ) {
$this->mFlags &= ~DBO_TRX;
} else {
$this->mFlags |= DBO_TRX;
}
}
/*
// Faster read-only access
if ( wfReadOnly() ) {
$this->mFlags |= DBO_PERSISTENT;
$this->mFlags &= ~DBO_TRX;
}*/
/** Get the default table prefix*/
if ( $tablePrefix == 'get from global' ) {
$this->mTablePrefix = $wgDBprefix;
} else {
$this->mTablePrefix = $tablePrefix;
}
if ( $server ) {
$this->open( $server, $user, $password, $dbName );
}
}
/**
* @static
* @param failFunction
* @param $flags
*/
function newFromParams( $server, $user, $password, $dbName,
$failFunction = false, $flags = 0 )
{
return new mwDatabase( $server, $user, $password, $dbName, $failFunction, $flags );
}
/**
* Usually aborts on failure
* If the failFunction is set to a non-zero integer, returns success
*/
function open( $server, $user, $password, $dbName ) {
global $wguname;
# Test for missing mysql.so
# First try to load it
if (!@extension_loaded('mysql')) {
@dl('mysql.so');
}
# Otherwise we get a suppressed fatal error, which is very hard to track down
if ( !function_exists( 'mysql_connect' ) ) {
wfDie( "MySQL functions missing, have you compiled PHP with the --with-mysql option?\n" );
}
$this->close();
$this->mServer = $server;
$this->mUser = $user;
$this->mPassword = $password;
$this->mDBname = $dbName;
$success = false;
# Force connecting to XOOPS DB
if($GLOBALS["xoopsDB"]->conn){
$this->mConn =& $GLOBALS["xoopsDB"]->conn;
}else
if ( $this->mFlags & DBO_PERSISTENT ) {
@/**/$this->mConn = mysql_pconnect( $server, $user, $password );
} else {
# Create a new connection...
if( version_compare( PHP_VERSION, '4.2.0', 'ge' ) ) {
@/**/$this->mConn = mysql_connect( $server, $user, $password, true );
} else {
# On PHP 4.1 the new_link parameter is not available. We cannot
# guarantee that we'll actually get a new connection, and this
# may cause some operations to fail possibly.
@/**/$this->mConn = mysql_connect( $server, $user, $password );
}
}
if ( $dbName != '' ) {
if ( $this->mConn !== false ) {
$success = @/**/mysql_select_db( $dbName, $this->mConn );
if ( !$success ) {
$error = "Error selecting database $dbName on server {$this->mServer} " .
"from client host {$wguname['nodename']}\n";
wfDebug( $error );
}
} else {
wfDebug( "DB connection error\n" );
wfDebug( "Server: $server, User: $user, Password: " .
substr( $password, 0, 3 ) . "..., error: " . mysql_error() . "\n" );
$success = false;
}
} else {
# Delay USE query
$success = (bool)$this->mConn;
}
if ( !$success ) {
$this->reportConnectionError();
}
global $wgDBmysql5;
if( $wgDBmysql5 ) {
// Tell the server we're communicating with it in UTF-8.
// This may engage various charset conversions.
$this->query( 'SET NAMES utf8' );
}
$this->mOpened = $success;
return $success;
}
/**#@-*/
/**
* Closes a database connection.
* if it is open : commits any open transactions
*
* @return bool operation success. true if already closed.
*/
function close()
{
$this->mOpened = false;
if ( $this->mConn ) {
if ( $this->trxLevel() ) {
$this->immediateCommit();
}
return mysql_close( $this->mConn );
} else {
return true;
}
}
/**
* @access private
* @param string $error fallback error message, used if none is given by MySQL
*/
function reportConnectionError( $error = 'Unknown error' ) {
$myError = $this->lastError();
if ( $myError ) {
$error = $myError;
}
if ( $this->mFailFunction ) {
if ( !is_int( $this->mFailFunction ) ) {
$ff = $this->mFailFunction;
$ff( $this, $error );
}
} else {
wfEmergencyAbort( $this, $error );
}
}
/**
* Usually aborts on failure
* If errors are explicitly ignored, returns success
*/
function query( $sql, $fname = '', $tempIgnore = false ) {
global $wgProfiling;
if ( $wgProfiling ) {
# generalizeSQL will probably cut down the query to reasonable
# logging size most of the time. The substr is really just a sanity check.
# Who's been wasting my precious column space? -- TS
#$profName = 'query: ' . $fname . ' ' . substr( Database::generalizeSQL( $sql ), 0, 255 );
if ( is_null( $this->getLBInfo( 'master' ) ) ) {
$queryProf = 'query: ' . substr( Database::generalizeSQL( $sql ), 0, 255 );
$totalProf = 'Database::query';
} else {
$queryProf = 'query-m: ' . substr( Database::generalizeSQL( $sql ), 0, 255 );
$totalProf = 'Database::query-master';
}
wfProfileIn( $totalProf );
wfProfileIn( $queryProf );
}
$this->mLastQuery = $sql;
# Add a comment for easy SHOW PROCESSLIST interpretation
if ( $fname ) {
$commentedSql = preg_replace("/\s/", " /* $fname */ ", $sql, 1);
} else {
$commentedSql = $sql;
}
# If DBO_TRX is set, start a transaction
if ( ( $this->mFlags & DBO_TRX ) && !$this->trxLevel() && $sql != 'BEGIN' ) {
$this->begin();
}
if ( $this->debug() ) {
$sqlx = substr( $commentedSql, 0, 500 );
$sqlx = strtr( $sqlx, "\t\n", ' ' );
wfDebug( "SQL: $sqlx\n" );
}
# Do the query and handle errors
$ret = $this->doQuery( $commentedSql );
# Try reconnecting if the connection was lost
if ( false === $ret && ( $this->lastErrno() == 2013 || $this->lastErrno() == 2006 ) ) {
# Transaction is gone, like it or not
$this->mTrxLevel = 0;
wfDebug( "Connection lost, reconnecting...\n" );
if ( $this->ping() ) {
wfDebug( "Reconnected\n" );
$ret = $this->doQuery( $commentedSql );
} else {
wfDebug( "Failed\n" );
}
}
if ( false === $ret ) {
$this->reportQueryError( $this->lastError(), $this->lastErrno(), $sql, $fname, $tempIgnore );
}
if ( $wgProfiling ) {
wfProfileOut( $queryProf );
wfProfileOut( $totalProf );
}
return $ret;
}
/**
* The DBMS-dependent part of query()
* @param string $sql SQL query.
*/
function doQuery( $sql ) {
if( $this->bufferResults() ) {
$ret = mysql_query( $sql, $this->mConn );
} else {
$ret = mysql_unbuffered_query( $sql, $this->mConn );
}
return $ret;
}
/**
* @param $error
* @param $errno
* @param $sql
* @param string $fname
* @param bool $tempIgnore
*/
function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
global $wgCommandLineMode, $wgFullyInitialised, $wgColorErrors;
# Ignore errors during error handling to avoid infinite recursion
$ignore = $this->ignoreErrors( true );
++$this->mErrorCount;
if( $ignore || $tempIgnore ) {
wfDebug("SQL ERROR (ignored): $error\n");
} else {
$sql1line = str_replace( "\n", "\\n", $sql );
wfLogDBError("$fname\t{$this->mServer}\t$errno\t$error\t$sql1line\n");
wfDebug("SQL ERROR: " . $error . "\n");
if ( $wgCommandLineMode || !$this->mOut || empty( $wgFullyInitialised ) ) {
$message = "A database error has occurred\n" .
"Query: $sql\n" .
"Function: $fname\n" .
"Error: $errno $error\n";
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?