<?php
/**
* DataBase abstraction class. This class is taken from {@link http://snk.area.lt/}.
* See class website for it's documentation and overview.
*
* @package tv2-engine
* @author Algirdas M. (hide@address.com)
* @copyright 20022003 Algirdas M.
* @version $Id: cdb.class.php,v 1.5 2003/07/05 09:46:53 lunaticlt Exp $
* @class Cdb
*/
/*
$Id: cdb.class.php,v 1.5 2003/07/05 09:46:53 lunaticlt Exp $
===================================================================
Compact database abstraction class
-------------------------------------------------------------------
Methods:
getOne()
getRow()
getAll()
getCol()
getLastQuery()
affectedRows()
nextId()
setDebugMode()
setFetchMode()
setErrorHandling()
setSequenceTable()
query(),
insert(),
update(),
limitQuery() ->
numRows()
numCols()
fetchInto()
fetchRow()
fetchingLastRow()
free()
-------------------------------------------------------------------
Example:
$db_config = array(
'username' => 'root',
'password' => 'root_',
'database' => 'db',
'host' => 'localhost',
'err_func' => array('g_error', 'handleError'),
'db_type' => CDB_MYSQL // or CDB_PGSQL
);
class err
{
function err() {}
function handleError($err)
{
echo $err;
}
}
$g_error =& new err;
$db =& new cdb();
$db->connect($db_config);
$result = $db->query('SELECT * FROM table');
while ($result->fetchInto($row))
{
echo $row['id'].'. '.$row['name'].'<br>';
}
-------------------------------------------------------------------
Author: Algirdas M. < hide@address.com >
Website: http://develop.kryptis.lt/snk/
===================================================================
*/
define('CDB_MYSQL', 'Mysql');
define('CDB_PGSQL', 'Pgsql');
define('CDB_FETCH_ASSOC', 1);
define('CDB_FETCH_NUM', 2);
define('CDB_FETCH_BOTH', 3);
define('CDB_FETCH_OBJECT', 4);
class cdb
{
function cdb() {}
function &connect($config)
{
isset($config['persistent']) || $config['persistent'] = false;
isset($config['username']) || $config['username'] = '';
isset($config['password']) || $config['password'] = '';
isset($config['database']) || $config['database'] = '';
isset($config['db_type']) || $config['db_type'] = CDB_MYSQL;
isset($config['host']) || $config['host'] = '';
isset($config['fetch_mode']) || $config['fetch_mode'] = CDB_FETCH_BOTH;
isset($config['seq_table']) || $config['seq_table'] = '_sequences';
isset($config['debug']) || $config['debug'] = false;
isset($config['err_func']) || $config['err_func'] = false;
$class = 'db'.$config['db_type'];
$this = new $class($config);
$this->connect();
}
}
class dbh
{
function dbh($config)
{
$this->host = $config['host'];
$this->cnt_db = $config['database'];
$this->username = $config['username'];
$this->password = $config['password'];
$this->persistent = $config['persistent'];
$this->seq_table = $this->_getTableName($config['seq_table']);
$this->setFetchMode($config['fetch_mode']);
$this->setDebugMode($config['debug']);
$this->setErrorHandling($config['err_func']);
}
function nextId($table)
{
return $this->_nextId($table);
}
function &query($sql)
{
if ($this->_isSelectQuery($sql))
{
return new dbResult($this, $this->_query($sql));
}
else
{
return $this->_query($sql);
}
}
function &limitQuery($sql, $from, $count)
{
$sql = $this->_buildLimitQuery($sql, $from, $count);
return $this->query($sql);
}
function &getOne($sql)
{
$result = $this->_query($sql);
$return = $this->_fetch($result, CDB_FETCH_NUM);
$this->_free($result);
return $return[0];
}
function &getRow($sql, $fetch = '')
{
$result = $this->_query($sql);
$return = $this->_fetch($result, $fetch);
$this->_free($result);
return $return;
}
function &getAll($sql, $fetch = '')
{
$result = $this->_query($sql);
$return = array();
$number = 0;
while ($row = $this->_fetch($result, $fetch, $number))
{
$return[] = $row;
$number++;
}
$this->_free($result);
return $return;
}
function &getCol($sql)
{
$result = $this->_query($sql);
$return = array();
$number = 0;
while ($row = $this->_fetch($result, CDB_FETCH_NUM, $number))
{
$return[] = $row[0];
$number++;
}
$this->_free($result);
return $return;
}
function &insert($table, $values)
{
$keys = array_keys($values);
$size = sizeOf($keys);
for ($i = 0; $i < $size; $i++)
{
if (preg_match('/[^\\\\]\'/', $values[$keys[$i]]))
{
$values[$keys[$i]] = addcslashes($values[$keys[$i]], "'");
}
}
return $this->_query('INSERT INTO '.$table.' ('.implode(', ', array_keys($values)).') VALUES (\''.implode('\', \'', array_values($values)).'\')');
}
function &update($table, $values, $condition = '')
{
$array = array();
$keys = array_keys($values);
$vals = array();
$size = sizeOf($keys);
for ($i = 0; $i < $size; $i++)
{
if (preg_match('/[^\\\\]\'/', $values[$keys[$i]]))
{
$values[$keys[$i]] = addcslashes($values[$keys[$i]], "'");
}
$array[] = $keys[$i].'=\''.$values[$keys[$i]].'\'';
}
$sql = 'UPDATE '.$table.' SET '.implode(', ', $array);
$sql .= !empty($condition) ? ' WHERE '.ereg_replace('\"', '\'', $condition) : '';
return $this->_query($sql);
}
function lastInsertId()
{
return $this->_lastInsertId();
}
function getLastQuery()
{
return $this->last_query;
}
function affectedRows()
{
if (!$this->_isSelectQuery($this->last_query))
{
return $this->_affectedRows();
}
return 0;
}
function setErrorHandling($params = '')
{
if (is_array($params) && @method_exists($GLOBALS[$params[0]], $params[1]))
{
$this->_err_func = array(&$GLOBALS[$params[0]], $params[1]);
}
elseif (@function_exists($params))
{
$this->_err_func = $params;
}
else
{
$this->_err_func = false;
}
}
function setDebugMode($mode)
{
$this->debug = true != (bool) $mode ? false : true;
}
function setSeqenceTable($tbl_name)
{
$this->seq_table = $this->_getTableName($tbl_name);
}
function setFetchMode($fetch_mode)
{
$fetch_mode = (int) $fetch_mode;
$this->fetch_mode = in_array($fetch_mode, array(1, 2, 3, 4))
? $fetch_mode : CDB_FETCH_BOTH;
}
function _getTableName($name)
{
return preg_replace('/[^0-9a-zA-Z_-]/', '', $name);
}
function _isSelectQuery($query)
{
return preg_match('/^\s*SELECT/i', $query);
}
function _setError($err, $errno = '', $die = false)
{
if (isset($this->no_show_errors))
{
$this->cnt_errno[0] = $errno;
$this->cnt_errno[1] = $err;
}
else
{
$query = $this->getLastQuery();
$err_msg = get_class($this).': '.$err.(!empty($errno) ? ' ['.$errno.']' : '');
$err_msg.= !empty($query) ? '. Last query: '.$query.'.' : '';
if (false != $this->_err_func)
{
call_user_func($this->_err_func, $err_msg);
}
else
{
echo $err_msg.'<br>'."\n";
}
if (false != $die)
{
die();
}
}
}
}
class dbResult
{
var $db = null;
var $result = null;
var $cnt_row = 0;
function dbResult(&$db, $result)
{
$this->db =& $db;
$this->result = $result;
}
function numRows()
{
return $this->db->_numRows($this->result);
}
function numCols()
{
return $this->db->_numCols($this->result);
}
function fetchInto(&$arr, $num = null)
{
if (null !== $num)
{
$this->cnt_row = $num;
$seek = true;
}
else
{
$seek = false;
}
if ($arr = $this->db->_fetch($this->result, '', $this->cnt_row, $seek))
{
$this->cnt_row++;
return true;
}
$this->cnt_row = 0;
return false;
}
function fetchRow($num = null)
{
if (null !== $num)
{
$this->cnt_row = $num;
$seek = true;
}
else
{
$seek = false;
}
if ($row = $this->db->_fetch($this->result, '', $this->cnt_row, $seek))
{
$this->cnt_row++;
return $row;
}
$this->cnt_row = 0;
return false;
}
function fetchingLastRow()
{
return $this->cnt_row == $this->numRows() ? true : false;
}
function free()
{
$this->db->_free($this->result);
}
}
class dbMysql extends dbh
{
var $conn;
var $cnt_db;
var $fetch_mode;
var $last_query = '';
var $_no_such_table = 1146;
function dbMysql($config)
{
$this->dbh($config);
}
function connect()
{
$func = true != (bool) $this->persistent ? 'mysql_connect' : 'mysql_pconnect';
$this->conn = @$func($this->host, $this->username, $this->password)
or $this->_setError(@mysql_error(), @mysql_errno(), 1);
unset($this->password);
@mysql_select_db($this->cnt_db, $this->conn)
or $this->_setError(@mysql_error($this->conn), @mysql_errno($this->conn), 1);
}
function disconnect()
{
@mysql_close($this->conn);
unset($this->conn);
}
function &_query($sql)
{
if ($this->debug) $this->query_list[] = $sql;
$this->last_query = $sql;
@mysql_select_db($this->cnt_db, $this->conn)
or $this->_setError(@mysql_error($this->conn), @mysql_errno($this->conn), 1);
$return = @mysql_query($sql, $this->conn)
or $this->_setError(@mysql_error($this->conn), @mysql_errno($this->conn));
return $return;
}
function _fetch($result, $fetch = '', $num = 0, $seek = false)
{
!empty($fetch) || $fetch = $this->fetch_mode;
if (false != $seek)
{
@mysql_data_seek($result, $num);
}
$return = null;
switch ($fetch)
{
case CDB_FETCH_OBJECT:
$return = @mysql_fetch_object($result);
break;
case CDB_FETCH_ASSOC:
$return = @mysql_fetch_array($result, MYSQL_ASSOC);
break;
case CDB_FETCH_NUM:
$return = @mysql_fetch_array($result, MYSQL_NUM);
break;
case CDB_FETCH_BOTH:
$return = @mysql_fetch_array($result, MYSQL_BOTH);
break;
}
return $return;
}
function _nextId($table)
{
$this->no_show_errors = 1;
$table = $this->_getTableName($table);
$this->_query('UPDATE `'.$this->seq_table.'` SET last_id = last_id + 1 WHERE table_name = "'.$table.'"');
unset($this->no_show_errors);
if (isset($this->cnt_errno[0]) && $this->cnt_errno[0] == $this->_no_such_table)
{
$this->_query('CREATE TABLE `'.$this->seq_table.'` (last_id INT UNSIGNED NOT NULL, table_name TINYTEXT NOT NULL)');
$this->_query('INSERT INTO `'.$this->seq_table.'` VALUES (1, "'.$table.'")');
unset($this->cnt_errno);
return 1;
}
else if (0 == $this->_affectedRows())
{
$this->_query('INSERT INTO `'.$this->seq_table.'` VALUES (1, "'.$table.'")');
return 1;
}
else
{
return $this->getOne('SELECT last_id FROM `'.$this->seq_table.'` WHERE table_name = "'.$table.'"');
}
}
function _numRows($result)
{
return @mysql_num_rows($result);
}
function _numCols($result)
{
return @mysql_num_fields($result);
}
function _affectedRows()
{
return @mysql_affected_rows($this->conn);
}
function _free($result)
{
@mysql_free_result($result);
}
function _lastInsertId()
{
return mysql_insert_id($this->conn);
}
function _buildLimitQuery($sql, $from, $count)
{
return $sql.' LIMIT '.$from.', '.$count;
}
}
class dbPgsql extends dbh
{
var $conn;
var $cnt_db;
var $fetch_mode;
var $last_query = '';
var $affected_rows = '';
function dbPgsql($config)
{
$this->dbh($config);
}
function connect()
{
$func = true != (bool) $this->persistent ? 'pg_connect' : 'pg_pconnect';
$conn_str = '';
$conn_str .= !empty($this->host) ? ' host='.$this->host : '';
$conn_str .= !empty($this->cnt_db) ? ' dbname='.$this->cnt_db : '';
$conn_str .= !empty($this->username) ? ' user='.$this->username : '';
$conn_str .= !empty($this->password) ? ' password='.$this->password : '';
ob_start();
$this->conn = $func($conn_str);
$error = ob_get_contents();
ob_end_clean();
$this->conn || $this->_setError(strip_tags($error), '', 1);
unset($this->password);
}
function disconnect()
{
@pg_close($this->conn);
unset($this->conn);
}
function &_query($sql)
{
if ($this->debug) $this->query_list[] = $sql;
$this->last_query = $sql;
$return = @pg_exec($this->conn, $sql)
or $this->_setError(@pg_errormessage($this->conn), '');
$this->affected_rows = @pg_cmdtuples($return);
return $return;
}
function _fetch($result, $fetch = '', $num = 0, $seek = false)
{
!empty($fetch) || $fetch = $this->fetch_mode;
$return = null;
switch ($fetch)
{
case CDB_FETCH_OBJECT:
$return = @pg_fetch_object($result, $num);
break;
case CDB_FETCH_ASSOC:
$return = @pg_fetch_array($result, $num, PGSQL_ASSOC);
break;
case CDB_FETCH_NUM:
$return = @pg_fetch_array($result, $num, PGSQL_NUM);
break;
case CDB_FETCH_BOTH:
$return = @pg_fetch_array($result, $num, PGSQL_BOTH);
break;
}
return $return;
}
function _nextId($table)
{
$this->no_show_errors = 1;
$table = $this->_getTableName($table);
$return = $this->getOne('SELECT NEXTVAL(\''.$table.'_seq\')');
unset($this->no_show_errors);
if (isset($this->cnt_errno[1]) && (preg_match('/class [\'"]'.$table.'_seq[\'"] not found/i', $this->cnt_errno[1]) || preg_match('/Relation [\'"]'.$table.'_seq[\'"] does not exist/i', $this->cnt_errno[1])))
{
$this->_query('CREATE SEQUENCE '.$table.'_seq START 1');
$return = $this->getOne('SELECT NEXTVAL(\''.$table.'_seq\')');
unset($this->cnt_errno);
}
return $return;
}
function _numRows($result)
{
return @pg_numrows($result);
}
function _numCols($result)
{
return @pg_numfields($result);
}
function _affectedRows()
{
return $this->affected_rows;
}
function _free($result)
{
@pg_freeresult($result);
}
function _lastInsertId()
{
return null;
}
function _buildLimitQuery($sql, $from, $count)
{
return $sql.' LIMIT '.$count.' OFFSET '.$from;
}
}
?>