Skip to content

Commit

Permalink
initial version of property bag collections
Browse files Browse the repository at this point in the history
  • Loading branch information
Magomogo committed Sep 18, 2013
1 parent 4b5e30d commit ec1cc43
Show file tree
Hide file tree
Showing 19 changed files with 334 additions and 84 deletions.
12 changes: 12 additions & 0 deletions lib/Magomogo/Persisted/CollectableModelInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Magomogo\Persisted;

interface CollectableModelInterface
{
/**
* @param PropertyBagCollection $collection
* @param $offset
*/
public function appendToCollection($collection, $offset);
}
8 changes: 8 additions & 0 deletions lib/Magomogo/Persisted/CollectionOwnerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Magomogo\Persisted;

interface CollectionOwnerInterface
{
public function collections();
}
13 changes: 7 additions & 6 deletions lib/Magomogo/Persisted/Container/ContainerInterface.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php
namespace Magomogo\Persisted\Container;
use Magomogo\Persisted\PropertyBagCollection;
use Magomogo\Persisted\PropertyBag;

interface ContainerInterface
Expand All @@ -23,17 +24,17 @@ public function saveProperties($propertyBag);
public function deleteProperties(array $propertyBags);

/**
* @param string $referenceName
* @param \Magomogo\Persisted\PropertyBag $leftProperties
* @param PropertyBagCollection $collectionBag
* @param \Magomogo\Persisted\PropertyBag $ownerProperties
* @param array $connections array of \Magomogo\Model\PropertyBag
* @return void
*/
public function referToMany($referenceName, $leftProperties, array $connections);
public function referToMany($collectionBag, $ownerProperties, array $connections);

/**
* @param string $referenceName
* @param \Magomogo\Persisted\PropertyBag $leftProperties
* @param PropertyBagCollection $collectionBag
* @param \Magomogo\Persisted\PropertyBag $ownerProperties
* @return array of \Magomogo\Model\PropertyBag
*/
public function listReferences($referenceName, $leftProperties);
public function listReferences($collectionBag, $ownerProperties);
}
27 changes: 14 additions & 13 deletions lib/Magomogo/Persisted/Container/Memory.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,33 +69,34 @@ public function saveProperties($propertyBag)
}

