<?php

/**
 * Array-style interface for database access
 *
 * Reads and stores data in database using array access interface.
 * Can read, insert and update database table rows.
 *
 * @version DR1.6
 */
class TableGateway implements ArrayAccess {



	protected $tableName;
	protected $key;
	protected $dbAdapter;



	/**
	 * Configures database table settings
	 *
	 * @param string, table name
	 * @param string, key name (most often primary key or unique column), default 'id'
	 * @param DBAdapter, default taken from DBFactory
	 */
	public function __construct($tableName, $key = 'id', DBAdapter $dbAdapter = null) {
		$this->tableName = $tableName;
		$this->key = $key;
		if ($dbAdapter) {
			$this->dbAdapter = $dbAdapter;
		} else {
			$this->dbAdapter = DBFactory::getAdapter();
		}
		$this->data = new ArrayObject();
	}



	/**
	 * Performs type checking for given offset
	 *
	 * @param mixed, offset
	 * @param boolean, whether to allow null offset, default not allowed
	 */
	public function sanitizeOffset($offset, $allowNull = false) {
		if (!is_numeric($offset) and !is_string($offset) and !($allowNull and is_null($offset))) {
			throw new Exception(get_class($this) . ' incorrect offset type');
		}
	}



	/**
	 * Performs check whether given offset exists
	 *
	 * @param mixed, offset
	 */
	public function offsetExists($offset) {
		return $this->offsetGet($offset) ? true : false;
	}



	
	/**
	 * Returns database table row at given offset
	 *
	 * @param mixed, offset
	 * @return ArrayObject
	 */
	public function offsetGet($offset) {
		$this->sanitizeOffset($offset);
		$dialect = $this->dbAdapter->getDialect();
		$q = $dialect->getQuotes();
		$tableName = $q . $this->tableName . $q;
		$key = $q . $this->key . $q;
		$sql = "
				SELECT * FROM $tableName
				WHERE $key = '$offset'
		";
		if ($this->dbAdapter->execute($sql)) {
			foreach ($this->dbAdapter as $row) {
				return $row;
			}
		}
		return null;
	}



	/**
	 * Saves row into database table
	 *
	 * @param mixed, offset
	 * @param array or ArrayObject, row
	 */
	public function offsetSet($offset, $record) {
		if (!is_array($record) and !($record instanceof ArrayObject)) {
			throw new Exception(get_class($this) . ' array or ArrayObject expected');
		}
		$this->sanitizeOffset($offset, true);
		$dialect = $this->dbAdapter->getDialect();
		$sql = $offset
			? $dialect->getUpdate($this->tableName, $record, $this->key, $offset)
			: $dialect->getInsert($this->tableName, $record);
		return $this->dbAdapter->execute($sql);
	}



	/**
	 * Removes row at given offset
	 *
	 * @param mixed, offset
	 */
	public function offsetUnset($offset) {
		$this->sanitizeOffset($offset);
		$dialect = $this->dbAdapter->getDialect();
		echo ($dialect->getDelete($this->tableName, $this->key, $offset));
		return $this->dbAdapter->execute($dialect->getDelete($this->tableName, $this->key, $offset));
	}


	
} // class TableGateway

?>