Skip to content

Commit

Permalink
Upgrade underlying queries component
Browse files Browse the repository at this point in the history
Queries component was upgraded to PHP 7.4 and changed one
interface function, we change the similar function here:
create new fetchAllAndFlatten function and remove flattenFields
option from query
  • Loading branch information
iquito committed Apr 26, 2020
1 parent c94f5f1 commit c262253
Show file tree
Hide file tree
Showing 25 changed files with 198 additions and 201 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"symfony/console": "^5.0",
"symfony/finder": "^5.0",
"doctrine/annotations": "^1.4",
"squirrelphp/queries": "^0.9"
"squirrelphp/queries": "^0.10"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.3",
Expand Down
2 changes: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ parameters:

-
message: "#^Parameter \\#1 \\$query of method Squirrel\\\\Queries\\\\DBInterface\\:\\:fetchAll\\(\\) expects array\\<string, array\\<int\\|string, mixed\\>\\|bool\\|int\\|string\\>\\|string, array\\<string, mixed\\> given\\.$#"
count: 1
count: 2
path: src/RepositoryReadOnly.php

3 changes: 2 additions & 1 deletion psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
</PossiblyInvalidArgument>
</file>
<file src="src/RepositoryReadOnly.php">
<ArgumentTypeCoercion occurrences="2">
<ArgumentTypeCoercion occurrences="3">
<code>$sanitizedQuery</code>
<code>$sanitizedQuery</code>
<code>$sanitizedQuery</code>
</ArgumentTypeCoercion>
Expand Down
5 changes: 1 addition & 4 deletions src/Action/MultiSelectEntries.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ public function where(array $whereClauses): self

