Skip to content

Commit 06fa71d

Browse files
authored
Merge pull request #170 from Kharhamel/emptyIterator
create empty resultIterator
2 parents 42e2f4f + 372e6b2 commit 06fa71d

File tree

7 files changed

+177
-49
lines changed

7 files changed

+177
-49
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
},
8282
"extra": {
8383
"branch-alias": {
84-
"dev-master": "5.1.x-dev"
84+
"dev-master": "5.2.x-dev"
8585
}
8686
},
8787
"minimum-stability": "dev",

src/InnerResultArray.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class InnerResultArray extends InnerResultIterator
5353
*/
5454
public function offsetExists($offset)
5555
{
56+
if ($this->count === 0) {
57+
return false;
58+
}
5659
try {
5760
$this->toIndex($offset);
5861
} catch (TDBMInvalidOffsetException $e) {
@@ -122,6 +125,9 @@ public function next()
122125
*/
123126
public function rewind()
124127
{
128+
if ($this->count === 0) {
129+
return;
130+
}
125131
if (!$this->fetchStarted) {
126132
$this->executeQuery();
127133
}

src/InnerResultIterator.php

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Doctrine\DBAL\Statement;
88
use Mouf\Database\MagicQuery;
99
use Psr\Log\LoggerInterface;
10+
use Psr\Log\NullLogger;
1011
use TheCodingMachine\TDBM\Utils\DbalUtils;
1112

1213
/*
@@ -65,23 +66,39 @@ class InnerResultIterator implements \Iterator, \Countable, \ArrayAccess
6566
*/
6667
private $logger;
6768

69+
protected $count = null;
70+
71+
private function __construct()
72+
{
73+
}
74+
6875
/**
6976
* @param mixed[] $parameters
7077
* @param array[] $columnDescriptors
7178
*/
72-
public function __construct(string $magicSql, array $parameters, ?int $limit, ?int $offset, array $columnDescriptors, ObjectStorageInterface $objectStorage, ?string $className, TDBMService $tdbmService, MagicQuery $magicQuery, LoggerInterface $logger)
79+
public static function createInnerResultIterator(string $magicSql, array $parameters, ?int $limit, ?int $offset, array $columnDescriptors, ObjectStorageInterface $objectStorage, ?string $className, TDBMService $tdbmService, MagicQuery $magicQuery, LoggerInterface $logger): self
7380
{
74-
$this->magicSql = $magicSql;
75-
$this->objectStorage = $objectStorage;
76-
$this->className = $className;
77-
$this->tdbmService = $tdbmService;
78-
$this->parameters = $parameters;
79-
$this->limit = $limit;
80-
$this->offset = $offset;
81-
$this->columnDescriptors = $columnDescriptors;
82-
$this->magicQuery = $magicQuery;
83-
$this->databasePlatform = $this->tdbmService->getConnection()->getDatabasePlatform();
84-
$this->logger = $logger;
81+
$iterator = new static();
82+
$iterator->magicSql = $magicSql;
83+
$iterator->objectStorage = $objectStorage;
84+
$iterator->className = $className;
85+
$iterator->tdbmService = $tdbmService;
86+
$iterator->parameters = $parameters;
87+
$iterator->limit = $limit;
88+
$iterator->offset = $offset;
89+
$iterator->columnDescriptors = $columnDescriptors;
90+
$iterator->magicQuery = $magicQuery;
91+
$iterator->databasePlatform = $iterator->tdbmService->getConnection()->getDatabasePlatform();
92+
$iterator->logger = $logger;
93+
return $iterator;
94+
}
95+
96+
public static function createEmpyIterator(): self
97+
{
98+
$iterator = new static();
99+
$iterator->count = 0;
100+
$iterator->logger = new NullLogger();
101+
return $iterator;
85102
}
86103

87104
private function getQuery(): string
@@ -102,7 +119,6 @@ protected function executeQuery(): void
102119
$this->fetchStarted = true;
103120
}
104121

105-
private $count = null;
106122
/**
107123
* Counts found records (this is the number of records fetched, taking into account the LIMIT and OFFSET settings).
108124
*
@@ -242,6 +258,9 @@ public function next()
242258
*/
243259
public function rewind()
244260
{
261+
if ($this->count === 0) {
262+
return;
263+
}
245264
$this->executeQuery();
246265
$this->key = -1;
247266
$this->next();
@@ -253,6 +272,9 @@ public function rewind()
253272
*/
254273
public function valid()
255274
{
275+
if ($this->count === 0) {
276+
return false;
277+
}
256278
return $this->current !== null;
257279
}
258280

@@ -311,7 +333,7 @@ public function offsetGet($offset)
311333
*/
312334
public function offsetSet($offset, $value)
313335
{
314-
throw new TDBMInvalidOperationException('You can set values in a TDBM result set.');
336+
throw new TDBMInvalidOperationException('You cannot set values in a TDBM result set.');
315337
}
316338

317339
/**
@@ -327,6 +349,6 @@ public function offsetSet($offset, $value)
327349
*/
328350
public function offsetUnset($offset)
329351
{
330-
throw new TDBMInvalidOperationException('You can unset values in a TDBM result set.');
352+
throw new TDBMInvalidOperationException('You cannot unset values in a TDBM result set.');
331353
}
332354
}

src/PageIterator.php

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Mouf\Database\MagicQuery;
88
use Porpaginas\Page;
99
use Psr\Log\LoggerInterface;
10+
use Psr\Log\NullLogger;
1011

1112
/*
1213
Copyright (C) 2006-2017 David Négrier - THE CODING MACHINE
@@ -67,24 +68,38 @@ class PageIterator implements Page, \ArrayAccess, \JsonSerializable
6768
*/
6869
private $logger;
6970

71+
private function __construct()
72+
{
73+
}
74+
7075
/**
7176
* @param mixed[] $parameters
7277
* @param array[] $columnDescriptors
7378
*/
74-
public function __construct(ResultIterator $parentResult, string $magicSql, array $parameters, int $limit, int $offset, array $columnDescriptors, ObjectStorageInterface $objectStorage, ?string $className, TDBMService $tdbmService, MagicQuery $magicQuery, int $mode, LoggerInterface $logger)
79+
public static function createResultIterator(ResultIterator $parentResult, string $magicSql, array $parameters, int $limit, int $offset, array $columnDescriptors, ObjectStorageInterface $objectStorage, ?string $className, TDBMService $tdbmService, MagicQuery $magicQuery, int $mode, LoggerInterface $logger): self
7580
{
76-
$this->parentResult = $parentResult;
77-
$this->magicSql = $magicSql;
78-
$this->objectStorage = $objectStorage;
79-
$this->className = $className;
80-
$this->tdbmService = $tdbmService;
81-
$this->parameters = $parameters;
82-
$this->limit = $limit;
83-
$this->offset = $offset;
84-
$this->columnDescriptors = $columnDescriptors;
85-
$this->magicQuery = $magicQuery;
86-
$this->mode = $mode;
87-
$this->logger = $logger;
81+
$iterator = new self();
82+
$iterator->parentResult = $parentResult;
83+
$iterator->magicSql = $magicSql;
84+
$iterator->objectStorage = $objectStorage;
85+
$iterator->className = $className;
86+
$iterator->tdbmService = $tdbmService;
87+
$iterator->parameters = $parameters;
88+
$iterator->limit = $limit;
89+
$iterator->offset = $offset;
90+
$iterator->columnDescriptors = $columnDescriptors;
91+
$iterator->magicQuery = $magicQuery;
92+
$iterator->mode = $mode;
93+
$iterator->logger = $logger;
94+
return $iterator;
95+
}
96+
97+
public static function createEmpyIterator(ResultIterator $parentResult): self
98+
{
99+
$iterator = new self();
100+
$iterator->parentResult = $parentResult;
101+
$iterator->logger = new NullLogger();
102+
return $iterator;
88103
}
89104

90105
/**
@@ -100,10 +115,12 @@ public function __construct(ResultIterator $parentResult, string $magicSql, arra
100115
public function getIterator()
101116
{
102117
if ($this->innerResultIterator === null) {
103-
if ($this->mode === TDBMService::MODE_CURSOR) {
104-
$this->innerResultIterator = new InnerResultIterator($this->magicSql, $this->parameters, $this->limit, $this->offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
118+
if ($this->parentResult->count() === 0) {
119+
$this->innerResultIterator = InnerResultIterator::createEmpyIterator();
120+
} elseif ($this->mode === TDBMService::MODE_CURSOR) {
121+
$this->innerResultIterator = InnerResultIterator::createInnerResultIterator($this->magicSql, $this->parameters, $this->limit, $this->offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
105122
} else {
106-
$this->innerResultIterator = new InnerResultArray($this->magicSql, $this->parameters, $this->limit, $this->offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
123+
$this->innerResultIterator = InnerResultArray::createInnerResultIterator($this->magicSql, $this->parameters, $this->limit, $this->offset, $this->columnDescriptors, $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
107124
}
108125
}
109126

@@ -173,6 +190,9 @@ public function toArray(): array
173190
*/
174191
public function map(callable $callable): MapIterator
175192
{
193+
if ($this->count() === 0) {
194+
return new MapIterator([], $callable);
195+
}
176196
return new MapIterator($this->getIterator(), $callable);
177197
}
178198

src/ResultIterator.php

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace TheCodingMachine\TDBM;
55

6+
use Psr\Log\NullLogger;
67
use function array_map;
78
use Doctrine\DBAL\Connection;
89
use Doctrine\DBAL\Statement;
@@ -66,23 +67,37 @@ class ResultIterator implements Result, \ArrayAccess, \JsonSerializable
6667

6768
private $logger;
6869

70+
private function __construct()
71+
{
72+
}
73+
6974
/**
7075
* @param mixed[] $parameters
7176
*/
72-
public function __construct(QueryFactory $queryFactory, array $parameters, ObjectStorageInterface $objectStorage, ?string $className, TDBMService $tdbmService, MagicQuery $magicQuery, int $mode, LoggerInterface $logger)
77+
public static function createResultIterator(QueryFactory $queryFactory, array $parameters, ObjectStorageInterface $objectStorage, ?string $className, TDBMService $tdbmService, MagicQuery $magicQuery, int $mode, LoggerInterface $logger): self
7378
{
79+
$iterator = new self();
7480
if ($mode !== TDBMService::MODE_CURSOR && $mode !== TDBMService::MODE_ARRAY) {
7581
throw new TDBMException("Unknown fetch mode: '".$mode."'");
7682
}
7783

78-
$this->queryFactory = $queryFactory;
79-
$this->objectStorage = $objectStorage;
80-
$this->className = $className;
81-
$this->tdbmService = $tdbmService;
82-
$this->parameters = $parameters;
83-
$this->magicQuery = $magicQuery;
84-
$this->mode = $mode;
85-
$this->logger = $logger;
84+
$iterator->queryFactory = $queryFactory;
85+
$iterator->objectStorage = $objectStorage;
86+
$iterator->className = $className;
87+
$iterator->tdbmService = $tdbmService;
88+
$iterator->parameters = $parameters;
89+
$iterator->magicQuery = $magicQuery;
90+
$iterator->mode = $mode;
91+
$iterator->logger = $logger;
92+
return $iterator;
93+
}
94+
95+
public static function createEmpyIterator(): self
96+
{
97+
$iterator = new self();
98+
$iterator->totalCount = 0;
99+
$iterator->logger = new NullLogger();
100+
return $iterator;
86101
}
87102

88103
protected function executeCountQuery(): void
@@ -113,6 +128,9 @@ public function count(): int
113128
*/
114129
public function toArray(): array
115130
{
131+
if ($this->totalCount === 0) {
132+
return [];
133+
}
116134
return iterator_to_array($this->getIterator());
117135
}
118136

@@ -125,6 +143,9 @@ public function toArray(): array
125143
*/
126144
public function map(callable $callable): MapIterator
127145
{
146+
if ($this->totalCount === 0) {
147+
return new MapIterator([], $callable);
148+
}
128149
return new MapIterator($this->getIterator(), $callable);
129150
}
130151

@@ -141,10 +162,12 @@ public function map(callable $callable): MapIterator
141162
public function getIterator()
142163
{
143164
if ($this->innerResultIterator === null) {
144-
if ($this->mode === TDBMService::MODE_CURSOR) {
145-
$this->innerResultIterator = new InnerResultIterator($this->queryFactory->getMagicSql(), $this->parameters, null, null, $this->queryFactory->getColumnDescriptors(), $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
165+
if ($this->totalCount === 0) {
166+
$this->innerResultIterator = InnerResultArray::createEmpyIterator();
167+
} elseif ($this->mode === TDBMService::MODE_CURSOR) {
168+
$this->innerResultIterator = InnerResultIterator::createInnerResultIterator($this->queryFactory->getMagicSql(), $this->parameters, null, null, $this->queryFactory->getColumnDescriptors(), $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
146169
} else {
147-
$this->innerResultIterator = new InnerResultArray($this->queryFactory->getMagicSql(), $this->parameters, null, null, $this->queryFactory->getColumnDescriptors(), $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
170+
$this->innerResultIterator = InnerResultArray::createInnerResultIterator($this->queryFactory->getMagicSql(), $this->parameters, null, null, $this->queryFactory->getColumnDescriptors(), $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->logger);
148171
}
149172
}
150173

@@ -159,7 +182,10 @@ public function getIterator()
159182
*/
160183
public function take($offset, $limit)
161184
{
162-
return new PageIterator($this, $this->queryFactory->getMagicSql(), $this->parameters, $limit, $offset, $this->queryFactory->getColumnDescriptors(), $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->mode, $this->logger);
185+
if ($this->totalCount === 0) {
186+
return PageIterator::createEmpyIterator($this);
187+
}
188+
return PageIterator::createResultIterator($this, $this->queryFactory->getMagicSql(), $this->parameters, $limit, $offset, $this->queryFactory->getColumnDescriptors(), $this->objectStorage, $this->className, $this->tdbmService, $this->magicQuery, $this->mode, $this->logger);
163189
}
164190

165191
/**
@@ -265,12 +291,15 @@ public function jsonSerialize($stopRecursion = false)
265291
*/
266292
public function first()
267293
{
294+
if ($this->totalCount === 0) {
295+
return null;
296+
}
268297
$page = $this->take(0, 1);
269298
foreach ($page as $bean) {
270299
return $bean;
271300
}
272301

273-
return;
302+
return null;
274303
}
275304

276305
/**
@@ -292,6 +321,9 @@ public function first()
292321
public function withOrder($orderBy) : ResultIterator
293322
{
294323
$clone = clone $this;
324+
if ($this->totalCount === 0) {
325+
return $clone;
326+
}
295327
$clone->queryFactory = clone $this->queryFactory;
296328
$clone->queryFactory->sort($orderBy);
297329
$clone->innerResultIterator = null;
@@ -313,6 +345,9 @@ public function withOrder($orderBy) : ResultIterator
313345
public function withParameters(array $parameters) : ResultIterator
314346
{
315347
$clone = clone $this;
348+
if ($this->totalCount === 0) {
349+
return $clone;
350+
}
316351
$clone->parameters = $parameters;
317352
$clone->innerResultIterator = null;
318353
$clone->totalCount = null;

src/TDBMService.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ public function findObjects(string $mainTable, $filter = null, array $parameters
11371137

11381138
$queryFactory = new FindObjectsQueryFactory($mainTable, $additionalTablesFetch, $filterString, $orderString, $this, $this->tdbmSchemaAnalyzer->getSchema(), $this->orderByAnalyzer, $this->cache);
11391139

1140-
return new ResultIterator($queryFactory, $parameters, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
1140+
return ResultIterator::createResultIterator($queryFactory, $parameters, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
11411141
}
11421142

11431143
/**
@@ -1170,7 +1170,7 @@ public function findObjectsFromSql(string $mainTable, string $from, $filter = nu
11701170

11711171
$queryFactory = new FindObjectsFromSqlQueryFactory($mainTable, $from, $filterString, $orderString, $this, $this->tdbmSchemaAnalyzer->getSchema(), $this->orderByAnalyzer, $this->schemaAnalyzer, $this->cache, $this->cachePrefix);
11721172

1173-
return new ResultIterator($queryFactory, $parameters, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
1173+
return ResultIterator::createResultIterator($queryFactory, $parameters, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
11741174
}
11751175

11761176
/**
@@ -1334,7 +1334,7 @@ public function findObjectsFromRawSql(string $mainTable, string $sql, array $par
13341334

13351335
$queryFactory = new FindObjectsFromRawSqlQueryFactory($this, $this->tdbmSchemaAnalyzer->getSchema(), $mainTable, $sql, $sqlCount);
13361336

1337-
return new ResultIterator($queryFactory, $parameters, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
1337+
return ResultIterator::createResultIterator($queryFactory, $parameters, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
13381338
}
13391339

13401340
/**

0 commit comments

Comments
 (0)