diff options
| -rw-r--r-- | .gitattributes | 3 | ||||
| -rw-r--r-- | framework/Data/DataGateway/TDataGatewayCommand.php | 340 | ||||
| -rw-r--r-- | framework/Data/DataGateway/TSqlCriteria.php | 177 | ||||
| -rw-r--r-- | framework/Data/DataGateway/TTableGateway.php | 305 | 
4 files changed, 825 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes index 51a89234..48644cc6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1652,6 +1652,9 @@ framework/Data/Common/TDbCommandBuilder.php -text  framework/Data/Common/TDbMetaData.php -text  framework/Data/Common/TDbTableColumn.php -text  framework/Data/Common/TDbTableInfo.php -text +framework/Data/DataGateway/TDataGatewayCommand.php -text +framework/Data/DataGateway/TSqlCriteria.php -text +framework/Data/DataGateway/TTableGateway.php -text  framework/Data/SqlMap/Configuration/TDiscriminator.php -text  framework/Data/SqlMap/Configuration/TInlineParameterMapParser.php -text  framework/Data/SqlMap/Configuration/TParameterMap.php -text diff --git a/framework/Data/DataGateway/TDataGatewayCommand.php b/framework/Data/DataGateway/TDataGatewayCommand.php new file mode 100644 index 00000000..25666059 --- /dev/null +++ b/framework/Data/DataGateway/TDataGatewayCommand.php @@ -0,0 +1,340 @@ +<?php +
 +class TDataGatewayCommand extends TComponent
 +{
 +	private $_builder;
 +
 +	/**
 +	 * @param TDbCommandBuilder database specific database command builder.
 +	 */
 +	public function __construct($builder)
 +	{
 +		$this->_builder = $builder;
 +	}
 +
 +	/**
 +	 * @return TDbTableInfo
 +	 */
 +	protected function getTableInfo()
 +	{
 +		return $this->_builder->getTableInfo();
 +	}
 +
 +	/**
 +	 * @return TDbConnection
 +	 */
 +	protected function getDbConnection()
 +	{
 +		return $this->_builder->getDbConnection();
 +	}
 +
 +	/**
 +	 * @return TDbCommandBuilder
 +	 */
 +	protected function getBuilder()
 +	{
 +		return $this->_builder;
 +	}
 +
 +	/**
 +	 * Executes a delete command.
 +	 * @param TSqlCriteria delete conditions and parameters.
 +	 * @return integer number of records affected.
 +	 */
 +	public function delete($criteria)
 +	{
 +		$where = $criteria->getCondition();
 +		$parameters = $criteria->getParameters()->toArray();
 +		$command = $this->getBuilder()->createDeleteCommand($where, $parameters);
 +		$command->prepare();
 +		return $command->execute();
 +	}
 +
 +	/**
 +	 * Updates the table with new data.
 +	 * @param array date for update.
 +	 * @param TSqlCriteria update conditions and parameters.
 +	 * @return integer number of records affected.
 +	 */
 +	public function update($data, $criteria)
 +	{
 +		$where = $criteria->getCondition();
 +		$parameters = $criteria->getParameters()->toArray();
 +		$command = $this->getBuilder()->createUpdateCommand($data,$where, $parameters);
 +		$command->prepare();
 +		return $command->execute();
 +	}
 +
 +	/**
 +	 * Find one record matching the critera.
 +	 * @param TSqlCriteria find conditions and parameters.
 +	 * @return array matching record.
 +	 */
 +	public function find($criteria)
 +	{
 +		return $this->getFindCommand($criteria)->queryRow();
 +	}
 +
 +	/**
 +	 * Find one or more matching records.
 +	 * @param TSqlCriteria $criteria
 +	 * @return TDbDataReader record reader.
 +	 */
 +	public function findAll($criteria)
 +	{
 +		return $this->getFindCommand($criteria)->query();
 +	}
 +
 +	/**
 +	 * @param mixed primary key value, or composite key values as array.
 +	 * @return array matching record.
 +	 */
 +	public function findByPk($keys)
 +	{
 +		list($where, $parameters) = $this->getPrimaryKeyCondition((array)$keys);
 +		$command = $this->getBuilder()->createFindCommand($where, $parameters);
 +		return $command->queryRow();
 +	}
 +
 +	/**
 +	 * @param array multiple primary key values or composite value arrays
 +	 * @return TDbDataReader record reader.
 +	 */
 +	public function findAllByPk($keys)
 +	{
 +		$where = $this->getCompositeKeyCondition((array)$keys);
 +		$command = $this->getBuilder()->createFindCommand($where);
 +		return $command->query();
 +	}
 +
 +	/**
 +	 * @param array multiple primary key values or composite value arrays
 +	 * @return integer number of rows affected.
 +	 */
 +	public function deleteByPk($keys)
 +	{
 +		$where = $this->getCompositeKeyCondition((array)$keys);
 +		$command = $this->getBuilder()->createDeleteCommand($where);
 +		$command->prepare();
 +		return $command->execute();
 +	}
 +
 +	/**
 +	 * Construct a "pk IN ('key1', 'key2', ...)" criteria.
 +	 * @param array values for IN predicate
 +	 * @param string SQL string for primary keys IN a list.
 +	 */
 +	protected function getCompositeKeyCondition($values)
 +	{
 +		$primary = $this->getTableInfo()->getPrimaryKeys();
 +		$count = count($primary);
 +		if($count===0)
 +		{
 +			throw new TDbException('dbtablegateway_no_primary_key_found',
 +				$this->getTableInfo()->getTableFullName());
 +		}
 +		if(!is_array($values) || count($values) === 0)
 +		{
 +			throw new TDbException('dbtablegateway_missing_pk_values',
 +				$this->getTableInfo()->getTableFullName());
 +		}
 +		if($count>1 && !is_array($values[0]))
 +			$values = array($values);
 +		if($count > 1 && count($values[0]) !== $count)
 +		{
 +			throw new TDbException('dbtablegateway_pk_value_count_mismatch',
 +				$this->getTableInfo()->getTableFullName());
 +		}
 +
 +		$columns = array();
 +		foreach($primary as $key)
 +			$columns[] = $this->getTableInfo()->getColumn($key)->getColumnName();
 +		return '('.implode(', ',$columns).') IN '.$this->quoteTuple($values);
 +	}
 +
 +	/**
 +	 * @param TDbConnection database connection.
 +	 * @param array values
 +	 * @return string quoted recursive tuple values, e.g. "('val1', 'val2')".
 +	 */
 +	protected function quoteTuple($array)
 +	{
 +		$conn = $this->getDbConnection();
 +		$data = array();
 +		foreach($array as $k=>$v)
 +			$data[] = is_array($v) ? $this->quoteTuple($v) : $conn->quoteString($v);
 +		return '('.implode(', ', $data).')';
 +	}
 +
 +	/**
 +	 * Create the condition and parameters for find by primary.
 +	 * @param array primary key values
 +	 * @return array tuple($where, $parameters)
 +	 */
 +	protected function getPrimaryKeyCondition($values)
 +	{
 +		$primary = $this->getTableInfo()->getPrimaryKeys();
 +		if(count($primary)===0)
 +		{
 +			throw new TDbException('dbtablegateway_no_primary_key_found',
 +				$this->getTableInfo()->getTableFullName());
 +		}
 +		$criteria=array();
 +		$bindings=array();
 +		$i = 0;
 +		foreach($primary as $key)
 +		{
 +			$column = $this->getTableInfo()->getColumn($key)->getColumnName();
 +			$criteria[] = $column.' = :'.$key;
 +			$bindings[$key] = $values[$i++];
 +		}
 +		return array(implode(' AND ', $criteria), $bindings);
 +	}
 +
 +	/**
 +	 * Find one or more matching records for arbituary SQL.
 +	 * @param TSqlCriteria $criteria
 +	 * @return TDbDataReader record reader.
 +	 */
 +	public function findBySql($criteria)
 +	{
 +		return $this->getSqlCommand($criteria)->query();
 +	}
 +
 +	/**
 +	 * Build sql command from the criteria. Limit, Offset and Ordering are applied if applicable.
 +	 * @param TSqlCriteria $criteria
 +	 * @return TDbCommand command corresponding to the criteria.
 +	 */
 +	protected function getSqlCommand($criteria)
 +	{
 +		$sql = $criteria->getCondition();
 +		$ordering = $criteria->getOrdersBy();
 +		$limit = $criteria->getLimit();
 +		$offset = $criteria->getOffset();
 +		if(count($ordering) > 0)
 +			$sql = $this->getBuilder()->applyOrdering($sql, $ordering);
 +		if($limit>=0 || $offset>=0)
 +			$sql = $this->getBuilder()->applyLimitOffset($sql, $limit, $offset);
 +		$command = $this->getBuilder()->createCommand($sql);
 +		$this->getBuilder()->bindArrayValues($command, $criteria->getParameters()->toArray());
 +		return $command;
 +	}
 +
 +	/**
 +	 * Build the find command from the criteria. Limit, Offset and Ordering are applied if applicable.
 +	 * @param TSqlCriteria $criteria
 +	 * @return TDbCommand.
 +	 */
 +	protected function getFindCommand($criteria)
 +	{
 +		$where = $criteria->getCondition();
 +		$parameters = $criteria->getParameters()->toArray();
 +		$ordering = $criteria->getOrdersBy();
 +		$limit = $criteria->getLimit();
 +		$offset = $criteria->getOffset();
 +		return $this->getBuilder()->createFindCommand($where,$parameters,$ordering,$limit,$offset);
 +	}
 +
 +	/**
 +	 * @param TSqlCriteria $criteria
 +	 * @return integer number of records.
 +	 */
 +	public function count($criteria)
 +	{
 +		if($criteria===null)
 +			return intval($this->getBuilder()->createCountCommand()->queryScalar());
 +		$where = $criteria->getCondition();
 +		$parameters = $criteria->getParameters()->toArray();
 +		$ordering = $criteria->getOrdersBy();
 +		$limit = $criteria->getLimit();
 +		$offset = $criteria->getOffset();
 +		$command = $this->getBuilder()->createCountCommand($where,$parameters,$ordering,$limit,$offset);
 +		return intval($command->queryScalar());
 +	}
 +
 +	/**
 +	 * Inserts a new record into the table. Each array key must
 +	 * correspond to a column name in the table unless a null value is permitted.
 +	 * @param array new record data.
 +	 * @return mixed last insert id if one column contains a serial or sequence,
 +	 * otherwise true if command executes successfully and affected 1 or more rows.
 +	 */
 +	public function insert($data)
 +	{
 +		$command=$this->getBuilder()->createInsertCommand($data);
 +		$command->prepare();
 +		if($command->execute() > 0)
 +		{
 +			$value = $this->getLastInsertId();
 +			return $value !== null ? $value : true;
 +		}
 +		return false;
 +	}
 +
 +	/**
 +	 * Iterate through all the columns and returns the last insert id of the
 +	 * first column that has a sequence or serial.
 +	 * @return mixed last insert id, null if none is found.
 +	 */
 +	public function getLastInsertID()
 +	{
 +		foreach($this->getTableInfo()->getColumns() as $column)
 +		{
 +			if($column->hasSequence())
 +				return $this->getDbConnection()->getLastInsertID($column->getSequenceName());
 +		}
 +	}
 +
 +	/**
 +	 * @param string __call method name
 +	 * @param string criteria conditions
 +	 * @param array method arguments
 +	 * @return TActiveRecordCriteria criteria created from the method name and its arguments.
 +	 */
 +	public function createCriteriaFromString($method, $condition, $args)
 +	{
 +		$fields = $this->extractMatchingConditions($method, $condition);
 +		$args=count($args) === 1 && is_array($args[0]) ? $args[0] : $args;
 +		if(count($fields)>count($args))
 +		{
 +			throw new TDbException('dbtablegateway_mismatch_args_exception',
 +				$method,count($fields),count($args));
 +		}
 +		return new TSqlCriteria(implode(' ',$fields), $args);
 +	}
 +
 +	/**
 +	 * Calculates the AND/OR condition from dynamic method substrings using
 +	 * table meta data, allows for any AND-OR combinations.
 +	 * @param string dynamic method name
 +	 * @param string dynamic method search criteria
 +	 * @return array search condition substrings
 +	 */
 +	protected function extractMatchingConditions($method, $condition)
 +	{
 +		$table = $this->getTableInfo();
 +		$columns = $table->getLowerCaseColumnNames();
 +		$regexp = '/('.implode('|', array_keys($columns)).')(and|_and_|or|_or_)?/i';
 +		$matches = array();
 +		if(!preg_match_all($regexp, strtolower($condition), $matches,PREG_SET_ORDER))
 +		{
 +			throw new TDbException('dbtablegateway_mismatch_column_name',
 +				$method, implode(', ', $columns), $table->getTableFullName());
 +		}
 +
 +		$fields = array();
 +		foreach($matches as $match)
 +		{
 +			$key = $columns[$match[1]];
 +			$column = $table->getColumn($key)->getColumnName();
 +			$sql = $column . ' = ? ';
 +			if(count($match) > 2)
 +				$sql .= strtoupper(str_replace('_', '', $match[2]));
 +			$fields[] = $sql;
 +		}
 +		return $fields;
 +	}
 +}
 + +?>
