diff --git a/src/Api.php b/src/Api.php index 3fd1a9e..47ff6d9 100644 --- a/src/Api.php +++ b/src/Api.php @@ -9,15 +9,18 @@ trait Api { - abstract public function getSpace(string $name): Space; + abstract public function getSpace(object|int|string $id): Space; public function create(string $space, array $data) { return $this->getSpace($space)->create($data); } - public function delete(string $space, $instance) + public function delete(object|string $space, array|object|null $instance = null) { + if (is_object($space)) { + $instance = $space; + } $this->getSpace($space)->delete($instance); } @@ -50,8 +53,11 @@ public function get(string $space, int $id, bool $require = true) return $this->getSpace($space)->findOne(compact('id')); } - public function update(string $space, $instance, Operations|array $operations) + public function update(string|object $space, object|array $instance, Operations|array|null $operations = null) { + if (is_object($space)) { + [$instance, $operations] = [$space, $instance]; + } $this->getSpace($space)->update($instance, $operations); } } diff --git a/src/Mapper.php b/src/Mapper.php index 11b0f12..9d8f035 100644 --- a/src/Mapper.php +++ b/src/Mapper.php @@ -143,12 +143,16 @@ public function getClassSpace(int|string $class): int|string return $class; } - public function getSpace(int|string $id): Space + public function getSpace(object|int|string $id): Space { if (!count($this->spaces)) { $this->setSchemaId(0); } + if (is_object($id)) { + $id = get_class($id); + } + $space = $this->getClassSpace($id); if ($space !== $id) { if (!$this->hasSpace($space)) { diff --git a/src/Pool.php b/src/Pool.php index 01cbcbb..ac4c3cb 100644 --- a/src/Pool.php +++ b/src/Pool.php @@ -5,6 +5,7 @@ namespace Tarantool\Mapper; use Closure; +use LogicException; class Pool { @@ -13,7 +14,8 @@ class Pool private array $mappers = []; public function __construct( - public readonly Closure $callback + public readonly Closure $mapperFactory, + public readonly ?Closure $spaceCasting = null ) { } @@ -40,15 +42,24 @@ public function getChanges(): array public function getMapper(string $name): Mapper { if (!array_key_exists($name, $this->mappers)) { - $callback = $this->callback; + $callback = $this->mapperFactory; $this->mappers[$name] = $callback($name); } return $this->mappers[$name]; } - public function getSpace(string $name): Space + public function getSpace(object|int|string $name): Space { + if (is_object($name) && $this->spaceCasting) { + $callback = $this->spaceCasting; + $name = $callback($name); + } + + if (!is_string($name)) { + throw new LogicException("Space should be a string"); + } + [$mapper, $space] = explode('.', $name); return $this->getMapper($mapper)->getSpace($space); } diff --git a/tests/MapperTest.php b/tests/MapperTest.php index 00e3649..c3623d7 100644 --- a/tests/MapperTest.php +++ b/tests/MapperTest.php @@ -46,6 +46,14 @@ public function testClassBased() $mapper->registerClass(TypedConstructor::class); $this->assertInstanceOf(TypedConstructor::class, $mapper->findOne('constructor')); $this->assertEquals($row, $mapper->findOne('constructor')); + + $constructor = $mapper->findOne('constructor'); + + $mapper->update($constructor, ['nick' => 'space casting']); + $this->assertSame($constructor->nick, 'space casting'); + + $mapper->delete($constructor); + $this->assertNull($mapper->findOne('constructor')); } public function testAttribute() @@ -490,14 +498,20 @@ public function testSpaces() $pool = new Pool(function () use ($mapper) { return $mapper; + }, function ($instance) use ($mapper) { + $name = get_class($instance)::getSpaceName(); + return "prefix.$name"; }); $pool->create('first.array', ['nick' => 'qwerty']); - $pool->create('second.constructor', ['nick' => 'asdf']); + $constructor = $pool->create('second.constructor', ['nick' => 'asdf']); $changes = $pool->getChanges(); $this->assertCount(4, $changes); $this->assertSame($changes[0]->space, 'first.array'); $this->assertSame($changes[2]->space, 'second.array'); + + // validate pool space casting + $pool->update($constructor, ['nick' => 'tester']); } }