/**
* @param string $referenceName
* @param PropertyBag $leftProperties
* @param array $connections
* @param CollectionBag $collectionBag
* @param PropertyBag $ownerProperties
* @param $connections
* @internal param array $connections
*/
public function referToMany($referenceName, $leftProperties, array $connections)
public function referToMany($collectionBag, $ownerProperties, array $connections)
{
$this->saveProperties($leftProperties);
$this->manyToManyReferences[$referenceName] = array();
$this->saveProperties($ownerProperties);
$this->manyToManyReferences[$collectionBag] = array();
foreach ($connections as $rightProperties) {
$this->manyToManyReferences[$referenceName][] = array(
'left' => $leftProperties->id($this),
$this->manyToManyReferences[$collectionBag][] = array(
'left' => $ownerProperties->id($this),
'right' => $rightProperties,
);
$this->saveProperties($rightProperties);
}
}

/**
* @param string $referenceName
* @param PropertyBag $leftProperties
* @param string $collectionBag
* @param PropertyBag $ownerProperties
* @return array
*/
public function listReferences($referenceName, $leftProperties)
public function listReferences($collectionBag, $ownerProperties)
{
$connections = array();
foreach ($this->manyToManyReferences[$referenceName] as $pair) {
if ($leftProperties->id($this) === $pair['left']) {
foreach ($this->manyToManyReferences[$collectionBag] as $pair) {
if ($ownerProperties->id($this) === $pair['left']) {
$connections[] = $pair['right'];
}
}
Expand Down
60 changes: 48 additions & 12 deletions lib/Magomogo/Persisted/Container/SqlDb.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
namespace Magomogo\Persisted\Container;

use Doctrine\DBAL\Connection;
use Magomogo\Persisted\CollectionOwnerInterface;
use Magomogo\Persisted\Container\SqlDb\NamesInterface;
use Magomogo\Persisted\ModelInterface;
use Magomogo\Persisted\PossessionInterface;
use Magomogo\Persisted\PropertyBagCollection;
use Magomogo\Persisted\PropertyBag;
use Magomogo\Persisted\Exception;

Expand Down Expand Up @@ -44,6 +46,9 @@ public function loadProperties($propertyBag)
if ($propertyBag instanceof PossessionInterface) {
$this->collectReferences($row, $propertyBag->foreign());
}
if ($propertyBag instanceof CollectionOwnerInterface) {
$this->collectCollections($propertyBag);
}

return $propertyBag;
}
Expand All @@ -64,8 +69,13 @@ public function saveProperties($propertyBag)
foreach ($propertyBag as $name => $property) {
$row[$this->db->quoteIdentifier($name)] = $this->toDbValue($property);
}
$this->commit($row, $propertyBag);

if ($propertyBag instanceof CollectionOwnerInterface) {
$this->saveCollections($propertyBag);
}

return $this->commit($row, $propertyBag);
return $propertyBag;
}

/**
Expand All @@ -79,42 +89,46 @@ public function deleteProperties(array $propertyBags)
}

/**
* @param string $referenceName
* @param \Magomogo\Persisted\PropertyBag $leftProperties
* @param array $connections
* @param PropertyBagCollection $collectionBag
* @param \Magomogo\Persisted\PropertyBag $ownerProperties
* @param $connections
* @internal param array $connections
*/
public function referToMany($referenceName, $leftProperties, array $connections)
public function referToMany($collectionBag, $ownerProperties, array $connections)
{
$referenceName = $this->names->manyToManyRelationName($collectionBag, $ownerProperties);

$this->db->delete(
$this->db->quoteIdentifier($referenceName),
array($this->db->quoteIdentifier($this->names->classToName($leftProperties)) => $leftProperties->id($this))
array($this->db->quoteIdentifier($this->names->classToName($ownerProperties)) => $ownerProperties->id($this))
);

/** @var PropertyBag $rightProperties */
foreach ($connections as $rightProperties) {
$this->db->insert(
$this->db->quoteIdentifier($referenceName),
array(
$this->db->quoteIdentifier($this->names->classToName($leftProperties)) => $leftProperties->id($this),
$this->db->quoteIdentifier($this->names->classToName($ownerProperties)) => $ownerProperties->id($this),
$this->db->quoteIdentifier($this->names->classToName($rightProperties)) => $rightProperties->id($this),
)
);
}
}

/**
* @param string $referenceName
* @param \Magomogo\Persisted\PropertyBag $leftProperties
* @param PropertyBagCollection $collectionBag
* @param \Magomogo\Persisted\PropertyBag $ownerProperties
* @return array
*/
public function listReferences($referenceName, $leftProperties)
public function listReferences($collectionBag, $ownerProperties)
{
$leftPropertiesName = $this->names->classToName($leftProperties);
$referenceName = $this->names->manyToManyRelationName($collectionBag, $ownerProperties);
$leftPropertiesName = $this->names->classToName($ownerProperties);

$list = $this->db->fetchAll(
'SELECT * FROM ' . $this->db->quoteIdentifier($referenceName)
. ' WHERE ' . $this->db->quoteIdentifier($leftPropertiesName) . '=?',
array($leftProperties->id($this))
array($ownerProperties->id($this))
);

$connections = array();
Expand Down Expand Up @@ -211,6 +225,28 @@ private function collectReferences(array $row, $references)
return $references;
}

/**
* @param CollectionOwnerInterface $propertyBag
*/
private function collectCollections($propertyBag)
{
/** @var PropertyBagCollection $collection */
foreach ($propertyBag->collections() as $collectionName => $collection) {
$collection->loadFrom($this);
}
}

/**
* @param CollectionOwnerInterface $propertyBag
*/
private function saveCollections($propertyBag)
{
/** @var PropertyBagCollection $collection */
foreach ($propertyBag->collections() as $collectionName => $collection) {
$collection->putIn($this);
}
}

private function foreignKeys($references)
{
$keys = array();
Expand Down
2 changes: 2 additions & 0 deletions lib/Magomogo/Persisted/Container/SqlDb/NamesInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ public function classToName($propertyBag);
* @return PropertyBag
*/
public function nameToClass($name);

public function manyToManyRelationName($collectionBag, $ownerPropertyBag);
}
27 changes: 19 additions & 8 deletions lib/Magomogo/Persisted/Container/SqlDb/SchemaCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
use Magomogo\Persisted\Container\ContainerInterface;
use Magomogo\Persisted\ModelInterface;
use Magomogo\Persisted\PossessionInterface;
use Magomogo\Persisted\PropertyBagCollection;
use Magomogo\Persisted\PropertyBag;
use Magomogo\Persisted\Exception;
use Magomogo\Persisted\CollectionOwnerInterface;

class SchemaCreator implements ContainerInterface
{
Expand Down Expand Up @@ -58,6 +60,14 @@ public function saveProperties($propertyBag)
$this->manager->createTable(
$this->newTableObject($propertyBag, $tableName)
);

if ($propertyBag instanceof CollectionOwnerInterface) {
/** @var PropertyBagCollection $collection */
foreach ($propertyBag->collections() as $collectionName => $collection) {
$collection->putIn($this);
}
}

}

$propertyBag->persisted($tableName, $this);
Expand All @@ -74,18 +84,20 @@ public function deleteProperties(array $propertyBags)
}

/**
* @param string $referenceName
* @param \Magomogo\Persisted\PropertyBag $leftProperties
* @param PropertyBagCollection $collectionBag
* @param \Magomogo\Persisted\PropertyBag $ownerProperties
* @param array $connections array of \Magomogo\Model\PropertyBag
* @return void
*/
public function referToMany($referenceName, $leftProperties, array $connections)
public function referToMany($collectionBag, $ownerProperties, array $connections)
{
$referenceName = $this->names->manyToManyRelationName($collectionBag, $ownerProperties);

if (!empty($connections) && !in_array($referenceName, $this->manager->listTableNames())) {
$rightProperties = reset($connections);
$table = new Table($this->quoteIdentifier($referenceName));
$this->addForeignReferenceColumn(
$table, $this->names->classToName($leftProperties), $leftProperties
$table, $this->names->classToName($ownerProperties), $ownerProperties
);
$this->addForeignReferenceColumn(
$table, $this->names->classToName($rightProperties), $rightProperties
Expand All @@ -95,12 +107,11 @@ public function referToMany($referenceName, $leftProperties, array $connections)
}

/**
* @param string $referenceName
* @param \Magomogo\Persisted\PropertyBag $leftProperties
* @internal param string $rightPropertiesSample
* @param string $collectionBag
* @param \Magomogo\Persisted\PropertyBag $ownerProperties
* @return array of \Magomogo\Model\PropertyBag
*/
public function listReferences($referenceName, $leftProperties)
public function listReferences($collectionBag, $ownerProperties)
{
trigger_error('Incorrect usage', E_USER_ERROR);
}
Expand Down
94 changes: 94 additions & 0 deletions lib/Magomogo/Persisted/PropertyBagCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace Magomogo\Persisted;

use Magomogo\Persisted\Container\ContainerInterface;
use Magomogo\Persisted\PropertyBag;
use Magomogo\Persisted\CollectableModelInterface;

abstract class PropertyBagCollection implements \ArrayAccess, \IteratorAggregate, \Countable
{
/**
* @var PropertyBag
*/
protected $owner;

protected $items = array();

abstract protected function constructModel($propertyBag);

/**
* @param ContainerInterface $container
* @return $this
*/
public function loadFrom($container)
{
foreach ($container->listReferences($this, $this->owner) as $properties) {
/** @var PropertyBag $properties */
$this->items[] = $properties;
}
return $this;
}

/**
* @param ContainerInterface $container
* @return $this
*/
public function putIn($container)
{
$container->referToMany($this, $this->owner, $this->items);
return $this;
}

public function appendPropertyBag($propertyBag, $offset)
{
if (is_null($offset)) {
$this->items[] = $propertyBag;
} else {
$this->items[$offset] = $propertyBag;
}
}

public function count()
{
return count($this->items);
}

public function offsetExists($offset)
{
return array_key_exists($offset, $this->items);
}

public function offsetGet($offset)
{
return $this->constructModel($this->items[$offset]);
}

/**
* @param mixed $offset
* @param CollectableModelInterface $value
*/
public function offsetSet($offset, $value)
{
$value->appendToCollection($this, $offset);
}

public function offsetUnset($offset)
{
unset($this->items[$offset]);
}

public function getIterator()
{
return new \ArrayIterator($this->asArray());
}

public function asArray()
{
$models = array();
foreach ($this->items as $offset => $propertyBag) {
$models[$offset] = $this->constructModel($propertyBag);
}
return $models;
}
}
Loading

0 comments on commit ec1cc43

Please sign in to comment.