\ No newline at end of file diff --git a/framework/Data/DataGateway/TSqlCriteria.php b/framework/Data/DataGateway/TSqlCriteria.php new file mode 100644 index 00000000..ac5f00f2 --- /dev/null +++ b/framework/Data/DataGateway/TSqlCriteria.php @@ -0,0 +1,177 @@ +<?php
 +/**
 + * TDbSqlCriteria class file.
 + *
 + * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
 + * @link http://www.pradosoft.com/
 + * @copyright Copyright © 2005-2007 PradoSoft
 + * @license http://www.pradosoft.com/license/
 + * @version $Id: TDbSqlCriteria.php 1835 2007-04-03 01:38:15Z wei $
 + * @package System.Data.Common
 + */
 +
 +/**
 + * Search criteria for TDbDataGateway.
 + *
 + * Criteria object for data gateway finder methods. Usage:
 + * <code>
 + * $criteria = new TDbSqlCriteria;
 + * $criteria->Parameters[':name'] = 'admin';
 + * $criteria->Parameters[':pass'] = 'prado';
 + * $criteria->OrdersBy['level'] = 'desc';
 + * $criteria->OrdersBy['name'] = 'asc';
 + * $criteria->Limit = 10;
 + * $criteria->Offset = 20;
 + * </code>
 + *
 + * @author Wei Zhuo <weizho[at]gmail[dot]com>
 + * @version $Id: TDbSqlCriteria.php 1835 2007-04-03 01:38:15Z wei $
 + * @package System.Data.Common
 + * @since 3.1
 + */
 +class TSqlCriteria extends TComponent
 +{
 +	private $_condition;
 +	private $_parameters;
 +	private $_ordersBy;
 +	private $_limit;
 +	private $_offset;
 +
 +	/**
 +	 * Creates a new criteria with given condition;
 +	 * @param string sql string after the WHERE stanza
 +	 * @param mixed named or indexed parameters, accepts as multiple arguments.
 +	 */
 +	public function __construct($condition=null, $parameters=array())
 +	{
 +		if(!is_array($parameters) && func_num_args() > 1)
 +			$parameters = array_slice(func_get_args(),1);
 +		$this->_parameters=new TAttributeCollection;
 +		$this->_parameters->setCaseSensitive(true);
 +		$this->_parameters->copyFrom((array)$parameters);
 +		$this->_ordersBy=new TAttributeCollection;
 +		$this->_ordersBy->setCaseSensitive(true);
 +		$this->setCondition($condition);
 +	}
 +
 +	/**
 +	 * @return string search conditions.
 +	 */
 +	public function getCondition()
 +	{
 +		return $this->_condition;
 +	}
 +
 +	/**
 +	 * Sets the search conditions to be placed after the WHERE clause in the SQL.
 +	 * @param string search conditions.
 +	 */
 +	public function setCondition($value)
 +	{
 +		$this->_condition=$value;
 +	}
 +
 +	/**
 +	 * @return TAttributeCollection list of named parameters and values.
 +	 */
 +	public function getParameters()
 +	{
 +		return $this->_parameters;
 +	}
 +
 +	/**
 +	 * @param ArrayAccess named parameters.
 +	 */
 +	public function setParameters($value)
 +	{
 +		if(!(is_array($value) || $value instanceof ArrayAccess))
 +			throw new TException('value must be array or ArrayAccess');
 +		$this->_parameters->copyFrom($value);
 +	}
 +
 +	/**
 +	 * @return boolean true if the parameter index are string base, false otherwise.
 +	 */
 +	public function getIsNamedParameters()
 +	{
 +		foreach($this->getParameters() as $k=>$v)
 +			return is_string($k);
 +	}
 +
 +	/**
 +	 * @return TAttributeCollection ordering clause.
 +	 */
 +	public function getOrdersBy()
 +	{
 +		return $this->_ordersBy;
 +	}
 +
 +	/**
 +	 * @param ArrayAccess ordering clause.
 +	 */
 +	public function setOrdersBy($value)
 +	{
 +		if(!(is_array($value) || $value instanceof ArrayAccess))
 +			throw new TException('value must be array or ArrayAccess');
 +		$this->_ordersBy->copyFrom($value);
 +	}
 +
 +	/**
 +	 * @return int maximum number of records to return.
 +	 */
 +	public function getLimit()
 +	{
 +		return $this->_limit;
 +	}
 +
 +	/**
 +	 * @param int maximum number of records to return.
 +	 */
 +	public function setLimit($value)
 +	{
 +		$this->_limit=$value;
 +	}
 +
 +	/**
 +	 * @return int record offset.
 +	 */
 +	public function getOffset()
 +	{
 +		return $this->_offset;
 +	}
 +
 +	/**
 +	 * @param int record offset.
 +	 */
 +	public function setOffset($value)
 +	{
 +		$this->_offset=$value;
 +	}
 +
 +	/**
 +	 * @return string string representation of the parameters. Useful for debugging.
 +	 */
 +	public function __toString()
 +	{
 +		$str = '';
 +		if(strlen((string)$this->getCondition()) > 0)
 +			$str .= '"'.(string)$this->getCondition().'"';
 +		$params = array();
 +		foreach($this->getParameters() as $k=>$v)
 +			$params[] = "{$k} => ${v}";
 +		if(count($params) > 0)
 +			$str .= ', "'.implode(', ',$params).'"';
 +		$orders = array();
 +		foreach($this->getOrdersBy() as $k=>$v)
 +			$orders[] = "{$k} => ${v}";
 +		if(count($orders) > 0)
 +			$str .= ', "'.implode(', ',$orders).'"';
 +		if($this->_limit !==null)
 +			$str .= ', '.$this->_limit;
 +		if($this->_offset !== null)
 +			$str .= ', '.$this->_offset;
 +		return $str;
 +	}
 +}
 +
 +?>
