so, hab das ganze jetzt mal implementiert, und es scheint ziemlich prima zu funktionieren...
falls es jemand brauchen kann - hier der quelltext dazu.
PHP-Code:
<?php
/**
* a small checking class which performs some basic checks if the database fulfills the requirements.
* @package util
* @author axo ( setzen (at) neuecouch (dot) de )
* @access public
* @date 08.03.2005
* @version 1.0
*/
class DatabaseCheck {
var $_db;
var $_error = array();
var $_testResult;
var $_dummyTable;
var $_indexCreated;
var $_tableAltered;
/**
* constructor.
* nees a PEAR::DB instance to perform the queries.
*
* @param $db DB_common
* @return void
* @access public
*/
function DatabaseCheck(&$db) {
$this -> _db = & $db;
}
/**
* returns the errors as an array.
* @param void
* @return array
* @access public
*/
function getError() {
return $this -> _error;
}
/**
* @desc give this function an array of database commands you need and it returns true if all
* of them can be fulfilled and false if any cannot be fulfilled.
* implemented commands are:
* INSERT - insert new rows into tables
* DELETE - delete rows from tables
* UPDATE - update tables
* SELECT - select from tables
* CREATE - create table
* DROP - drop table
* INDEX - add or remove indexes
* ALTER - alter table
* LOCK - lock and unlock tables
*
* usage: $obj -> checkGrants(array('INSERT', 'DELETE','UPDATE'));
* @param $granted array
* @return boolean
* @access public
*/
function checkGrants($toBeGranted) {
$toBeGranted = array_map('strtoupper',array_values($toBeGranted));
if(count($toBeGranted) < 1) {
return true;
}
$implementedChecks = array(
'INSERT' => '_checkInsert',
'DELETE' => '_checkDelete',
'UPDATE' => '_checkUpdate',
'SELECT' => '_checkSelect',
'CREATE' => '_checkCreate',
'DROP' => '_checkDrop',
'INDEX' => '_checkIndex',
'ALTER' => '_checkAlterTable',
'LOCK' => '_checkLockTables',
);
$granted = array();
foreach ($toBeGranted as $g) {
if(!isset($implementedChecks[$g])) {
$this -> _error[] = $g . ' not supported!';
$granted[$g] = 0;
continue;
}
$granted[$g] = (int) call_user_func(array(&$this,$implementedChecks[$g]));
}
$this -> _checkDrop(); // drop the table from the database.
return array_reduce(array_values($granted),create_function('$a,$b','return $a * $b;'),1);
}
/**
* checks whether the LOCK TABLES command is available.
* @param void
* @return boolean
* @access private
*/
function _checkLockTables() {
return ($this -> _simpleTestQuery('LOCK TABLES {tableName} WRITE') && $this -> _simpleTestQuery('UNLOCK TABLES'));
}
/**
* performs a query and simply returns true if the query could be executed
* successfully, false if not.
* @param $sql string
* @return boolean
* @access private
*/
function _simpleTestQuery($sql) {
$tn = & $this -> _createDummyTable();
if($tn === false) {
return false;
}
$sql = strtr($sql,array('{tableName}' => $tn));
$chk = & $this -> _expectErrorQuery($sql);
return ($chk !== false);
}
/**
* checks whether the ALTER TABLE command is available.
* @param void
* @return boolean
* @access private
*/
function _checkAlterTable() {
if($this -> _tableAltered === null) {
$this -> _tableAltered = $this -> _simpleTestQuery("ALTER TABLE `{tableName}` ADD `ding` INT( 11 ) UNSIGNED NOT NULL ");
}
return $this -> _tableAltered;
}
/**
* checks whether the ALTER TABLE ... ADD INDEX and ALTER TABLE ... DROP INDEX works.
* @param void
* @return boolean
* @access private
*/
function _checkIndex() {
if($this -> _indexCreated === null) {
$this -> _indexCreated = (
$this -> _simpleTestQuery("ALTER TABLE `{tableName}` ADD INDEX ( `id` )")
&& $this -> _simpleTestQuery("ALTER TABLE `{tableName}` DROP INDEX `id`")
);
}
return $this -> _indexCreated;
}
/**
* checks whether DROP TABLE can be performed.
* @param void
* @return boolean
* @access private
*/
function _checkDrop() {
return ($this -> _simpleTestQuery("DROP TABLE {tableName}") === true && ($this -> _dummyTable = null) === null);
}
/**
* checks whether a table can be created.
* @param void
* @return boolean
* @access private
*/
function _checkCreate() {
return ($this -> _createDummyTable() !== false);
}
/**
* checks whether a SELECT statement can be performed.
* @param $value mixed
* @return boolean
* @access private
*/
function _checkSelect($value = 'b') {
$tn = & $this -> _createDummyTable();
$chk = $this -> _checkInsert($value);
if($chk === false) {
return false;
}
$sql = 'SELECT feld FROM ' . $tn . ' WHERE feld=' . $this -> _db -> quoteSmart($value);
$qry = & $this -> _expectErrorQuery($sql);
if($qry === false) {
return false;
}
/* @var $qry DB_result */
$data = & $qry -> fetchRow(DB_FETCHMODE_ASSOC);
return ($data['feld'] == $value);
}
/**
* checks for row deletion.
* @param void
* @return boolean
* @access private
*/
function _checkDelete() {
$tn = & $this -> _createDummyTable();
$chk = & $this -> _checkInsert('ding');
if($chk === false) {
return false;
}
$chk2 = $this -> _simpleTestQuery('DELETE FROM {tableName} WHERE feld=' . $this -> _db -> quoteSmart('ding'));
if($chk2 === false) {
return false;
}
$qry = & $this -> _expectErrorQuery('SELECT feld FROM ' . $tn . ' WHERE feld=' . $this -> _db -> quoteSmart('ding') );
if($qry === false) {
return false;
}
return ($qry -> numRows() < 1);
}
/**
* checks for row update.
* @param void
* @return boolean
* @access private
*/
function _checkUpdate() {
$tn = &$this -> _createDummyTable();
$chk = & $this -> _checkInsert('ding');
$sql = 'SELECT id FROM ' . $tn . ' WHERE feld=' . $this -> _db -> quoteSmart('ding');
$qry = & $this -> _expectErrorQuery($sql);
if($qry === false || $qry -> numRows() < 1) {
return false;
}
$data = & $qry -> fetchRow(DB_FETCHMODE_ASSOC);
$sql2 = 'UPDATE ' . $tn . ' SET feld=' . $this -> _db -> quoteSmart('dong') . ' WHERE id=' . (int)$data['id'];
if(!$this -> _simpleTestQuery($sql2)) {
return false;
}
$sql3 = 'SELECT feld FROM ' . $tn . ' WHERE id=' . (int) $data['id'];
$qry3 = & $this -> _expectErrorQuery($sql3);
if($qry3 === false || $qry3 -> numRows() < 1) {
return false;
}
$data = & $qry3 -> fetchRow(DB_FETCHMODE_ASSOC);
return ($data['feld'] === 'dong');
}
/**
* tries to create a dummy table.
* if the creation fails, it returns false.
* if it works, it returns the name of the dummy table.
* @param void
* @return mixed
* @access private
*/
function _createDummyTable() {
if($this -> _dummyTable !== null) {
return $this -> _dummyTable;
}
$dummyTable = 'a_table_' . time();
$sql = "CREATE TABLE `" .$dummyTable . "` (
`id` SMALLINT(3) UNSIGNED NOT NULL,
`feld` VARCHAR(32) NOT NULL
)";
$db = & $this -> _db;
/* @var $db DB_common */
$db -> expectError();
$qry = & $this -> _expectErrorQuery($sql);
if($qry === false) {
$this -> _error[] = 'table creation failed.';
$this -> _error[] = mysql_error();
$this -> _dummyTable = false;
return false;
}
$this -> _dummyTable = $dummyTable;
return $this -> _dummyTable;
}
/**
* performs a dummy insert operation into $tablename with value $value.
* @param $tableName string
* @param $value string
* @access public
* @return void
*/
function _checkInsert($value = 'a') {
return $this -> _simpleTestQuery('INSERT INTO {tableName} SET feld=' . $this -> _db -> quoteSmart($value));
}
/**
* performs a 'safe' query to the database.
* returns false if the query has failed, the query object if succeeded.
* @param $sql string
* @return mixed
* @access public
*/
function &_expectErrorQuery($sql) {
$db = & $this -> _db;
/* @var $db DB_common */
$db -> expectError();
$qry = & $db -> query($sql);
if($db -> isError($qry)) {
$db -> popExpect();
return false;
}
return $qry;
}
/**
* checks the database size.
* @param void
* @return integer
* @access public
* @TODO implement this correctly.
*/
function checkDbSize() {
$query = "SHOW TABLE STATUS FROM ". $db;
if ($result = mysql_query($query)) {
$tables = 0;
$rows = 0;
$size = 0;
while ($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
$rows += $row["Rows"];
$size += $row["Data_length"];
$size += $row["Index_length"];
$tables++;
}
}
$data[0] = $size;
$data[1] = $tables;
$data[2] = $rows;
return $data;
}
/**
* simple dumpfile parser in order to generate multiple queries.
* the dumpfile can be a file generated by phpmyadmin.
* wants the $q to be a string of multiple sql queries from a file.
* @param $dumpFileName string
* @access public
* @return string
*/
function parseDumpFile($q){
$q = preg_replace('/--(.*)/','',$q);
$n=strlen($q);
$k=0;
$queries=array();
$current_delimiter='';
for($i=0;$i<$n;$i++){
if(!isset($queries[$k])) {
$queries[$k] = '';
}
if($q[$i]=='\\' && ($q[$i+1]=='\\' || $q[$i+1]=="'" || $q[$i+1]=='"') ){
$queries[$k].=$q[$i].$q[$i+1];
$i++;
continue;
}
if($q[$i]==$current_delimiter) {
$current_delimiter='';
} elseif($q[$i]=='`' || $q[$i]=="'" || $q[$i]=='"') {
$current_delimiter=$q[$i];
}
if($q[$i]==';' && $current_delimiter==''){
$queries[$k]=trim($queries[$k]);
if(trim(substr($q,$i),"\r \n;")!='')
$k++;
} else {
$queries[$k].=$q[$i];
}
}
foreach($queries as $k => $v) {
$queries[$k] = trim($queries[$k]);
if(preg_match('/^\s*$/si',$queries[$k])) {
unset($queries[$k]);
}
}
return array_values($queries);
}
}
?>