Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Commit

Permalink
Zend\Db\RowGateway
Browse files Browse the repository at this point in the history
* RowGateway refactor primary key handling
* Enable delete() method
* Minimize memory footprint of stored data
* Add internal API for tracking existing rows
  • Loading branch information
Ralph Schindler committed Aug 17, 2012
1 parent a68d8c6 commit 3e6594f
Show file tree
Hide file tree
Showing 4 changed files with 303 additions and 151 deletions.
103 changes: 71 additions & 32 deletions library/Zend/Db/RowGateway/AbstractRowGateway.php
Expand Up @@ -35,14 +35,14 @@ abstract class AbstractRowGateway implements ArrayAccess, Countable, RowGatewayI
protected $table = null;

/**
* @var string
* @var array
*/
protected $primaryKeyColumn = null;

/**
* @var array
*/
protected $originalData = null;
protected $primaryKeyData = null;

/**
* @var array
Expand Down Expand Up @@ -81,6 +81,8 @@ public function initialize()

if ($this->primaryKeyColumn == null) {
throw new Exception\RuntimeException('This row object does not have a primary key column set.');
} elseif (is_string($this->primaryKeyColumn)) {
$this->primaryKeyColumn = (array) $this->primaryKeyColumn;
}

if (!$this->sql instanceof Sql) {
Expand All @@ -92,30 +94,21 @@ public function initialize()
$this->isInitialized = true;
}

/**
* Populate Original Data
*
* @param array $originalData
* @param boolean $originalDataIsCurrent
* @return RowGateway
*/
public function populateOriginalData(array $originalData)
{
$this->originalData = $originalData;
return $this;
}

/**
* Populate Data
*
* @param array $currentData
* @return RowGateway
*/
public function populate(array $rowData, $isOriginal = null)
public function populate(array $rowData, $rowExistsInDatabase = false)
{
$this->initialize();

$this->data = $rowData;
if ($isOriginal == true || ($isOriginal == null && empty($this->originalData))) {
$this->populateOriginalData($rowData);
if ($rowExistsInDatabase == true) {
$this->processPrimaryKeyData();
} else {
$this->primaryKeyData = null;
}

return $this;
Expand All @@ -137,17 +130,22 @@ public function exchangeArray($array)
*/
public function save()
{
if (is_array($this->primaryKeyColumn)) {
// @todo compound primary keys
throw new Exception\RuntimeException('Compound primary keys are currently not supported, but are on the TODO list.');
}
$this->initialize();

if (isset($this->originalData[$this->primaryKeyColumn])) {
if ($this->rowExistsInDatabase()) {

// UPDATE
$where = array($this->primaryKeyColumn => $this->originalData[$this->primaryKeyColumn]);

$data = $this->data;
unset($data[$this->primaryKeyColumn]);
$where = array();

// primary key is always an array even if its a single column
foreach ($this->primaryKeyColumn as $pkColumn) {
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
if ($data[$pkColumn] == $this->primaryKeyData[$pkColumn]) {
unset($data[$pkColumn]);
}
}

$statement = $this->sql->prepareStatementForSqlObject($this->sql->update()->set($data)->where($where));
$result = $statement->execute();
Expand All @@ -163,11 +161,18 @@ public function save()
$statement = $this->sql->prepareStatementForSqlObject($insert);

$result = $statement->execute();
$primaryKeyValue = $result->getGeneratedValue();
if (($primaryKeyValue = $result->getGeneratedValue()) && count($this->primaryKeyColumn) == 1) {
$this->primaryKeyData = array($this->primaryKeyColumn[0] => $primaryKeyValue);
}
$rowsAffected = $result->getAffectedRows();
unset($statement, $result); // cleanup

$where = array($this->primaryKeyColumn => $primaryKeyValue);
$where = array();
// primary key is always an array even if its a single column
foreach ($this->primaryKeyColumn as $pkColumn) {
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
}

}

// refresh data
Expand All @@ -186,16 +191,27 @@ public function save()
/**
* Delete
*
* @return void
* @return int
*/
public function delete()
{
if (is_array($this->primaryKeyColumn)) {
// @todo compound primary keys
$this->initialize();

$where = array();
// primary key is always an array even if its a single column
foreach ($this->primaryKeyColumn as $pkColumn) {
$where[$pkColumn] = $this->primaryKeyData[$pkColumn];
}

$where = array($this->primaryKeyColumn => $this->originalData[$this->primaryKeyColumn]);
//return $this->tableGateway->delete($where);
// @todo determine if we need to do a select to ensure 1 row will be affected

$statement = $this->sql->prepareStatementForSqlObject($this->sql->delete()->where($where));
$result = $statement->execute();

if ($result->getAffectedRows() == 1) {
// detach from database
$this->primaryKeyData = null;
}
}

/**
Expand Down Expand Up @@ -311,4 +327,27 @@ public function __unset($name)
{
$this->offsetUnset($name);
}

/**
* @return bool
*/
public function rowExistsInDatabase()
{
return ($this->primaryKeyData !== null);
}

/**
* @throws Exception\RuntimeException
*/
protected function processPrimaryKeyData()
{
$this->primaryKeyData = array();
foreach ($this->primaryKeyColumn as $column) {
if (!isset($this->data[$column])) {
throw new Exception\RuntimeException('While processing primary key data, a known key ' . $column . ' was not found in the data array');
}
$this->primaryKeyData[$column] = $this->data[$column];
}
}

}
2 changes: 1 addition & 1 deletion library/Zend/Db/RowGateway/RowGateway.php
Expand Up @@ -31,7 +31,7 @@ class RowGateway extends AbstractRowGateway
public function __construct($primaryKeyColumn, $table, $adapterOrSql = null)
{
// setup primary key
$this->primaryKeyColumn = $primaryKeyColumn;
$this->primaryKeyColumn = (array) $primaryKeyColumn;

// set table
$this->table = $table;
Expand Down

0 comments on commit 3e6594f

Please sign in to comment.