\ No newline at end of file diff --git a/framework/Data/DataGateway/TTableGateway.php b/framework/Data/DataGateway/TTableGateway.php new file mode 100644 index 00000000..6acdb837 --- /dev/null +++ b/framework/Data/DataGateway/TTableGateway.php @@ -0,0 +1,305 @@ +<?php +
 +Prado::using('System.Data.DataGateway.TSqlCriteria');
 +Prado::using('System.Data.DataGateway.TDataGatewayCommand');
 +
 +class TTableGateway extends TComponent
 +{
 +	private $_command;
 +	private $_connection;
 +
 +	public function __construct($tableName,$connection)
 +	{
 +		$this->_connection=$connection;
 +		$this->setTableName($tableName);
 +	}
 +
 +	protected function setTableName($tableName)
 +	{
 +		Prado::using('System.Data.Common.TDbMetaData');
 +		$meta = TDbMetaData::getMetaData($this->getDbConnection());
 +		$builder = $meta->createCommandBuilder($tableName);
 +		$this->_command = new TDataGatewayCommand($builder);
 +	}
 +
 +	protected function getCommand()
 +	{
 +		return $this->_command;
 +	}
 +
 +	/**
 +	 * @return TDbConnection database connection.
 +	 */
 +	public function getDbConnection()
 +	{
 +		return $this->_connection;
 +	}
 +
 +	/**
 +	 * Execute arbituary sql command with binding parameters.
 +	 * @param string SQL query string.
 +	 * @param array binding parameters, positional or named.
 +	 * @return TDbDataReader query results.
 +	 */
 +	public function findBySql($sql, $parameters=array())
 +	{
 +		$args = func_num_args() > 1 ? array_slice(func_get_args(),1) : null;
 +		$criteria = $this->getCriteria($sql,$parameters, $args);
 +		return $this->getCommand()->findBySql($criteria);
 +	}
 +
 +	/**
 +	 * Find one single record that matches the criteria.
 +	 *
 +	 * Usage:
 +	 * <code>
 +	 * $table->find('username = :name AND password = :pass',
 +	 * 					array(':name'=>$name, ':pass'=>$pass));
 +	 * $table->find('username = ? AND password = ?', array($name, $pass));
 +	 * $table->find('username = ? AND password = ?', $name, $pass);
 +	 * //$criteria is of TSqlCriteria
 +	 * $table->find($criteria); //the 2nd parameter for find() is ignored.
 +	 * </code>
 +	 *
 +	 * @param string|TSqlCriteria SQL condition or criteria object.
 +	 * @param mixed parameter values.
 +	 * @return array matching record object.
 +	 */
 +	public function find($criteria, $parameters=array())
 +	{
 +		$args = func_num_args() > 1 ? array_slice(func_get_args(),1) : null;
 +		$criteria = $this->getCriteria($criteria,$parameters, $args);
 +		return $this->getCommand()->find($criteria);
 +	}
 +
 +	/**
 +	 * Accepts same parameters as find(), but returns TDbDataReader instead.
 +	 * @param string|TSqlCriteria SQL condition or criteria object.
 +	 * @param mixed parameter values.
 +	 * @return TDbDataReader matching records.
 +	 */
 +	public function findAll($criteria, $parameters=array())
 +	{
 +		$args = func_num_args() > 1 ? array_slice(func_get_args(),1) : null;
 +		$criteria = $this->getCriteria($criteria,$parameters, $args);
 +		return $this->getCommand()->findAll($criteria);
 +	}
 +
 +	/**
 +	 * Find one record using only the primary key or composite primary keys. Usage:
 +	 *
 +	 * <code>
 +	 * $table->findByPk($primaryKey);
 +	 * $table->findByPk($key1, $key2, ...);
 +	 * $table->findByPk(array($key1,$key2,...));
 +	 * </code>
 +	 *
 +	 * @param mixed primary keys
 +	 * @return array matching record.
 +	 */
 +	public function findByPk($keys)
 +	{
 +		if(func_num_args() > 1)
 +			$keys = func_get_args();
 +		return $this->getCommand()->findByPk($keys);
 +	}
 +
 +	/**
 +	 * Similar to findByPk(), but returns TDbDataReader instead.
 +	 *
 +	 * For scalar primary keys:
 +	 * <code>
 +	 * $table->findAllByPk($key1, $key2, ...);
 +	 * $table->findAllByPk(array($key1, $key2, ...));
 +	 * </code>
 +	 *
 +	 * For composite keys:
 +	 * <code>
 +	 * $table->findAllByPk(array($key1, $key2), array($key3, $key4), ...);
 +	 * $table->findAllByPk(array(array($key1, $key2), array($key3, $key4), ...));
 +	 * </code>
 +	 * @param mixed primary keys
 +	 * @return TDbDataReader data reader.
 +	 */
 +	public function findAllByPks($keys)
 +	{
 +		if(func_num_args() > 1)
 +			$keys = func_get_args();
 +		return $this->getCommand()->findAllByPk($keys);
 +	}
 +
 +	/**
 +	 * Delete records from the table with condition given by $where and
 +	 * binding values specified by $parameter argument.
 +	 * This method uses additional arguments as $parameters. E.g.
 +	 * <code>
 +	 * $table->delete('age > ? AND location = ?', $age, $location);
 +	 * </code>
 +	 * @param string delete condition.
 +	 * @param array condition parameters.
 +	 * @return integer number of records deleted.
 +	 */
 +	public function deleteAll($criteria, $parameters=array())
 +	{
 +		$args = func_num_args() > 1 ? array_slice(func_get_args(),1) : null;
 +		$criteria = $this->getCriteria($criteria,$parameters, $args);
 +		return $this->getCommand()->delete($criteria);
 +	}
 +
 +	/**
 +	 * Delete records by primary key. Usage:
 +	 *
 +	 * <code>
 +	 * $table->deleteByPk($primaryKey); //delete 1 record
 +	 * $table->deleteByPk($key1,$key2,...); //delete multiple records
 +	 * $table->deleteByPk(array($key1,$key2,...)); //delete multiple records
 +	 * </code>
 +	 *
 +	 * For composite primary keys (determined from the table definitions):
 +	 * <code>
 +	 * $table->deleteByPk(array($key1,$key2)); //delete 1 record
 +	 *
 +	 * //delete multiple records
 +	 * $table->deleteByPk(array($key1,$key2), array($key3,$key4),...);
 +	 *
 +	 * //delete multiple records
 +	 * $table->deleteByPk(array( array($key1,$key2), array($key3,$key4), .. ));
 +	 * </code>
 +	 *
 +	 * @param mixed primary key values.
 +	 * @return int number of records deleted.
 +	 */
 +	public function deleteByPk($keys)
 +	{
 +		if(func_num_args() > 1)
 +			$keys = func_get_args();
 +		return $this->getCommand()->deleteByPk($keys);
 +	}
 +
 +	/**
 +	 * Find the number of records.
 +	 * @param string|TSqlCriteria SQL condition or criteria object.
 +	 * @param mixed parameter values.
 +	 * @return int number of records.
 +	 */
 +	public function count($criteria=null,$parameters=array())
 +	{
 +		$args = func_num_args() > 1 ? array_slice(func_get_args(),1) : null;
 +		if($criteria!==null)
 +			$criteria = $this->getCriteria($criteria,$parameters, $args);
 +		return $this->getCommand()->count($criteria);
 +	}
 +
 +	/**
 +	 * Updates the table with new name-value pair $data. Each array key must
 +	 * correspond to a column name in the table. The update condition is
 +	 * specified by the $where argument and additional binding values can be
 +	 * specified using the $parameter argument.
 +	 * This method uses additional arguments as $parameters. E.g.
 +	 * <code>
 +	 * $gateway->update($data, 'age > ? AND location = ?', $age, $location);
 +	 * </code>
 +	 * @param array new record data.
 +	 * @param string update condition
 +	 * @param array additional binding name-value pairs.
 +	 * @return integer number of records updated.
 +	 */
 +	public function update($data, $criteria, $parameters=array())
 +	{
 +		$args = func_num_args() > 2 ? array_slice(func_get_args(),2) : null;
 +		$criteria = $this->getCriteria($criteria,$parameters, $args);
 +		return $this->getCommand()->update($data, $criteria);
 +	}
 +
 +	/**
 +	 * Inserts a new record into the table. Each array key must
 +	 * correspond to a column name in the table unless a null value is permitted.
 +	 * @param array new record data.
 +	 * @return mixed last insert id if one column contains a serial or sequence,
 +	 * otherwise true if command executes successfully and affected 1 or more rows.
 +	 */
 +	public function insert($data)
 +	{
 +		return $this->getCommand()->insert($data);
 +	}
 +
 +	/**
 +	 * @return mixed last insert id, null if none is found.
 +	 */
 +	public function getLastInsertId()
 +	{
 +		return $this->getCommand()->getLastInsertId();
 +	}
 +
 +	/**
 +	 * Create a new TSqlCriteria object from a string $criteria. The $args
 +	 * are additional parameters and are used in place of the $parameters
 +	 * if $parameters is not an array and $args is an arrary.
 +	 * @param string|TSqlCriteria sql criteria
 +	 * @param mixed parameters passed by the user.
 +	 * @param array additional parameters obtained from function_get_args().
 +	 * @return TSqlCriteria criteria object.
 +	 */
 +	protected function getCriteria($criteria, $parameters, $args)
 +	{
 +		if(is_string($criteria))
 +		{
 +			$useArgs = !is_array($parameters) && is_array($args);
 +			return new TSqlCriteria($criteria,$useArgs ? $args : $parameters);
 +		}
 +		else if($criteria instanceof TSqlCriteria)
 +			return $criteria;
 +		else
 +			throw new TDbException('dbtablegateway_invalid_criteria');
 +	}
 +
 +	/**
 +	 * Dynamic find method using parts of method name as search criteria.
 +	 * Method name starting with "findBy" only returns 1 record.
 +	 * Method name starting with "findAllBy" returns 0 or more records.
 +	 * Method name starting with "deleteBy" deletes records by the trail criteria.
 +	 * The condition is taken as part of the method name after "findBy", "findAllBy"
 +	 * or "deleteBy".
 +	 *
 +	 * The following are equivalent:
 +	 * <code>
 +	 * $table->findByName($name)
 +	 * $table->find('Name = ?', $name);
 +	 * </code>
 +	 * <code>
 +	 * $table->findByUsernameAndPassword($name,$pass); // OR may be used
 +	 * $table->findBy_Username_And_Password($name,$pass); // _OR_ may be used
 +	 * $table->find('Username = ? AND Password = ?', $name, $pass);
 +	 * </code>
 +	 * <code>
 +	 * $table->findAllByAge($age);
 +	 * $table->findAll('Age = ?', $age);
 +	 * </code>
 +	 * <code>
 +	 * $table->deleteAll('Name = ?', $name);
 +	 * $table->deleteByName($name);
 +	 * </code>
 +	 * @return mixed single record if method name starts with "findBy", 0 or more records
 +	 * if method name starts with "findAllBy"
 +	 */
 +	public function __call($method,$args)
 +	{
 +		$delete =false;
 +		if($findOne = substr(strtolower($method),0,6)==='findby')
 +			$condition = $method[6]==='_' ? substr($method,7) : substr($method,6);
 +		else if(substr(strtolower($method),0,9)==='findallby')
 +			$condition = $method[9]==='_' ? substr($method,10) : substr($method,9);
 +		else if($delete = substr(strtolower($method),0,8)==='deleteby')
 +			$condition = $method[8]==='_' ? substr($method,9) : substr($method,8);
 +		else
 +			return null;
 +
 +		$criteria = $this->getCommand()->createCriteriaFromString($method, $condition, $args);
 +		if($delete)
 +			return $this->deleteAll($criteria);
 +		else
 +			return $findOne ? $this->find($criteria) : $this->findAll($criteria);
 +	}
 +}
 + +?>
\ No newline at end of file  | 
