631 lines
12 KiB
PHP
631 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* KatharsisDb5 is a mysql query class, that is based on native php functionality (PHP5)
|
|
*
|
|
* @author Karl Pannek
|
|
*/
|
|
class Katharsis_Db5
|
|
{
|
|
const FETCHMODE_ASSOC = 'ASSOC';
|
|
const FETCHMODE_ARRAY = 'ARRAY';
|
|
|
|
/**
|
|
* @var Mysql Resource
|
|
*/
|
|
private $_connection = null;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $_host = null;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $_user = null;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $_password = null;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $_database = null;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $_lastStatement = "";
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $_lastResult = array();
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $_lastError = array();
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
private $_lastRowCount = 0;
|
|
|
|
/**
|
|
* Create a connection
|
|
*
|
|
* @param $host
|
|
* @param $user
|
|
* @param $password
|
|
* @param $database
|
|
*
|
|
* @return KatharsisDbConnector
|
|
*/
|
|
public function __construct($host = null, $user = null, $password = null, $database = null)
|
|
{
|
|
$this->setHost($host);
|
|
$this->setUser($user);
|
|
$this->setPassword($password);
|
|
$this->setDatabase($database);
|
|
|
|
if($host !== null && $user !== null && $password !== null && $database !== null)
|
|
{
|
|
$this->connect();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the value of $_host
|
|
*
|
|
* @param string $host
|
|
* @author Karl Pannek
|
|
*/
|
|
public function setHost($value)
|
|
{
|
|
$this->_host = $value;
|
|
}
|
|
|
|
/**
|
|
* Sets the value of $_user
|
|
*
|
|
* @param string $user
|
|
* @author Karl Pannek
|
|
*/
|
|
public function setUser($value)
|
|
{
|
|
$this->_user = $value;
|
|
}
|
|
|
|
/**
|
|
* Sets the value of $_password
|
|
*
|
|
* @param string $password
|
|
* @author Karl Pannek
|
|
*/
|
|
public function setPassword($value)
|
|
{
|
|
$this->_password = $value;
|
|
}
|
|
|
|
/**
|
|
* Sets the value of $_database
|
|
*
|
|
* @param string $database
|
|
* @author Karl Pannek
|
|
*/
|
|
public function setDatabase($value)
|
|
{
|
|
$this->_database = $value;
|
|
// $this->_selectDatabase();
|
|
}
|
|
|
|
/**
|
|
* Returns the value of $_host
|
|
*
|
|
* @return string
|
|
* @author Karl Pannek
|
|
*/
|
|
public function getHost()
|
|
{
|
|
return $this->_host;
|
|
}
|
|
|
|
/**
|
|
* Returns the value of $_user
|
|
*
|
|
* @return string
|
|
* @author Karl Pannek
|
|
*/
|
|
public function getUser()
|
|
{
|
|
return $this->_user;
|
|
}
|
|
|
|
/**
|
|
* Returns the value of $_password
|
|
*
|
|
* @return string
|
|
* @author Karl Pannek
|
|
*/
|
|
public function getPassword()
|
|
{
|
|
return $this->_password;
|
|
}
|
|
|
|
/**
|
|
* Returns the value of $_database
|
|
*
|
|
* @return string
|
|
* @author Karl Pannek
|
|
*/
|
|
public function getDatabase()
|
|
{
|
|
return $this->_database;
|
|
}
|
|
|
|
/**
|
|
* Connect to database
|
|
*
|
|
*
|
|
* @return void
|
|
*/
|
|
public function connect()
|
|
{
|
|
$this->_connection = mysqli_connect(
|
|
$this->getHost(),
|
|
$this->getUser(),
|
|
$this->getPassword(),
|
|
$this->getDatabase()
|
|
);
|
|
|
|
if(!$this->_connection)
|
|
{
|
|
throw new KatharsisDb5_Exception('Could not connect to "' . $this->getHost() . '" with user "' . $this->getUser() . '".');
|
|
}
|
|
|
|
// $this->_selectDatabase();
|
|
}
|
|
|
|
/**
|
|
* Disconnect database connection
|
|
* @return bool
|
|
*/
|
|
public function disconnect()
|
|
{
|
|
$this->_connection = null;
|
|
return (bool) mysqli_close($this->_connection);
|
|
}
|
|
|
|
/**
|
|
* Checks connection to database
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isConnected()
|
|
{
|
|
if($this->_connection !== null && $this->_connection !== false)
|
|
{
|
|
return true;
|
|
} else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns mysql connection link resource
|
|
*
|
|
* @return mysql link resource
|
|
*/
|
|
public function getMysqlResource ()
|
|
{
|
|
return $this->_connection;
|
|
}
|
|
|
|
/**
|
|
* Executes a Sql statement
|
|
*
|
|
* @param $statement
|
|
* @return bool
|
|
*/
|
|
public function run ($statement)
|
|
{
|
|
if($this->_execute($statement))
|
|
{
|
|
return true;
|
|
} else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns Result set for incremental fetching
|
|
*
|
|
* @param $statement
|
|
* @return KatharsisDb5_ResultSet
|
|
*/
|
|
public function runForIncrementalFetch ($statement)
|
|
{
|
|
$resultSet = $this->_execute($statement);
|
|
return new KatharsisDb5_ResultSet($resultSet);
|
|
}
|
|
|
|
/**
|
|
* Inserts a row into a specified table
|
|
*
|
|
* @param $table
|
|
* @param $values
|
|
* @return bool
|
|
*/
|
|
public function insert ($table, $values = array())
|
|
{
|
|
$sets = array();
|
|
|
|
foreach($values as $key => $value)
|
|
{
|
|
if(is_string($value))
|
|
{
|
|
$value = "'" . mysqli_real_escape_string($this->_connection, $value) . "'";
|
|
}
|
|
if($value === null)
|
|
{
|
|
$value = 'NULL';
|
|
}
|
|
$sets[] = "`" . $key . "` = " . $value;
|
|
}
|
|
|
|
$sql = 'INSERT INTO ' . $table;
|
|
|
|
if($values !== array())
|
|
{
|
|
$sql .= ' SET ' . implode(',', $sets);
|
|
} else
|
|
{
|
|
$sql .= ' () VALUES () ';
|
|
}
|
|
|
|
return $this->run($sql);
|
|
}
|
|
|
|
public function simpleDelete($table, $fieldvalue, $fieldname = 'id')
|
|
{
|
|
$sql = "DELETE FROM " . $table . " WHERE " . $fieldname . " = :field";
|
|
$sql = $this->createStatement($sql, array('field' => $fieldvalue));
|
|
return $this->run($sql);
|
|
}
|
|
|
|
/**
|
|
* Executes Query and returns number of rows
|
|
*
|
|
* @param $statement
|
|
* @return int
|
|
*/
|
|
public function count ($statement)
|
|
{
|
|
$result = $this->_execute($statement);
|
|
$this->_lastRowCount = mysqli_num_rows($result);
|
|
return $this->_lastRowCount;
|
|
}
|
|
|
|
/**
|
|
* Returns a fetched result set (All rows)
|
|
*
|
|
* @param $statement
|
|
* @param $fetchmode
|
|
* @return array
|
|
*/
|
|
public function fetchAll($statement, $fetchmode = self::FETCHMODE_ASSOC)
|
|
{
|
|
return $this->_fetch($statement, $fetchmode, false);
|
|
}
|
|
|
|
/**
|
|
* Returns a fetched result (One rows)
|
|
*
|
|
* @param $statement
|
|
* @param $fetchmode
|
|
* @return array
|
|
*/
|
|
public function fetchOne($statement, $fetchmode = self::FETCHMODE_ASSOC)
|
|
{
|
|
return $this->_fetch($statement, $fetchmode, true);
|
|
}
|
|
|
|
/**
|
|
* Returns a fetched result (One rows)
|
|
*
|
|
* @param $statement
|
|
* @param $fetchmode
|
|
* @return array
|
|
*/
|
|
public function fetchField ($statement, $field = 0)
|
|
{
|
|
if(intval($field) === $field)
|
|
{
|
|
$result = $this->_fetch($statement, self::FETCHMODE_ARRAY, true);
|
|
} else
|
|
{
|
|
$result = $this->_fetch($statement, self::FETCHMODE_ASSOC, true);
|
|
}
|
|
|
|
return array_key_exists($field, $result) ? $result[$field] : null;
|
|
}
|
|
|
|
/**
|
|
* Prints out details of the last query (Html formatted)
|
|
*
|
|
* @return void
|
|
*/
|
|
public function analyseLast ()
|
|
{
|
|
$debug = debug_backtrace();
|
|
$file = explode("/", str_replace("\\", "/", $debug[0]['file']));
|
|
$file = $file[count($file)-1];
|
|
|
|
|
|
echo '<pre style="position: absolute; z-index: 10000; margin: 10px; padding: 0px; background-color: #eee">';
|
|
|
|
echo '<table style="width: 1100px"><tr><td style="font-size: 0.9em; padding-left: 10px; color: #aaa;">QUERY ANALYSIS | from ' . $file . ' on line ' . $debug[0]['line'] . '</td>';
|
|
echo '<td align="right" style="padding: 5px;">';
|
|
echo '<button style="background-color: #ddd; border: 0px solid #bbb;" onclick="parentNode.parentNode.parentNode.parentNode.parentNode.style.display=\'none\';">X</button></td></tr></table>';
|
|
echo '<div style="margin: 1px; background-color: #FFFCE6; padding: 5px; color: #3F0808;">';
|
|
echo '<b>Statement:</b><br/>';
|
|
echo '<p style="margin-left: 15px;">';
|
|
print_r((string) $this->_lastStatement);
|
|
echo '</p>';
|
|
echo '</div>';
|
|
|
|
echo '<div style="margin: 1px; background-color: #EFFFEF;padding: 5px; color: #3F0808;">';
|
|
echo '<b>Result:</b><br/>';
|
|
echo '<p style="margin-left: 15px;">';
|
|
print_r($this->_lastResult);
|
|
echo '</p>';
|
|
echo '</div>';
|
|
|
|
if($this->_lastError)
|
|
{
|
|
echo '<div style="margin: 1px; background-color: #FFEEEE; padding: 5px; color: #3F0808;">';
|
|
echo '<b>Error:</b><br/>';
|
|
echo '<p style="margin-left: 15px;">';
|
|
echo '<table>';
|
|
echo '<tr><td><b>Number:</b></td><td>' . $this->_lastError['number'] . '</td></tr>';
|
|
echo '<tr><td style="vertical-align:top;"><b>Message:</b></td><td>' . $this->_lastError['message'] . '</td></tr>';
|
|
echo '</table>';
|
|
echo '</p>';
|
|
echo '</div>';
|
|
}
|
|
echo '</pre>';
|
|
}
|
|
|
|
/**
|
|
* Prepares a statement with certain values
|
|
*
|
|
* @param $statement
|
|
* @param $values
|
|
* @return string
|
|
*/
|
|
public function createStatement ($statement, $values = array())
|
|
{
|
|
foreach($values as $key => $value)
|
|
{
|
|
if($value === null)
|
|
{
|
|
$statement = str_replace(":" . $key, 'NULL', $statement);
|
|
continue;
|
|
}
|
|
|
|
$wasString = false;
|
|
if(is_string($value))
|
|
{
|
|
$wasString = true;
|
|
}
|
|
|
|
if($this->_connection !== null)
|
|
{
|
|
$value = mysqli_real_escape_string($this->_connection, $value);
|
|
} else
|
|
{
|
|
$value = mysqli_escape_string($this->_connection, $value);
|
|
}
|
|
|
|
// if string, or a integer, but wanting to request via LIKE
|
|
if($wasString || preg_match('~%' . $key . '|' . $key . '%~', $statement))
|
|
{
|
|
$statement = preg_replace('~\:(%*)' . $key . '(%*)~', "'" . '${1}' . (string) $value . '${2}' . "'", $statement);
|
|
} else
|
|
{
|
|
$statement = str_replace(":" . $key, $value, $statement);
|
|
}
|
|
}
|
|
|
|
return $statement;
|
|
}
|
|
|
|
public function getEmptyColumnArray($table)
|
|
{
|
|
$sql = $this->createStatement("SHOW COLUMNS FROM " . $table);
|
|
$columns = $this->fetchAll($sql);
|
|
$result = array();
|
|
foreach($columns as $column)
|
|
{
|
|
$result[$column['Field']] = $column['Default'];
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Last primary key that has been inserted
|
|
*
|
|
* @return int
|
|
*/
|
|
public function lastInsertId ()
|
|
{
|
|
return mysqli_insert_id($this->_connection);
|
|
}
|
|
|
|
/**
|
|
* Returns the number of rows fro m the last executed statement
|
|
*
|
|
* @return int
|
|
*/
|
|
public function lastRowCount ()
|
|
{
|
|
return $this->_lastRowCount;
|
|
}
|
|
|
|
/**
|
|
* Select a database for usage
|
|
*
|
|
* @return void
|
|
* @throws KatharsisDb5_Exception
|
|
*/
|
|
protected function _selectDatabase()
|
|
{
|
|
if($this->isConnected() && $this->getDatabase() !== null)
|
|
{
|
|
if(!mysqli_select_db($this->getDatabase(), $this->_connection))
|
|
{
|
|
throw new KatharsisDb5_Exception('Could not select database "' . $this->getDatabase() . '".');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Executes Sql statement
|
|
*
|
|
* @param $statement
|
|
* @return mysql resource
|
|
*/
|
|
protected function _execute($statement)
|
|
{
|
|
if(!$this->isConnected())
|
|
{
|
|
throw new KatharsisDb5_Exception("Not connected to database.");
|
|
}
|
|
if($result = mysqli_query($this->_connection, $statement))
|
|
{
|
|
$this->_lastRowCount = mysqli_affected_rows($this->_connection);
|
|
}
|
|
$this->_lastStatement = $statement;
|
|
|
|
if(mysqli_error($this->_connection))
|
|
{
|
|
$this->_lastError['number'] = mysqli_errno($this->_connection);
|
|
$this->_lastError['message'] = mysqli_error($this->_connection);
|
|
$this->analyseLast();
|
|
} else
|
|
{
|
|
$this->_lastError = array();
|
|
$this->_lastResult = " ";
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Fetches database result
|
|
*
|
|
* @param $statement
|
|
* @param $fetchmode
|
|
* @param $fetchOne
|
|
* @return array
|
|
*/
|
|
protected function _fetch($statement, $fetchmode = self::FETCHMODE_ASSOC, $fetchOne = false)
|
|
{
|
|
$result = $this->_execute($statement);
|
|
|
|
if(!$result)
|
|
{
|
|
$this->_lastResult = array();
|
|
return array();
|
|
}
|
|
|
|
$fetchedResult = array();
|
|
|
|
switch($fetchmode)
|
|
{
|
|
case self::FETCHMODE_ASSOC:
|
|
while($row = mysqli_fetch_assoc($result))
|
|
{
|
|
if($fetchOne)
|
|
{
|
|
$fetchedResult = $row;
|
|
break;
|
|
} else
|
|
{
|
|
$fetchedResult[] = $row;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case self::FETCHMODE_ARRAY:
|
|
while($row = mysqli_fetch_row($result))
|
|
{
|
|
if($fetchOne)
|
|
{
|
|
$fetchedResult = $row;
|
|
break;
|
|
} else
|
|
{
|
|
$fetchedResult[] = $row;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
throw new KatharsisDb5_Exception('Wrong Fetchmode');
|
|
break;
|
|
}
|
|
|
|
$this->_lastResult = $fetchedResult;
|
|
|
|
return $fetchedResult;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* KatharsisDb exception spicification
|
|
*
|
|
* @author Karl Pannek
|
|
*/
|
|
class KatharsisDb5_Exception extends Exception {}
|
|
|
|
/**
|
|
* KatharsisDb Result Set
|
|
*
|
|
* @author Karl Pannek
|
|
*/
|
|
class KatharsisDb5_ResultSet
|
|
{
|
|
private $_resultSet;
|
|
private $_connection;
|
|
|
|
public function __construct($resultSet)
|
|
{
|
|
$this->_resultSet = $resultSet;
|
|
}
|
|
|
|
public function fetchNext ($fetchmode = Katharsis_Db5::FETCHMODE_ASSOC)
|
|
{
|
|
switch ($fetchmode)
|
|
{
|
|
case Katharsis_Db5::FETCHMODE_ASSOC:
|
|
return mysqli_fetch_assoc($this->_resultSet);
|
|
break;
|
|
|
|
case Katharsis_Db5::FETCHMODE_ARRAY:
|
|
return mysqli_fetch_row($this->_resultSet);
|
|
break;
|
|
|
|
default:
|
|
throw new KatharsisDb5_Exception('Wrong Fetchmode');
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
?>
|