Skip to content

Commit

Permalink
DB: add ResultFactory, rename ResultIterator to RowIterator [tests + …
Browse files Browse the repository at this point in the history
…doc]
  • Loading branch information
forrest79 committed Sep 30, 2024
1 parent 1e9cd68 commit ff538ca
Show file tree
Hide file tree
Showing 16 changed files with 290 additions and 101 deletions.
35 changes: 34 additions & 1 deletion docs/db.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,39 @@ $resource = $result->getResource();
assert($resource !== FALSE);
```

#### Use custom result factory

You can use your own result object. Your result object must `extends` existing `Result` object, and you must implement your own `ResultFactory` to create your own results. Then you can set your factory to the `Connection` and it will be used for all new query results.

```php
class MyOwnResult extends Forrest79\PhPgSql\Db\Result
{
public function age(): string
{
return $this->age . ' years';
}
}

class MyOwnResultFactory implements Forrest79\PhPgSql\Db\ResultFactory
{
public function createResult(Forrest79\PhPgSql\Db\ColumnValueParser $columnValueParser, array $rawValues): Forrest79\PhPgSql\Db\Result
{
return new MyOwnRow($columnValueParser, $rawValues);
}
}

$result = $connection->query('SELECT age FROM users WHERE id = 1');
$result->setResultFactory(new MyOwnResultFactory());
$row = $result->fetch();
dump($row->age()); // (string) '45 years'

$connection->setRowFactory(new MyOwnResultFactory());
$row = $connection->query('SELECT age FROM users WHERE id = 2')->fetch();
dump($row->age()); // (string) '24 years'
```

> By default, is used `Forrest79\PhPgSql\Db\ResultFactories\Basic` result factory that produces default `Result` objects.
#### Safely passing parameters

Important is to know how to safety pass parameters to a query. You can do something like this:
Expand Down Expand Up @@ -594,7 +627,7 @@ $result->setRowFactory(new MyOwnRowFactory());
$row = $result->fetch();
dump($row->age()); // (string) '45 years'

$connection->setDefaultRowFactory(new MyOwnRowFactory());
$connection->setRowFactory(new MyOwnRowFactory());
$row = $connection->query('SELECT age FROM users WHERE id = 2')->fetch();
dump($row->age()); // (string) '24 years'
```
Expand Down
60 changes: 39 additions & 21 deletions phpcs-ignores.neon
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,19 @@ ignoreErrors:
sniff: SlevomatCodingStandard.Classes.RequireAbstractOrFinal.ClassNeitherAbstractNorFinal
message: All classes should be declared using either the "abstract" or "final" keyword.
count: 1
path: src/Db/ResultIterator.php
path: src/Db/ResultBuilder.php

-
sniff: SlevomatCodingStandard.Classes.RequireAbstractOrFinal.ClassNeitherAbstractNorFinal
message: All classes should be declared using either the "abstract" or "final" keyword.
count: 1
path: src/Db/ResultFactories/Basic.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "create"
count: 1
path: src/Db/ResultFactory.php

-
sniff: SlevomatCodingStandard.Classes.RequireAbstractOrFinal.ClassNeitherAbstractNorFinal
Expand All @@ -251,6 +263,12 @@ ignoreErrors:
count: 1
path: src/Db/RowFactory.php

-
sniff: SlevomatCodingStandard.Classes.RequireAbstractOrFinal.ClassNeitherAbstractNorFinal
message: All classes should be declared using either the "abstract" or "final" keyword.
count: 1
path: src/Db/RowIterator.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "getParams"
Expand Down Expand Up @@ -371,6 +389,18 @@ ignoreErrors:
count: 1
path: src/Fluent/Sql.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "doNothing"
count: 1
path: src/Fluent/Sql.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "doUpdate"
count: 1
path: src/Fluent/Sql.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "except"
Expand Down Expand Up @@ -491,18 +521,6 @@ ignoreErrors:
count: 1
path: src/Fluent/Sql.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "doUpdate"
count: 1
path: src/Fluent/Sql.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "doNothing"
count: 1
path: src/Fluent/Sql.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "orderBy"
Expand Down Expand Up @@ -625,13 +643,13 @@ ignoreErrors:

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "whereIf"
message: Visibility must be declared on method "whereAnd"
count: 1
path: src/Fluent/Sql.php

-
sniff: Squiz.Scope.MethodScope.Missing
message: Visibility must be declared on method "whereAnd"
message: Visibility must be declared on method "whereIf"
count: 1
path: src/Fluent/Sql.php

Expand Down Expand Up @@ -684,22 +702,22 @@ ignoreErrors:
path: tests/Integration/CollectingResultsTest.php

-
sniff: PSR1.Files.SideEffects.FoundWithSymbols
message: 'A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line 15 and the first side effect is on line 9.'
sniff: SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter
message: Unused parameter $connection.
count: 1
path: tests/Integration/CustomPrepareQueryTest.php
path: tests/Integration/CollectingResultsTest.php

