* @copyright (cc) creative commons - attribution-shareAlike 3.0 unported
* @version 2.0
* @package qoob
* @subpackage core.data
*/
class dbException extends Exception {
/**
* constructor
* sets the error code and messag
*
* @param string $message
* @param int $code 500
*/
public function __construct($message, $code = 500) {
// -- set error message
statusCodes::setHeader($code);
$this->code = $code;
$this->message = mysql_error()."\n
\n".$this->hightlight($message);
}
/**
* formats/color the sql query for ease of reading/debugging
*
* @param string $sql
* @return string
*/
private function hightlight($sql) {
// --- remove html for debugging
$sql = strip_tags($sql);
// --- add html line breaks
$sql = nl2br($sql);
// --- hightlight symbols
$sql = preg_replace('#(\(|\)|\,|\=|\.|-|\+|\!|\@)#si', "$1", $sql);
// --- hightlight digits
$sql = preg_replace('#([0-9]+)#si', "$1", $sql);
// --- hightlight keywords
$sql = preg_replace('#(SELECT|UPDATE|INSERT|DELETE|DROP|TRUNCATE|FROM|WHERE|IN|AS|JOIN|INNER|LEFT|RIGHT|LIMIT|GROUP BY|ORDER BY|ON|HAVING|COUNT|MIN|MAX)\s#si', "$1 ", $sql);
return $sql;
}
}
class mySQL implements iDB {
/**
* @var string $dbhost the database hostname
*/
private $dbhost;
/**
* @var string $dbuser the database username
*/
private $dbuser;
/**
* @var string $dbpass the database password
*/
private $dbpass;
/**
* @var string $dbname the database name
*/
private $dbname;
/**
* @var object $db the database reference
*/
protected $db = null;
/**
* @var object $instance the singleton instance of the mySQL class
*/
protected static $instance = null;
/**
* @var string $sql the sql query
*/
protected $sql = null;
/**
* getInstance
* singleton pattern for instantiating the DB class
*
* @return mySQL
*/
public static function getInstance() {
if(!self::$instance)
{
self::$instance = new mySQL();
}
return self::$instance;
}
/**
* constructor
* calls the init and connect functions
*/
protected function __construct() {
$this->init();
$this->connect();
}
/**
* initilizer
* sets up database connection varibles from the config file
*/
public function init() {
$this->dbhost = library::catalog()->db_host;
$this->dbuser = library::catalog()->db_user;
$this->dbpass = library::catalog()->db_pass;
$this->dbname = library::catalog()->db_name;
}
/**
* connect
* creates the mySQL database connection and selects the
* appropriate table. throws a dbException on failure.
*/
public function connect() {
if(($db = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpass)) === false) {
throw new dbException("Can't connect to {$this->dbuser}@{$this->dbhost}");
}
if((@mysql_select_db($this->dbname, $db)) === false) {
throw new dbException("Can't connect to database {$this->dbname}");
}
$this->db = $db;
}
/**
* sanitizing
* simple method for injection attack protection
*
* @param string $string
* @return string
*/
public function sanitize($string) {
if(get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
return mysql_real_escape_string($string);
}
/**
* escape
* simple method for injection attack protection which
* replaces any non-ascii character with its hex code.
*
* @param string $string
* @return string
*/
public function escape($string) {
$return = '';
for($i = 0; $i < strlen($string); ++$i) {
$char = $string[$i];
$ord = ord($char);
if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126)
$return .= $char;
else
$return .= '\\x' . dechex($ord);
}
return $return;
}
/**
* SQL query function
* executes a mySQL query.
* make sure all insert, and update statements have
* the results flag set to false.
*
* @param string $statement
* @param boolean $results
* @return object|boolean
*/
public function query($statement, $results = true) {
$this->sql = $statement;
$query = new mySQLquery($statement, $this->db);
if($results) {
return $query->result();
} else {
return true;
}
}
/**
* SQL query generation function
* pass this function a stored procedure and an array of parameters
* in name values pairs to replace in the spored procedure.
*
* @param string $sp stored procedure
* @param array $args
* @return string
*/
public function makeQuery($sp, $args) {
$haystack = $sp;
foreach ($args as $key => $value) {
$needle = "&".$key."&";
$value = $this->sanitize($value);
$haystack = str_replace($needle, $value, $haystack);
}
return $haystack;
}
/**
* get insertID
* used to get the last inserted record's id
*
* @return int|string
*/
public function insertID() {
return mysql_insert_id($this->db);
}
/**
* destructor
* close the connection when finished
*/
public function __destruct() {
@mysql_close($this->db);
}
}
class mySQLquery {
protected $result;
private $link = null;
/**
* constructor
* gets the results of the mySQL query
* or throws a dbException error.
*
* @param string $query
* @param object $link mysql_connection
*/
public function __construct($query, $link) {
$this->link = $link;
if(($this->result = @mysql_query($query, $link)) === false) {
throw new dbException($query, statusCodes::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* get result
* returns the results of the mySQL query
*
* @return array
*/
public function result() {
$result = array();
//while ($row = @mysql_fetch_assoc($this->result)) {
while (($row = @mysql_fetch_assoc($this->result)) != false) {
$result[] = $row;
}
return $result;
}
/**
* number of rows
* returns the number of rows in a given result
*
* @return int
*/
public function num_rows() {
return @mysql_num_rows($this->link);
}
/**
* destructor
* call's free result only if result has be used
*/
public function __destruct() {
if(is_array($this->result)) {
@mysql_free_result($this->result);
}
}
}
?>