Skip to content

Commit 6ac07d7

Browse files
author
Marco Bunge
committed
Update identity map and unit of work. Fix datatype issues
1 parent 2d6dd59 commit 6ac07d7

File tree

6 files changed

+127
-51
lines changed

6 files changed

+127
-51
lines changed

src/AbstractMapper.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ public function delete($entity)
323323

324324
$result = $query->execute();
325325

326-
$this->getIdentityMap()->removeId($data[$this->getLastInsertIdReference()]);
327-
$this->getConnection()->getObjectGraph()->remove($entity);
326+
$this->getIdentityMap()->remove($data[$this->getLastInsertIdReference()], $entity);
328327

329328
return $result;
330329
}
@@ -356,14 +355,12 @@ public function create($entity)
356355
$this->getIdentityMap()->set($data[$this->getLastInsertIdReference()], $entity);
357356
}
358357

359-
$this->getConnection()->getObjectGraph()->add($entity);
360-
361358
return $entity;
362359
}
363360

364361
/**
365362
* @param $entity
366-
* @return mixed
363+
* @return object
367364
*/
368365
public function update($entity)
369366
{
@@ -397,7 +394,6 @@ public function update($entity)
397394

398395
// update identity
399396
$this->getIdentityMap()->set($data[$this->getLastInsertIdReference()], $entity);
400-
$this->getConnection()->getObjectGraph()->modify($entity);
401397

402398
// we don't need to update entity data
403399
return $entity;
@@ -407,7 +403,7 @@ public function update($entity)
407403
* Save new or existing entity
408404
*
409405
* @param object[]|object $entity
410-
* @return int
406+
* @return object
411407
*/
412408
public function save($entity)
413409
{

src/Connection.php

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ final class Connection extends \Doctrine\DBAL\Connection
3232
private $mapperLocator;
3333

3434
/**
35-
* @var ObjectGraph
35+
* @var EntityStates
3636
*/
3737
private $objectGraph;
3838

@@ -108,31 +108,13 @@ public function createUnitOfWork(){
108108
}
109109

110110
/**
111-
* @return ObjectGraph
111+
* @return EntityStates
112112
*/
113113
public function getObjectGraph(){
114114
if(null === $this->objectGraph){
115-
$this->objectGraph = new ObjectGraph($this);
115+
$this->objectGraph = new EntityStates($this);
116116
}
117117
return $this->objectGraph;
118118
}
119119

120-
/**
121-
* @return array
122-
*/
123-
public function getEntityStateGraph(){
124-
$objectGraph = $this->getObjectGraph();
125-
$graph = [];
126-
127-
foreach ($this->identityMap as $identityMap){
128-
$identities = $identityMap->toArray();
129-
130-
foreach ($identities as $id => $object){
131-
$graph[get_class($object)][$id] = $objectGraph->getState($object);
132-
}
133-
}
134-
135-
return $graph;
136-
}
137-
138120
}

src/ObjectGraph.php renamed to src/EntityStates.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Hawkbit\Storage;
1010

11-
class ObjectGraph
11+
final class EntityStates
1212
{
1313

1414
const ADDED = 'added';
@@ -67,7 +67,7 @@ public function toArray(){
6767
$copy[get_class($object)] = $state;
6868
}
6969

70-
return $this->objectStorage->getInfo();
70+
return $copy;
7171
}
7272

7373
}

src/IdentityMap.php

Lines changed: 109 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@
1313
use OutOfBoundsException;
1414
use SplObjectStorage;
1515

16-
class IdentityMap
16+
final class IdentityMap
1717
{
1818

19+
const ADDED = 'added';
20+
const MODIFIED = 'modified';
21+
const REMOVED = 'removed';
22+
const UNHANDLED = 'unhandled';
23+
1924
/**
2025
* @var ArrayObject
2126
*/
@@ -26,11 +31,54 @@ class IdentityMap
2631
*/
2732
protected $objectToId;
2833

34+
/**
35+
* @var ArrayObject
36+
*/
37+
private $removed;
38+
2939
public function __construct()
3040
{
3141
$this->objectToId = new SplObjectStorage();
3242
$this->idToObject = new ArrayObject();
3343
$this->removed = new ArrayObject();
44+
$this->objectStorage = new \SplObjectStorage();
45+
}
46+
47+
/**
48+
* @param $object
49+
*/
50+
private function add($object)
51+
{
52+
$this->objectStorage[$object] = self::ADDED;
53+
}
54+
55+
/**
56+
* @param $object
57+
*/
58+
private function modify($object)
59+
{
60+
$this->objectStorage[$object] = self::MODIFIED;
61+
}
62+
63+
/**
64+
* @param $object
65+
*/
66+
private function delete($object)
67+
{
68+
$this->objectStorage[$object] = self::REMOVED;
69+
}
70+
71+
/**
72+
* @param $object
73+
* @return object|string
74+
*/
75+
public function getState($object)
76+
{
77+
if (isset($this->objectStorage[$object])) {
78+
return $this->objectStorage[$object];
79+
}
80+
81+
return self::UNHANDLED;
3482
}
3583

3684
/**
@@ -39,6 +87,19 @@ public function __construct()
3987
*/
4088
public function set($id, $object)
4189
{
90+
if ($this->hasObject($object)) {
91+
$this->modify($object);
92+
}else{
93+
$this->add($object);
94+
}
95+
96+
// remove old id's
97+
if($this->hasObject($object)){
98+
if($this->getId($object) !== $id){
99+
$this->removeId($id);
100+
}
101+
}
102+
42103
$this->idToObject[$id] = $object;
43104
$this->objectToId[$object] = $id;
44105
}
@@ -93,38 +154,72 @@ public function getObject($id)
93154
}
94155

