Difference between revisions of "Extension:MediaWikiLite.php"
(close()) |
(Fill in the main guts of whats needed) |
||
Line 7: | Line 7: | ||
if (!defined('SQLITE_OK')) die('SQLite is not installed!'); | if (!defined('SQLITE_OK')) die('SQLite is not installed!'); | ||
− | define('SQLITE_VERSION','0.0.0, 2007-12- | + | define('SQLITE_VERSION','0.0.0, 2007-12-30'); |
$wgDBtype = 'sqlite'; | $wgDBtype = 'sqlite'; | ||
Line 21: | Line 21: | ||
class DatabaseSqlite extends Database { | class DatabaseSqlite extends Database { | ||
+ | |||
+ | var $mAffectedRows; | ||
function DatabaseSqlite($server = false, $user = false, $password = false, $dbName = false, $failFunction = false, $flags = 0) { | function DatabaseSqlite($server = false, $user = false, $password = false, $dbName = false, $failFunction = false, $flags = 0) { | ||
Line 66: | Line 68: | ||
return true; | return true; | ||
} | } | ||
+ | |||
+ | function doQuery($sql) { | ||
+ | if ($this->bufferResults()) $ret = sqlite_query($this->mConn, $sql, SQLITE_BOTH, $err); | ||
+ | else $ret = sqlite_unbuffered_query($this->mConn, $sql, SQLITE_BOTH, $err); | ||
+ | if ($err) $this->reportQueryError($err, 0, $sql, __FUNCTION__); | ||
+ | return $ret; | ||
+ | } | ||
+ | |||
+ | function queryIgnore($sql, $fname = '') { | ||
+ | return $this->query($sql, $fname, true); | ||
+ | } | ||
+ | |||
+ | function freeResult($res) { | ||
+ | $res->free(); | ||
+ | } | ||
+ | |||
+ | function fetchObject($res) { | ||
+ | return $res->fetchObject(); | ||
+ | } | ||
+ | |||
+ | function fetchRow($res) { | ||
+ | return $res->fetchAssoc(); | ||
+ | } | ||
+ | |||
+ | function numRows($res) { | ||
+ | return $res->numRows(); | ||
+ | } | ||
+ | |||
+ | function numFields($res) { | ||
+ | return $res->numFields(); | ||
+ | } | ||
+ | |||
+ | function fieldName($stmt, $n) { | ||
+ | return pg_field_name($stmt, $n); | ||
+ | } | ||
+ | |||
+ | # This must be called after nextSequenceVal | ||
+ | function insertId() { | ||
+ | # todo: return $this->mInsertId; ? | ||
+ | } | ||
+ | |||
+ | function dataSeek($res, $row) { | ||
+ | $res->seek($row); | ||
+ | } | ||
+ | |||
+ | function lastError() { | ||
+ | if ($this->mConn === false) $e = oci_error(); | ||
+ | else $e = oci_error($this->mConn); | ||
+ | return $e['message']; | ||
+ | } | ||
+ | |||
+ | function lastErrno() { | ||
+ | if ($this->mConn === false) $e = oci_error(); | ||
+ | else $e = oci_error($this->mConn); | ||
+ | return $e['code']; | ||
+ | } | ||
+ | |||
+ | function affectedRows() { | ||
+ | return $this->mAffectedRows; | ||
+ | } | ||
+ | |||
+ | # Returns information about an index | ||
+ | # - if errors are explicitly ignored, returns NULL on failure | ||
+ | function indexInfo($table, $index, $fname = 'Database::indexExists') { | ||
+ | # todo | ||
+ | } | ||
+ | |||
+ | function indexUnique($table, $index, $fname = 'Database::indexUnique') { | ||
+ | # todo | ||
+ | } | ||
+ | |||
+ | function insert($table, $a, $fname = 'Database::insert', $options = array()) { | ||
+ | # todo | ||
+ | } | ||
+ | |||
+ | function insertOneRow($table, $row, $fname) { | ||
+ | # todo | ||
+ | } | ||
+ | |||
+ | # SQLite does not have a "USE INDEX" clause, so return an empty string | ||
+ | function useIndexClause($index) { | ||
+ | return ''; | ||
+ | } | ||
+ | |||
+ | # REPLACE query wrapper | ||
+ | function replace($table, $uniqueIndexes, $rows, $fname = 'Database::replace') { | ||
+ | # todo | ||
+ | } | ||
+ | |||
+ | # DELETE where the condition is a join | ||
+ | function deleteJoin($delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin") { | ||
+ | # todo | ||
+ | } | ||
+ | |||
+ | # Returns the size of a text field, or -1 for "unlimited" | ||
+ | function textFieldSize($table, $field) { | ||
+ | # todo | ||
+ | } | ||
+ | |||
+ | # No low priority option in SQLite | ||
+ | function lowPriorityOption() { | ||
+ | return ''; | ||
+ | } | ||
+ | |||
+ | # Returns an SQL expression for a simple conditional. | ||
+ | # - uses CASE on SQLite | ||
+ | function conditional($cond, $trueVal, $falseVal) { | ||
+ | return " (CASE WHEN $cond THEN $trueVal ELSE $falseVal END) "; | ||
+ | } | ||
+ | |||
+ | function wasDeadlock() { | ||
+ | return $this->lastErrno() == SQLITE_BUSY; | ||
+ | } | ||
+ | |||
+ | # @return string wikitext of a link to the server software's web site | ||
+ | function getSoftwareLink() { | ||
+ | return "[http://sqlite.org/ SQLite]"; | ||
+ | } | ||
+ | |||
+ | # @return string Version information from the database | ||
+ | function getServerVersion() { | ||
+ | return sqlite_libversion($this->mConn); | ||
+ | } | ||
+ | |||
+ | # Query whether a given table exists (in the given schema, or the default mw one if not given) | ||
+ | function tableExists($table) { | ||
+ | $etable= $this->addQuotes($table); | ||
+ | $SQL = "SELECT 1 FROM user_tables WHERE table_name='$etable'"; | ||
+ | $res = $this->query($SQL); | ||
+ | $count = $res ? sqlite_num_rows($res) : 0; | ||
+ | if ($res) $this->freeResult($res); | ||
+ | return $count; | ||
+ | } | ||
+ | |||
+ | # Query whether a given column exists in the mediawiki schema | ||
+ | function fieldExists($table, $field) { return true; } | ||
+ | |||
+ | function fieldInfo($table, $field) { return false; } | ||
+ | |||
+ | function begin($fname = 'DatabasePostgres::begin') { | ||
+ | $this->query('BEGIN', $fname); | ||
+ | $this->mTrxLevel = 1; | ||
+ | } | ||
+ | |||
+ | function immediateCommit($fname = 'DatabaseSqlite::immediateCommit') { | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | function commit($fname = 'DatabaseSqlite::commit') { | ||
+ | $this->query('COMMIT', $fname); | ||
+ | $this->mTrxLevel = 0; | ||
+ | } | ||
+ | |||
+ | function limitResultForUpdate($sql, $num) { | ||
+ | return $sql; | ||
+ | } | ||
+ | |||
+ | function strencode($s) { | ||
+ | return sqlite_escape_string($s); | ||
+ | } | ||
+ | |||
+ | function encodeBlob($b) { | ||
+ | return new SQLiteBlob($b); | ||
+ | } | ||
+ | |||
+ | function decodeBlob($b) { | ||
+ | return $b; //return $b->load(); | ||
+ | } | ||
+ | |||
+ | function addQuotes($s) { | ||
+ | global $wgLang; | ||
+ | $s = $wgLang->checkTitleEncoding($s); | ||
+ | return "'".$this->strencode($s)."'"; | ||
+ | } | ||
+ | |||
+ | function quote_ident($s) { return $s; } | ||
+ | |||
+ | # For now, does nothing | ||
+ | function selectDB($db) { return true; } | ||
+ | |||
+ | /** | ||
+ | * Returns an optional USE INDEX clause to go after the table, and a | ||
+ | * string to go at the end of the query | ||
+ | * | ||
+ | * @private | ||
+ | * | ||
+ | * @param array $options an associative array of options to be turned into | ||
+ | * an SQL query, valid keys are listed in the function. | ||
+ | * @return array | ||
+ | */ | ||
+ | function makeSelectOptions($options) { | ||
+ | return array($startOpts, $useIndex, $preLimitTail, $postLimitTail); | ||
+ | } | ||
+ | |||
+ | # not done | ||
+ | public function setTimeout($timeout) { return; } | ||
+ | |||
+ | function ping() { | ||
+ | wfDebug("Function ping() not written for SQLite yet"); | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | # How lagged is this slave? | ||
+ | public function getLag() { return 0; } | ||
} | } |
Revision as of 06:57, 30 December 2007
<?php
- Extension:SQLite
Template:PhpCategory:Extensions in progress
- - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
- - Author: User:NadCategory:Extensions created with Template:Extension
if (!defined('MEDIAWIKI')) die('Not an entry point.'); if (!defined('SQLITE_OK')) die('SQLite is not installed!');
define('SQLITE_VERSION','0.0.0, 2007-12-30');
$wgDBtype = 'sqlite'; $wgSQLiteDataDir = dirname(__FILE__);
$wgExtensionCredits['other'][] = array( 'name' => 'SQLite', 'author' => 'User:Nad', 'description' => 'Allow MediaWiki installations to store content in an SQLite database instead of MySQL', 'url' => 'http://www.organicdesign.co.nz/Extension:SQLite.php', 'version' => SQLITE_VERSION );
class DatabaseSqlite extends Database {
var $mAffectedRows;
function DatabaseSqlite($server = false, $user = false, $password = false, $dbName = false, $failFunction = false, $flags = 0) { global $wgOut; # 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; $this->open($server, $user, $password, $dbName); }
function cascadingDeletes() { return true; } function cleanupTriggers() { return true; } function strictIPs() { return true; } function realTimestamps() { return true; } function implicitGroupby() { return false; } function implicitOrderby() { return false; } function searchableIPs() { return true; } function functionalIndexes() { return true; }
static function newFromParams($server, $user, $password, $dbName, $failFunction = false, $flags = 0) { return new DatabaseSqlite($server, $user, $password, $dbName, $failFunction, $flags); }
# Open an SQLite database and return a resource handle to it # NOTE: only $dbName is used, the other parameters are irrelevant for SQLite databases function open($server,$user,$password,$dbName) { global $wgSQLiteDataDir; $this->mConn = false; if ($this->mFlags & DBO_PERSISTENT) @$this->mConn = sqlite_popen("$wgSQLiteDataDir/$dbName", 0666, $err); else @$this->mConn = @$this->mConn = sqlite_open("$wgSQLiteDataDir/$dbName", 0666, $err); if ($this->mConn === false) wfDebug("DB connection error: $err\n");; $this->mOpened = $this->mConn; return $this->mConn; }
# Close an SQLite database function close() { $this->mOpened = false; if ($this->mConn) { if ($this->trxLevel()) $this->immediateCommit(); sqlite_close($this->mConn); } return true; }
function doQuery($sql) { if ($this->bufferResults()) $ret = sqlite_query($this->mConn, $sql, SQLITE_BOTH, $err); else $ret = sqlite_unbuffered_query($this->mConn, $sql, SQLITE_BOTH, $err); if ($err) $this->reportQueryError($err, 0, $sql, __FUNCTION__); return $ret; }
function queryIgnore($sql, $fname = ) { return $this->query($sql, $fname, true); }
function freeResult($res) { $res->free(); }
function fetchObject($res) { return $res->fetchObject(); }
function fetchRow($res) { return $res->fetchAssoc(); }
function numRows($res) { return $res->numRows(); }
function numFields($res) { return $res->numFields(); }
function fieldName($stmt, $n) { return pg_field_name($stmt, $n); }
# This must be called after nextSequenceVal function insertId() { # todo: return $this->mInsertId; ? }
function dataSeek($res, $row) { $res->seek($row); }
function lastError() { if ($this->mConn === false) $e = oci_error(); else $e = oci_error($this->mConn); return $e['message']; }
function lastErrno() { if ($this->mConn === false) $e = oci_error(); else $e = oci_error($this->mConn); return $e['code']; }
function affectedRows() { return $this->mAffectedRows; }
# Returns information about an index # - if errors are explicitly ignored, returns NULL on failure function indexInfo($table, $index, $fname = 'Database::indexExists') { # todo }
function indexUnique($table, $index, $fname = 'Database::indexUnique') { # todo }
function insert($table, $a, $fname = 'Database::insert', $options = array()) { # todo }
function insertOneRow($table, $row, $fname) { # todo }
# SQLite does not have a "USE INDEX" clause, so return an empty string function useIndexClause($index) { return ; }
# REPLACE query wrapper function replace($table, $uniqueIndexes, $rows, $fname = 'Database::replace') { # todo }
# DELETE where the condition is a join function deleteJoin($delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin") { # todo }
# Returns the size of a text field, or -1 for "unlimited" function textFieldSize($table, $field) { # todo }
# No low priority option in SQLite function lowPriorityOption() { return ; }
# Returns an SQL expression for a simple conditional. # - uses CASE on SQLite function conditional($cond, $trueVal, $falseVal) { return " (CASE WHEN $cond THEN $trueVal ELSE $falseVal END) "; }
function wasDeadlock() { return $this->lastErrno() == SQLITE_BUSY; }
# @return string wikitext of a link to the server software's web site function getSoftwareLink() { return "SQLite"; }
# @return string Version information from the database function getServerVersion() { return sqlite_libversion($this->mConn); }
# Query whether a given table exists (in the given schema, or the default mw one if not given) function tableExists($table) { $etable= $this->addQuotes($table); $SQL = "SELECT 1 FROM user_tables WHERE table_name='$etable'"; $res = $this->query($SQL); $count = $res ? sqlite_num_rows($res) : 0; if ($res) $this->freeResult($res); return $count; }
# Query whether a given column exists in the mediawiki schema function fieldExists($table, $field) { return true; }
function fieldInfo($table, $field) { return false; }
function begin($fname = 'DatabasePostgres::begin') { $this->query('BEGIN', $fname); $this->mTrxLevel = 1; }
function immediateCommit($fname = 'DatabaseSqlite::immediateCommit') { return true; }
function commit($fname = 'DatabaseSqlite::commit') { $this->query('COMMIT', $fname); $this->mTrxLevel = 0; }
function limitResultForUpdate($sql, $num) { return $sql; }
function strencode($s) { return sqlite_escape_string($s); }
function encodeBlob($b) { return new SQLiteBlob($b); }
function decodeBlob($b) { return $b; //return $b->load(); }
function addQuotes($s) { global $wgLang; $s = $wgLang->checkTitleEncoding($s); return "'".$this->strencode($s)."'"; }
function quote_ident($s) { return $s; }
# For now, does nothing function selectDB($db) { return true; }
/** * Returns an optional USE INDEX clause to go after the table, and a * string to go at the end of the query * * @private * * @param array $options an associative array of options to be turned into * an SQL query, valid keys are listed in the function. * @return array */ function makeSelectOptions($options) { return array($startOpts, $useIndex, $preLimitTail, $postLimitTail); }
# not done public function setTimeout($timeout) { return; }
function ping() { wfDebug("Function ping() not written for SQLite yet"); return true; }
# How lagged is this slave? public function getLag() { return 0; }
}