<?php
class Database {

	var $linkID;
	var $debug;

	function Database($debug = FALSE)
	{
		$this->debug = $debug;
		$this->linkID = FALSE;
	}

	function connect($host, $username, $password, $database = '')
	{
		$this->linkID = mysql_connect($host, $username, $password);
		if (!$this->linkID) {
			return $this->debug();
		}

		if (!empty($database)) {
			if (!mysql_select_db($database, $this->linkID)) {
				return $this->debug();
			}
		}

		return TRUE;
	}

	function close()
	{
		if ($this->linkID)
			mysql_close($this->linkID);
	}

	function debug($msg = '')
	{
		if ($this->debug) {
			if ($msg != '')
				error_log($msg);
			else
				error_log(mysql_error());
		}

		return FALSE;
	}

	function query($sql)
	{
		if (!$this->linkID)
			return FALSE;

		$result = mysql_query($sql, $this->linkID);
		if (!$result) {
			return $this->debug(mysql_error().$sql);
		}
		return $result;
	}

	function fetchRow($result)
	{
		return mysql_fetch_assoc($result);
	}

	function getString($sql)
	{
		$result = $this->query($sql);
		if ($result) {
			$numRows = mysql_num_rows($result);
			if ($numRows == 1) {
				$arr = mysql_fetch_array($result);
				if ($arr) {
					return $arr[0];
				}
			} else if ($numRows > 1) {
				return $this->debug("ERROR getString: results more than ONE row: $numRows, sql: $sql");
			} else if ($numRows == 0) {
				return FALSE;
			}
		}
		return FALSE;
	}

	function getNumber($sql)
	{
		$ret = $this->getString($sql);
		if ($ret !== FALSE && $ret !== null) {
			if (is_numeric($ret)) {
				return $ret;
			} else {
				$this->debug("ERROR getNumber: not a number: $ret, sql: $sql");
				return 0;
			}
		}
		return 0;
	}

	function getRecord($sql)
	{
		$result = $this->query($sql);
		if ($result) {
			$numRows = mysql_num_rows($result);
			if ($numRows == 1)
				return mysql_fetch_assoc($result);
			else if ($numRows > 1)
				return $this->debug("ERROR getRecord: results more than ONE row: $numRows, sql: $sql");
			else if ($numRows == 0)
				return FALSE;
		}

		return FALSE;
	}

	function getRecords($sql)
	{
		$result = $this->query($sql);
		if ($result && mysql_num_rows($result) > 0) {
			$all = array();

			while ($arr = mysql_fetch_assoc($result))
				$all[] = $arr;

			return $all;
		} else {
			return FALSE;
		}
	}

	function getRecordsByPage($page, $pageSize, $sql)
	{
		if (!$pageSize) {
			return $this->debug("ERROR getRecordsByPage: pageSize = 0");
		}

		if (preg_match("/GROUP\sBY\s.*\sHAVING\s/i", $sql, $arr)) {
			$result = $this->query($sql);
			$total = mysql_num_rows($result);
			mysql_free_result($result);
		} else {
			if (preg_match("/group\sby\s?([^\s$]+)/i", $sql, $arr)) {
				$countsql = "SELECT COUNT(DISTINCT({$arr[1]})) ";
			} else {
				$countsql = "SELECT COUNT(*) ";
			}
			if (preg_match("/[)\s]+(from\s.*)/i", $sql, $arr)) {
				$countsql .= preg_replace("/(group\sby\s.*)/i", "", $arr[1]);
			} else {
				$this->debug("ERROR: getRecordsByPage: can not find 'FROM' clause");
				return FALSE;
			}
			$total = $this->getNumber($countsql);
		}
		if ($total == 0)
			return FALSE;

		$pageCount = ceil($total / $pageSize);
		$page = ($page > $pageCount) ? $pageCount : (($page > 0) ? $page : 1);

		$from = ($page - 1) * $pageSize;
		$sql .= " LIMIT $from,$pageSize";

		$data = $this->getRecords($sql);
		if (!$data)
			return FALSE;

		$arr = array(
				"page" => $page,
				"pageSize" => $pageSize,
				"pageCount" => $pageCount,
				"total" => $total,
				"data" => $data,
				);
		return $arr;
	}

	function escape($str)
	{
		return mysql_escape_string($str);
	}

	function like_escape($str)
	{
    	return strtr($str, array("\\\\" => "\\\\\\\\", '_' => '\_', '%' => '\%', "\'" => "\\\\\'"));
	}

	function affectedRows()
	{
		return mysql_affected_rows($this->linkID);
	}

	function insertID()
	{
		return mysql_insert_id($this->linkID);
	}

	function numRows($result)
	{
		return mysql_num_rows($result);
	}

	function numFields($result)
	{
		return mysql_num_fields($result);
	}

	function getFieldNames($table)
	{
		$result = $this->query("SELECT * FROM $table LIMIT 1");
		if ($result) {
			$fields = array();
			for ($i=0; $i<mysql_num_fields($result); $i++) {
				$fields[$i] = mysql_field_name($result, $i);
			}
			return $fields;
		}

		return FALSE;
	}

	function updateRecord($table, $cond, $data)
	{
		if (empty($table) || empty($cond) || !is_array($data) || count($data) == 0) {
			return $this->debug("ERROR updateRecord: table: $table, cond: $cond, data: $data");
		}

		$str = "";
		foreach ($data as $key => $val) {
			$str .= ", $key='" . $this->escape($val) . "'";
		}

		if ($str != "") {
			$str[0] = ' ';
			$sql = "UPDATE $table SET $str WHERE $cond";
			return $this->query($sql);
		}

		return FALSE;
	}

	function addRecord($table, $data)
	{
		if (empty($table) || !is_array($data) || count($data) == 0) {
			return $this->debug("ERROR addRecord: table: $table, data: $data");
		}

		$items = "";
		$values = "";
		foreach ($data as $key => $val) {
			$items .= ", $key";
			$values .= ", '" . $this->escape($val) . "'";
		} 
		if ($items != "" && $values != "") {
			$items[0] = ' ';
			$values[0] = ' ';
			$sql = "INSERT INTO $table ($items) VALUES ($values)";
			$ret = $this->query($sql);
			if ($ret) {
				return $this->insertID();
			}
		}

		return FALSE;
	}

	function deleteRecord($table, $cond)
	{
		if (empty($table) || empty($cond)) {
			return $this->debug("ERROR deleteRecord: table: $table, cond: $cond");
		}

		$sql = "DELETE FROM $table WHERE $cond";
		return $this->query($sql);
	}
}

/* vim:set ts=4 sw=4:*/
?>