-
sniff: SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter
message: Unused parameter $connection.
sniff: PSR1.Files.SideEffects.FoundWithSymbols
message: 'A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line 15 and the first side effect is on line 9.'
count: 1
path: tests/Integration/CustomPrepareQueryTest.php

-
sniff: SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter
message: Unused parameter $connection.
count: 1
path: tests/Integration/CollectingResultsTest.php
path: tests/Integration/CustomPrepareQueryTest.php

-
sniff: PSR1.Files.SideEffects.FoundWithSymbols
Expand Down
12 changes: 6 additions & 6 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,16 @@ parameters:
path: %rootDir%/../../../src/Db/Result.php
count: 1

-
message: '#^Method Forrest79\\PhPgSql\\Db\\ResultIterator::current\(\) should return Forrest79\\PhPgSql\\Db\\Row but returns Forrest79\\PhPgSql\\Db\\Row\|null\.$#'
path: %rootDir%/../../../src/Db/ResultIterator.php
count: 1

-
message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#'
path: %rootDir%/../../../src/Db/Row.php
count: 3

-
message: '#^Method Forrest79\\PhPgSql\\Db\\RowIterator::current\(\) should return Forrest79\\PhPgSql\\Db\\Row but returns Forrest79\\PhPgSql\\Db\\Row\|null\.$#'
path: %rootDir%/../../../src/Db/RowIterator.php
count: 1

-
message: '#^Parameter \#2 \$expected of static method Forrest79\\PhPgSql\\Fluent\\Exceptions\\QueryBuilderException::badParamsCount\(\) expects int, int(\<0, max\>)?\|false(\|null)? given\.$#' # (|null)? is for forward PHP 8 compatibility
path: %rootDir%/../../../src/Fluent/QueryBuilder.php
Expand All @@ -208,6 +208,6 @@ parameters:
# === Fix PhPgSql-PHPStan rules ===

-
message: '#^Method Forrest79\\PhPgSql\\Fluent\\QueryExecute::getIterator\(\) should return Forrest79\\PhPgSql\\Db\\ResultIterator but returns iterable<int, Forrest79\\PhPgSql\\Db\\Row>\.$#'
message: '#^Method Forrest79\\PhPgSql\\Fluent\\QueryExecute::getIterator\(\) should return Forrest79\\PhPgSql\\Db\\RowIterator but returns iterable<int, Forrest79\\PhPgSql\\Db\\Row>\.$#'
path: %rootDir%/../../../src/Fluent/QueryExecute.php
count: 1
8 changes: 6 additions & 2 deletions src/Db/AsyncHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ public function __construct(Connection $connection)
}


public function createAndSetAsyncQuery(Query $query, string|NULL $preparedStatementName = NULL): AsyncQuery
public function createAndSetAsyncQuery(
ResultBuilder $resultBuilder,
Query $query,
string|NULL $preparedStatementName = NULL,
): AsyncQuery
{
$this->asyncQuery = new AsyncQuery($this->connection, $this, $query, $preparedStatementName);
$this->asyncQuery = new AsyncQuery($this->connection, $resultBuilder, $this, $query, $preparedStatementName);
$this->asyncExecuteQuery = NULL;

return $this->asyncQuery;
Expand Down
12 changes: 9 additions & 3 deletions src/Db/AsyncPreparedStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ class AsyncPreparedStatement extends PreparedStatementHelper
private AsyncHelper $asyncHelper;


public function __construct(Connection $connection, AsyncHelper $asyncHelper, Events $events, string $query)
public function __construct(
AsyncHelper $asyncHelper,
Connection $connection,
ResultBuilder $resultBuilder,
Events $events,
string $query,
)
{
parent::__construct($connection, $events, $query);
parent::__construct($connection, $resultBuilder, $events, $query);
$this->asyncHelper = $asyncHelper;
}

Expand Down Expand Up @@ -45,7 +51,7 @@ public function executeArgs(array $params): AsyncQuery
$this->events->onQuery($query, NULL, $statementName);
}

return $this->asyncHelper->createAndSetAsyncQuery($query, $statementName);
return $this->asyncHelper->createAndSetAsyncQuery($this->resultBuilder, $query, $statementName);
}


Expand Down
6 changes: 5 additions & 1 deletion src/Db/AsyncQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class AsyncQuery
{
private Connection $connection;

private ResultBuilder $resultBuilder;

private AsyncHelper $asyncHelper;

private Query $query;
Expand All @@ -15,12 +17,14 @@ class AsyncQuery

public function __construct(
Connection $connection,
ResultBuilder $resultBuilder,
AsyncHelper $asyncHelper,
Query $query,
string|NULL $preparedStatementName = NULL,
)
{
$this->connection = $connection;
$this->resultBuilder = $resultBuilder;
$this->asyncHelper = $asyncHelper;
$this->query = $query;
$this->preparedStatementName = $preparedStatementName;
Expand Down Expand Up @@ -67,7 +71,7 @@ public function getNextResult(): Result
}
}

return $this->connection->createResult($resource, $this->getQuery());
return $this->resultBuilder->buildResult($resource, $this->getQuery());
}

}
Loading

0 comments on commit ff538ca

Please sign in to comment.