From 6943ade32ba459c9bd2da1a3ab37a866c3b293ff Mon Sep 17 00:00:00 2001 From: dmitry krokhin Date: Wed, 10 Jul 2024 13:38:26 +0300 Subject: [PATCH] find or create using cache --- src/Space.php | 51 +++++++++++++++++++++++++++++++++----------- tests/MapperTest.php | 11 ++++++++++ 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/Space.php b/src/Space.php index bc8689c..7fcc92a 100644 --- a/src/Space.php +++ b/src/Space.php @@ -153,18 +153,7 @@ public function drop() public function find(Criteria|array|null $criteria = null, ?int $limit = null): array { - if (!$criteria) { - $criteria = Criteria::allIterator(); - } elseif (is_array($criteria)) { - $index = $this->castIndex(array_keys($criteria)); - $criteria = Criteria::eqIterator() - ->andIndex($index['iid']) - ->andKey($this->getKey($criteria, $index)); - } - - if ($limit) { - $criteria = $criteria->andLimit($limit); - } + $criteria = $this->getCriteria($criteria, $limit); $item = null; if ($this->cache) { @@ -195,6 +184,15 @@ public function findOne(Criteria|array|null $criteria = null) public function findOrCreate(array $query, ?array $data = null) { + if ($this->cache) { + $instance = $this->findOne($query); + if ($instance) { + return $instance; + } + $criteria = $this->getCriteria($query, 1); + $this->cache->deleteItem(md5(serialize($criteria))); + } + if ($data == null) { $data = $query; } else { @@ -230,6 +228,7 @@ public function findOrCreate(array $query, ?array $data = null) 'id_key' => array_search('id', $this->fields) + 1 ] ); + if (!$present) { $this->mapper->middleware->register( new InsertRequest($this->id, $tuple), @@ -237,7 +236,15 @@ public function findOrCreate(array $query, ?array $data = null) ); } - return $this->getInstance($tuple); + $instance = $this->getInstance($tuple); + if ($this->cache) { + $criteria = $this->getCriteria($query, 1); + $item = $this->cache->getItem(md5(serialize($criteria))); + $item->set([$instance]); + $this->cache->save($item); + } + + return $instance; } public function findOrFail(Criteria|array|null $criteria = null) @@ -250,6 +257,24 @@ public function findOrFail(Criteria|array|null $criteria = null) throw new Exception("Not found"); } + public function getCriteria(Criteria|array|null $criteria = null, ?int $limit = null): Criteria + { + if (!$criteria) { + $criteria = Criteria::allIterator(); + } elseif (is_array($criteria)) { + $index = $this->castIndex(array_keys($criteria)); + $criteria = Criteria::eqIterator() + ->andIndex($index['iid']) + ->andKey($this->getKey($criteria, $index)); + } + + if ($limit) { + $criteria = $criteria->andLimit($limit); + } + + return $criteria; + } + public function getFieldFormat(string $name): array { foreach ($this->format as $field) { diff --git a/tests/MapperTest.php b/tests/MapperTest.php index c6f9f98..2669af2 100644 --- a/tests/MapperTest.php +++ b/tests/MapperTest.php @@ -65,6 +65,17 @@ public function testCache() $mapper->find('_vspace'); $this->assertCount(1, $cache->getValues()); $this->assertCount($queries, $this->middleware->data); + + $tester = $mapper->createSpace('tester'); + $tester->addProperty('id', 'unsigned'); + $tester->cache = new ArrayAdapter(); + $mapper->findOrCreate('tester', []); // created + $queries = count($this->middleware->data); + $mapper->findOrCreate('tester', []); + $mapper->findOrCreate('tester', []); + $mapper->findOrCreate('tester', []); + $mapper->findOrCreate('tester', []); + $this->assertCount($queries, $this->middleware->data); } public function testDifferentIndexPartConfiguration()