/**
* @param array<int|string,string>|string $orderByClauses
* @return MultiSelectEntries
*/
public function orderBy($orderByClauses): self
{
Expand All @@ -123,7 +122,6 @@ public function orderBy($orderByClauses): self

/**
* @param array<int|string,string>|string $groupByClauses
* @return MultiSelectEntries
*/
public function groupBy($groupByClauses): self
{
Expand Down Expand Up @@ -197,7 +195,7 @@ public function getOneEntry(): ?array
*/
public function getFlattenedFields(): array
{
return $this->queryHandler->fetchAll([
return $this->queryHandler->fetchAllAndFlatten([
'fields' => $this->fields,
'repositories' => $this->repositories,
'tables' => $this->connections,
Expand All @@ -207,7 +205,6 @@ public function getFlattenedFields(): array
'limit' => $this->limitTo,
'offset' => $this->startAt,
'lock' => $this->blocking,
'flattenFields' => true,
]);
}

Expand Down
3 changes: 1 addition & 2 deletions src/Action/MultiSelectEntriesFreeform.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,11 @@ public function getFlattenedFields(): array
{
$this->makeSureBadPracticeWasConfirmed();

return $this->queryHandler->fetchAll([
return $this->queryHandler->fetchAllAndFlatten([
'fields' => $this->fields,
'repositories' => $this->repositories,
'query' => $this->query,
'parameters' => $this->parameters,
'flattenFields' => true,
]);
}

Expand Down
21 changes: 17 additions & 4 deletions src/Action/MultiSelectIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,27 @@ class MultiSelectIterator implements \Iterator, ActionInterface
{
use SelectIteratorTrait;

/** @var MultiRepositoryReadOnlyInterface */
private $source;
/** @var MultiRepositorySelectQueryInterface|null */
private $selectReference = null;
private MultiRepositoryReadOnlyInterface $source;
private ?MultiRepositorySelectQueryInterface $selectReference = null;
private ?array $lastResult = null;

public function __construct(MultiRepositoryReadOnlyInterface $repository, array $query)
{
$this->source = $repository;
$this->query = $query;
}

/**
* @return array<string,mixed>
*/
public function current(): array
{
// @codeCoverageIgnoreStart
if ($this->lastResult === null) {
throw new \LogicException('Cannot get current value if no result has been retrieved');
}
// @codeCoverageIgnoreEnd

return $this->lastResult;
}
}
3 changes: 1 addition & 2 deletions src/Action/SelectEntries.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,13 @@ public function getOneEntry(): ?object
*/
public function getFlattenedFields(): array
{
return $this->repository->fetchAll([
return $this->repository->fetchAllAndFlatten([
'where' => $this->where,
'order' => $this->orderBy,
'fields' => $this->fields,
'limit' => $this->limitTo,
'offset' => $this->startAt,
'lock' => $this->blocking,
'flattenFields' => true,
]);
}

Expand Down
18 changes: 14 additions & 4 deletions src/Action/SelectIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,24 @@ class SelectIterator implements \Iterator, ActionInterface
{
use SelectIteratorTrait;

/** @var RepositoryReadOnlyInterface */
private $source;
/** @var RepositorySelectQueryInterface|null */
private $selectReference = null;
private RepositoryReadOnlyInterface $source;
private ?RepositorySelectQueryInterface $selectReference = null;
private ?object $lastResult = null;

public function __construct(RepositoryReadOnlyInterface $repository, array $query)
{
$this->source = $repository;
$this->query = $query;
}

public function current(): object
{
// @codeCoverageIgnoreStart
if ($this->lastResult === null) {
throw new \LogicException('Cannot get current value if no result has been retrieved');
}
// @codeCoverageIgnoreEnd

return $this->lastResult;
}
}
8 changes: 7 additions & 1 deletion src/Generate/RepositoriesGenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,13 @@ public function __construct(\Squirrel\Entities\Action\SelectIterator $iterator)
public function current(): \{namespaceOfEntity}\{classOfEntity}
{
return $this->iteratorInstance->current();
$entry = $this->iteratorInstance->current();
if ($entry instanceof \{namespaceOfEntity}\{classOfEntity}) {
return $entry;
}
throw new \LogicException('Unexpected type encountered - wrong repository might be configured: ' . \get_class($entry));
}
public function next(): void
Expand Down
53 changes: 13 additions & 40 deletions src/MultiRepositoryReadOnly.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,6 @@ public function fetchOne(array $query): ?array

public function fetchAll(array $query): array
{
// Whether to flatten fields and just return an array of values instead of objects
if (isset($query['flattenFields'])) {
$flattenFields = $this->booleanSettingValidation($query['flattenFields'], 'flattenFields');
unset($query['flattenFields']);
}

// Freeform query was detected
if (isset($query['query']) || isset($query['parameters'])) {
[$sqlQuery, $parameters, $selectTypes, $selectTypesNullable] = $this->buildSelectQueryFreeform($query);
Expand All @@ -152,24 +146,24 @@ public function fetchAll(array $query): array
}

// Process the select results
$processedResults = $this->processSelectResults($tableResults, $selectTypes, $selectTypesNullable);
return $this->processSelectResults($tableResults, $selectTypes, $selectTypesNullable);
}

// Flatten all values into a one-dimensional array if requested
if (($flattenFields ?? false) === true) {
$list = [];
public function fetchAllAndFlatten(array $query): array
{
$processedResults = $this->fetchAll($query);

// Go through table results
foreach ($processedResults as $objIndex => $objEntry) {
// Go through all table fields
foreach ($objEntry as $fieldName => $fieldValue) {
$list[] = $fieldValue;
}
}
$list = [];

return $list;
// Go through table results
foreach ($processedResults as $objIndex => $objEntry) {
// Go through all table fields
foreach ($objEntry as $fieldName => $fieldValue) {
$list[] = $fieldValue;
}
}

return $processedResults;
return $list;
}

/**
Expand Down Expand Up @@ -1094,25 +1088,4 @@ protected function preprocessOrder(array $orderOptions, array $objectToTableFiel

return $orderProcessed;
}

/**
* @param mixed $shouldBeBoolean
*/
private function booleanSettingValidation($shouldBeBoolean, string $settingName): bool
{
// Make sure the setting is a boolean or at least an integer which can be clearly interpreted as boolean
if (
!\is_bool($shouldBeBoolean)
&& $shouldBeBoolean !== 1
&& $shouldBeBoolean !== 0
) {
throw Debug::createException(
DBInvalidOptionException::class,
[MultiRepositoryReadOnlyInterface::class, ActionInterface::class],
$settingName . ' set to a non-boolean value: ' . Debug::sanitizeData($shouldBeBoolean)
);
}

return \boolval($shouldBeBoolean);
}
}
18 changes: 12 additions & 6 deletions src/MultiRepositoryReadOnlyInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,20 @@ public function clear(MultiRepositorySelectQueryInterface $selectQuery): void;
public function fetchOne(array $query): ?array;

/**
* Select query and return all entries. The query options are the same as with the select function,
* except for flattenFields:
*
* 'flattenFields': Whether to return a one dimensional array of just values instead of arrays (optional)
* Select query and return all entries. The query options are the same as with the select function.
*
* @param array $query
* @psalm-param array{repositories:array,tables?:array,fields:array,where?:array,group?:array,order?:array,limit?:int,offset?:int,lock?:bool,query?:string,parameters?:array,flattenFields?:bool} $query
* @return array
* @psalm-param array{repositories:array,tables?:array,fields:array,where?:array,group?:array,order?:array,limit?:int,offset?:int,lock?:bool,query?:string,parameters?:array} $query
* @return array<int, array<string, mixed>>
*/
public function fetchAll(array $query): array;

/**
* Select query and return all entries as flattened values (no field names)
*
* @param array $query
* @psalm-param array{repositories:array,tables?:array,fields:array,where?:array,group?:array,order?:array,limit?:int,offset?:int,lock?:bool,query?:string,parameters?:array} $query
* @return array<bool|int|float|string|null>
*/
public function fetchAllAndFlatten(array $query): array;
}
42 changes: 28 additions & 14 deletions src/RepositoryReadOnly.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function select(array $query): RepositorySelectQueryInterface
}
}

public function fetch(RepositorySelectQueryInterface $selectQuery)
public function fetch(RepositorySelectQueryInterface $selectQuery): ?object
{
// Make sure the same repository configuration is used
$this->compareRepositoryConfigMustBeEqual($selectQuery->getConfig());
Expand Down Expand Up @@ -138,7 +138,7 @@ public function clear(RepositorySelectQueryInterface $selectQuery): void
}
}

public function fetchOne(array $query)
public function fetchOne(array $query): ?object
{
if (isset($query['limit']) && $query['limit'] !== 1) {
throw Debug::createException(
Expand All @@ -159,16 +159,35 @@ public function fetchOne(array $query)
return $result;
}

public function fetchAll(array $query)
public function fetchAll(array $query): array
{
$flattenFields = false;
// Process options and make sure all values are valid
$sanitizedQuery = $this->prepareSelectQueryForLowerLayer($this->validateQueryOptions([
'where' => [],
'order' => [],
'limit' => 0,
'offset' => 0,
'fields' => [],
'lock' => false,
], $query));

// Whether to flatten fields and just return an array of values instead of objects
if (isset($query['flattenFields'])) {
$flattenFields = $this->booleanSettingValidation($query['flattenFields'], 'flattenFields');
unset($query['flattenFields']);
try {
// Get all the data from the database
$tableResults = $this->db->fetchAll($sanitizedQuery);
} catch (DBException $e) {
throw Debug::createException(
\get_class($e),
[RepositoryReadOnlyInterface::class, ActionInterface::class],
$e->getMessage(),
$e->getPrevious()
);
}

return \array_map([$this, 'convertResultToObject'], $tableResults);
}

public function fetchAllAndFlatten(array $query): array
{
// Process options and make sure all values are valid
$sanitizedQuery = $this->prepareSelectQueryForLowerLayer($this->validateQueryOptions([
'where' => [],
Expand All @@ -191,12 +210,7 @@ public function fetchAll(array $query)
);
}

// Special case: Flatten all field values and return an array
if ($flattenFields === true) {
return $this->convertResultsToFlattenedResults($tableResults);
}

return \array_map([$this, 'convertResultToObject'], $tableResults);
return $this->convertResultsToFlattenedResults($tableResults);
}

/**
Expand Down
23 changes: 14 additions & 9 deletions src/RepositoryReadOnlyInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function select(array $query): RepositorySelectQueryInterface;
* @param RepositorySelectQueryInterface $selectQuery
* @return object|null One entity object, or an array of flattened fields
*/
public function fetch(RepositorySelectQueryInterface $selectQuery);
public function fetch(RepositorySelectQueryInterface $selectQuery): ?object;

/**
* Clear existing result set
Expand All @@ -64,15 +64,20 @@ public function clear(RepositorySelectQueryInterface $selectQuery): void;
* @psalm-param array{fields?:array<string>,field?:string,where?:array<int|string,mixed>,order?:array<int|string,string>,offset?:int,lock?:bool} $query
* @return object|null An entity object or null if no entry was found
*/
public function fetchOne(array $query);
public function fetchOne(array $query): ?object;

/**
* Find all entries and return them as objects
*
* $query can have the same values as with select function, with the addition of:
*
* 'flattenFields' (set to true or false, default is false):
* $query can have the same values as with the select function.
*
* @param array<string,mixed> $query Query parts as an array
* @psalm-param array{fields?:array<string>,field?:string,where?:array<int|string,mixed>,order?:array<int|string,string>,limit?:int,offset?:int,lock?:bool} $query
* @return array<int,object> A list of entity objects
*/
public function fetchAll(array $query): array;

/**
* Return results as flattened fields (no field names, no entries, just an array with
* the values), examples where this might be useful:
*
Expand All @@ -81,11 +86,11 @@ public function fetchOne(array $query);
* orders, or all email addresses associated with a user
*
* The flattened results can be run through array_unique to remove duplicates, if
* necessary - fetchAll does not that do that for you
* necessary - fetchAll does not do that for you
*
* @param array<string,mixed> $query Query parts as an array
* @psalm-param array{fields?:array<string>,field?:string,where?:array<int|string,mixed>,order?:array<int|string,string>,limit?:int,offset?:int,lock?:bool,flattenFields?:bool} $query
* @return array<int,mixed> A list of entity objects, or a list of flattened values
* @psalm-param array{fields?:array<string>,field?:string,where?:array<int|string,mixed>,order?:array<int|string,string>,limit?:int,offset?:int,lock?:bool} $query
* @return array<bool|int|float|string|null> A list of flattened values
*/
public function fetchAll(array $query);
public function fetchAllAndFlatten(array $query): array;
}
Loading

0 comments on commit c262253

Please sign in to comment.