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);
  }
}