95156
/**
157+
* Remove link from object to id
96158
* @param $object
97159
*/
98-
public function removeObject($object)
160+
private function removeObject($object)
99161
{
100-
if (false === $this->hasObject($object)) {
101-
$id = $this->getId($object);
162+
if ($this->hasObject($object)) {
102163
unset($this->objectToId[$object]);
103-
unset($this->idToObject[$id]);
104-
$this->removed[$id] = $object;
105164
}
106165
}
107166

108167
/**
168+
* Remove link from id to object
109169
* @param $id
110170
*/
111-
public function removeId($id)
171+
private function removeId($id)
112172
{
113173
if ($this->hasId($id)) {
114-
$object = $this->getObject($id);
115-
unset($this->objectToId[$object]);
116174
unset($this->idToObject[$id]);
117-
$this->removed[$id] = $object;
118175
}
119176
}
120177

178+
/**
179+
* remove object by id
180+
* @param $id
181+
* @param $object
182+
*/
183+
public function remove($id, $object){
184+
$this->removeId($id);
185+
$this->removeObject($object);
186+
$this->removed[$id] = $object;
187+
188+
//update object state
189+
$this->delete($object);
190+
}
191+
192+
/**
193+
* @return array
194+
*/
195+
public function getModified()
196+
{
197+
return $this->idToObject->getArrayCopy();
198+
}
199+
121200
/**
122201
* @return array
123202
*/
124-
public function toArray()
203+
public function getRemoved()
125204
{
126-
$modified = $this->idToObject->getArrayCopy();
127-
$removed = $this->removed->getArrayCopy();
128-
return array_replace($modified, $removed);
205+
return $this->removed->getArrayCopy();
206+
}
207+
208+
/**
209+
* @return array
210+
*/
211+
public function getGraph()
212+
{
213+
$graph = [];
214+
215+
$modified = $this->getModified();
216+
$removed = $this->getRemoved();
217+
$identities = array_replace($modified, $removed);
218+
219+
foreach ($identities as $id => $object) {
220+
$graph[get_class($object)][$id] = $this->getState($object);
221+
}
222+
223+
return $graph;
129224
}
130225
}

src/UnitOfWork.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ public function getException()
8181
*/
8282
public function update($object)
8383
{
84+
85+
if ($this->isDeleted($object)) {
86+
throw new \InvalidArgumentException('Cannot register as new, object is marked for deletion.');
87+
}
88+
if ($this->isUpdated($object)) {
89+
throw new \InvalidArgumentException('Cannot register as new, object is marked as updated.');
90+
}
91+
8492
$mapper = $this->connection->loadMapper($object);
8593
$data = $mapper->getHydrator()->extract($object);
8694

@@ -105,12 +113,13 @@ public function create($object)
105113
throw new \InvalidArgumentException('Cannot register as new, object is marked for deletion.');
106114
}
107115
if ($this->isUpdated($object)) {
108-
throw new \InvalidArgumentException('Cannot register as new, object is marked as dirty.');
116+
throw new \InvalidArgumentException('Cannot register as new, object is marked as updated.');
109117
}
110118
if ($this->isNew($object)) {
111119
throw new \InvalidArgumentException('Cannot register as new, object is already marked as new.');
112120
}
113121

122+
$this->connection->loadMapper($object)->getIdentityMap()->set(0, $object);
114123
$this->newObjects[ spl_object_hash($object) ] = $object;
115124
}
116125
/**

tests/IntegrationTest.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
namespace Hawkbit\Storage\Tests;
1010

11-
use Doctrine\DBAL\Types\Type;
12-
use Hawkbit\Storage\AbstractMapper;
1311
use Hawkbit\Storage\Connection;
1412
use Hawkbit\Storage\ConnectionManager;
1513
use Hawkbit\Storage\Tests\Stubs\PostEntity;
@@ -63,7 +61,6 @@ public function testIntegration()
6361

6462
/** @var PostEntity $createdEntity */
6563
$createdEntity = $mapper->create($entity);
66-
$graph = $connection->getEntityStateGraph();
6764

6865
$this->assertEquals($connection->lastInsertId(), $entity->getId());
6966
$this->assertEquals($entity, $createdEntity);
@@ -82,7 +79,6 @@ public function testIntegration()
8279

8380
/** @var PostEntity $updatedEntity */
8481
$updatedEntity = $mapper->update($entity);
85-
$graph = $connection->getEntityStateGraph();
8682

8783
$this->assertEquals($entity, $updatedEntity);
8884
$this->assertEquals($updatedEntity->getContent(), 'FOO');
@@ -93,8 +89,6 @@ public function testIntegration()
9389

9490
$mapper->delete($entity);
9591

96-
$graph = $connection->getEntityStateGraph();
97-
9892
if(true){
9993

10094
}

0 commit comments

Comments
 (0)