Rev 61 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
1
<?php
namespace PointedEars\PHPX\Db
;
use \PointedEars\PHPX\Application
;
/**
* Generic database table model class
*
* @author Thomas Lahn
* @property Database $database
* @property-read int $lastInsertId
* ID of the last inserted row, or the last value from
a sequence object, depending on the underlying driver.
*/
class Table
extends \PointedEars\PHPX\AbstractModel
{
/**
* Name of the table
* @var string
*/
protected static
$_name = '';
/**
* Columns definition
* @var array
* @see Table::create()
*/
protected static
$_columns;
/**
* Indexes definition
* @var array
* @see Table::create()
*/
protected static
$_indexes;
/**
* Constraints definition
* @var array
* @see Table::create()
*/
protected static
$_constraints;
/**
* Database of the table
* @var Database|string
* @see Table::create()
*/
protected static
$_database;
/**
* Name of the primary key column of the table
* @var string
*/
protected static
$_id = 'id';
/**
* Creates a new <code>Table</code> instance.
*
* Each of the parameters is optional and can also be given
* by a protected property where the parameter name is preceded
* by <code>_</code>. Parameter values overwrite the default
* property values. It is recommended to use default property
* values of inheriting classes except for small applications
* and testing purposes.
*
* @param Database $database
* Database of the table (required in order to use a fitting
* query language)
* @param string $name
* Table name
* @param string $id
* Name of the primary key column
* @throws InvalidArgumentException
*/
public function __construct
($database = null, $name = '', $id = '')
{
if ($database === null)
{
/* Call getter to convert to Database if possible */
if ($this->database === null)
{
$this->database = Application
::getInstance()->getDefaultDatabase();
}
}
else
{
$this->database = $database;
}
if ($name !== '')
{
$this->name = $name;
}
$name = $this->name;
if (!\
is_string($name))
{
throw new \InvalidArgumentException
(
'Expected string for table name, saw '
. (\
is_object($name) ? \
get_class($name) : \
gettype($name)));
}
if ($id !== '')
{
$this->id = $id;
}
}
/**
* @param string $value
*/
public function setName
($value)
{
$class = \
get_class($this);
$class::$_name = (string
) $value;
}
/**
* @return string
*/
public function getName
()
{
$class = \
get_class($this);
return $class::$_name;
}
/**
* Returns the database for the table
* @return Database
*/
public function getDatabase
()
{
/* FIXME: What about tables from different databases? */
$class = \
get_class($this);
if (\
is_string($class::$_database))
{
/* Call setter to convert to Database */
$this->setDatabase($class::$_database);
}
return $class::$_database;
}
/**
* @param Database|string $value
* @throws InvalidArgumentException
*/
public function setDatabase
($value)
{
$class = \
get_class($this);
if ($value instanceof Database
)
{
$class::$_database = $value;
}
else if ($value !== null)
{
$database = new $value();
if (!($database instanceof Database
))
{
throw new \InvalidArgumentException
(
'Expected Database instance or string for class name, saw '
. (\
is_object($value) ? \
get_class($value) : \
gettype($value))
);
}
$class::$_database = $database;
}
}
/**
* @param string $value
*/
public function setId
($value)
{
$class = \
get_class($this);
$class::$_id = (string
) $value;
}
/**
* @return string
*/
public function getId
()
{
$class = \
get_class($this);
return $class::$_id;
}
/**
* Returns the <var>options</var> array for {@link Database::createTable}
*
* Should be called and overridden by inheriting classes.
*
* @return array
*/
protected function _createOptions
()
{
$options = array();
foreach (array('indexes', 'constraints') as $option)
{
if ($class::$
{"_$option"})
{
$options[$option] = $class::$
{"_$option"};
}
}
return $options;
}
/**
* Creates the table for this model
*
* @return bool
*/
public function create
()
{
$class = \
get_class($this);
return $this->database->createTable(
$class::$_name, $class::$_columns, $this->_createOptions
());
}
/**
* Initiates a transaction
*
* @return bool
* @see Database::beginTransaction()
*/
public function beginTransaction
()
{
return $this->database->beginTransaction();
}
/**
* Rolls back a transaction
*
* @return bool
* @see Database::rollBack()
*/
public function rollBack
()
{
return $this->database->rollBack();
}
/**
* Commits a transaction
*
* @return bool
* @see Database::commit()
*/
public function commit
()
{
return $this->database->commit();
}
/**
* Retrieves all rows from the table
*
* @return array
* @see Database::fetchAll()
*/
public function fetchAll
($fetch_style = null, $column_index = null, array $ctor_args = null)
{
return $this->database->fetchAll($this->name, $fetch_style, $column_index, $ctor_args);
}
/**
* Selects data from one or more tables
*
* @return array
* @see Database::select()
*/
public function select
($columns = null, $where = null, $order = null, $limit = null)
{
return $this->database->select($this->name, $columns, $where, $order, $limit);
}
/**
* Updates records in one or more tables
*
* @return bool
* @see Database::update()
*/
public function update
($data, $condition)
{
return $this->database->update($this->name, $data, $condition);
}
/**
* Inserts a record into the table
*
* @return bool
* @see Database::insert()
*/
public function insert
($data, $cols = null)
{
return $this->database->insert($this->name, $data, $cols);
}
/**
* Returns the ID of the last inserted row, or the last value from
* a sequence object, depending on the underlying driver.
*
* @return int
* @see Database::getLastInsertId()
*/
public function getLastInsertId
()
{
return $this->database->lastInsertId;
}
/**
* Delete a record from the table
*
* @param int $id
* ID of the record to delete. May be <code>null</code>,
* in which case <var>$condition</var> must specify
* the records to be deleted.
* @param array[optional] $condition
* Conditions that must be met for a record to be deleted.
* Ignored if <var>$id</var> is not <code>null</code>.
* @return bool
* @throws InvalidArgumentException if both <var>$id</var> and
* <var>$condition</var> are <code>null</code>.
* @see Database::delete()
*/
public function delete
($id, array $condition = null)
{
if ($id !== null)
{
$condition = array($this->id => $id);
}
else if ($condition === null)
{
throw new InvalidArgumentException
(
'$id and $condition cannot both be null');
}
return $this->database->delete($this->name, $condition);
}
/**
* Inserts a row into the table or updates an existing one
*
* @param array $data
* Associative array of column-value pairs to be updated/inserted
* @param string|array $condition
* If there are no records matching this condition, a row
* will be inserted; otherwise matching records are updated.
* @return bool
* The return value of Table::update() or Table::insert()
* @see Table::update()
* @see Table::insert()
*/
public function updateOrInsert
($data, array $condition = null)
{
if ($this->select($this->id, $condition))
{
return $this->update($data, $condition);
}
return $this->insert($data);
}
/**
* Finds a record by ID
*
* @param mixed $id
* @return array
*/
public function find
($id)
{
/* DEBUG */
if (defined('DEBUG') && DEBUG
> 0)
{
debug
($id);
}
$result = $this->select(null, array($this->id => $id));
if ($result)
{
$result = $result[0];
}
return $result;
}
/**
* Returns the date of last modification of this table.
*
* @return int|null
* Timestamp of last modification, or <code>null</code> if
* unavailable.
*/
public function getLastModified
()
{
return $this->database->getLastModified($this->name);
}
}