Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,21 +308,16 @@ composer require nyholm/psr7 nyholm/psr7-server kriswallsmith/buzz

## Result formats/hydration

In order to make the results of the bolt protocol and the http uniform, the driver provides result formatters (aka hydrators). The client is configurable with these formatters. You can even implement your own.
In order to make the results of the bolt protocol and the http uniform, the driver provides a summarizes the results.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be: provides and summarizes ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like it to me too! It's probably a simple typo. Good catch @stefanak-michal


The default formatter is the `\Laudis\Neo4j\Formatters\OGMFormatter`, which is explained extensively in [the result format section](#accessing-the-results).
The default formatter is the `\Laudis\Neo4j\Formatters\SummarizedResultFormatter`, which is explained extensively in [the result format section](#accessing-the-results).

The driver provides three formatters by default, which are all found in the Formatter namespace:
- `\Laudis\Neo4j\Formatter\BasicFormatter` which erases all the Cypher types and simply returns every value in the resulting map as a [scalar](https://www.php.net/manual/en/function.is-scalar.php), null or array value.
- `\Laudis\Neo4j\Formatter\OGMFormatter` which maps the cypher types to php types as explained [here](#accessing-the-results).
- `\Laudis\Neo4j\Formatter\SummarizedResultFormatter` which decorates any formatter and adds an extensive result summary.
`\Laudis\Neo4j\Formatter\SummarizedResultFormatter` adds an extensive result summary.

The client builder provides an easy way to change the formatter:

```php
$client = \Laudis\Neo4j\ClientBuilder::create()
->withFormatter(\Laudis\Neo4j\Formatter\SummarizedResultFormatter::create())
->build();
$client = \Laudis\Neo4j\ClientBuilder::create()->build();

/**
* The client will now return a result, decorated with a summary.
Expand All @@ -339,8 +334,6 @@ $summary = $summarisedResult->getSummary();
$result = $summarisedResult->getResult();
```

In order to use a custom formatter, implement the `Laudis\Neo4j\Contracts\FormatterInterface` and provide it when using the client builder.

## Concepts

The driver API described [here](https://neo4j.com/docs/driver-manual/current/) is the main target of the driver. Because of this, the client is nothing more than a driver manager. The driver creates sessions. A session runs queries through a transaction.
Expand Down
7 changes: 0 additions & 7 deletions src/Basic/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,9 @@
use Laudis\Neo4j\Databags\SummarizedResult;
use Laudis\Neo4j\Databags\TransactionConfiguration;
use Laudis\Neo4j\Types\CypherList;
use Laudis\Neo4j\Types\CypherMap;

/**
* @implements ClientInterface<SummarizedResult<CypherMap>>
*/
final class Client implements ClientInterface
{
/**
* @param ClientInterface<SummarizedResult<CypherMap>> $client
*/
public function __construct(
private readonly ClientInterface $client
) {}
Expand Down
6 changes: 0 additions & 6 deletions src/Basic/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,9 @@
use Laudis\Neo4j\Types\CypherMap;
use Psr\Http\Message\UriInterface;

/**
* @implements DriverInterface<SummarizedResult<CypherMap>>
*/
final class Driver implements DriverInterface
{
/**
* @param DriverInterface<SummarizedResult<CypherMap>> $driver
*
* @psalm-external-mutation-free
*/
public function __construct(
Expand All @@ -52,7 +47,6 @@ public function verifyConnectivity(?SessionConfiguration $config = null): bool

public static function create(string|UriInterface $uri, ?DriverConfiguration $configuration = null, ?AuthenticateInterface $authenticate = null): self
{
/** @var DriverInterface<SummarizedResult<CypherMap>> */
$driver = DriverFactory::create($uri, $configuration, $authenticate, SummarizedResultFormatter::create());

return new self($driver);
Expand Down
13 changes: 1 addition & 12 deletions src/Basic/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,29 @@
use Laudis\Neo4j\Types\CypherList;
use Laudis\Neo4j\Types\CypherMap;

/**
* @implements SessionInterface<SummarizedResult<CypherMap>>
*/
final class Session implements SessionInterface
{
/**
* @param SessionInterface<SummarizedResult<CypherMap>> $session
*/
public function __construct(
private readonly SessionInterface $session
) {}

/**
* @param iterable<Statement> $statements
*
* @return CypherList<SummarizedResult<CypherMap>>
* @return CypherList<SummarizedResult>
*/
public function runStatements(iterable $statements, ?TransactionConfiguration $config = null): CypherList
{
return $this->session->runStatements($statements, $config);
}

/**
* @return SummarizedResult<CypherMap>
*/
public function runStatement(Statement $statement, ?TransactionConfiguration $config = null): SummarizedResult
{
return $this->session->runStatement($statement, $config);
}

/**
* @param iterable<string, mixed> $parameters
*
* @return SummarizedResult<CypherMap>
*/
public function run(string $statement, iterable $parameters = [], ?TransactionConfiguration $config = null): SummarizedResult
{
Expand Down
16 changes: 2 additions & 14 deletions src/Basic/UnmanagedTransaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,21 @@
use Laudis\Neo4j\Databags\Statement;
use Laudis\Neo4j\Databags\SummarizedResult;
use Laudis\Neo4j\Types\CypherList;
use Laudis\Neo4j\Types\CypherMap;

/**
* @implements UnmanagedTransactionInterface<SummarizedResult<CypherMap>>
*/
final class UnmanagedTransaction implements UnmanagedTransactionInterface
{
/**
* @param UnmanagedTransactionInterface<SummarizedResult<CypherMap>> $tsx
*/
public function __construct(
private readonly UnmanagedTransactionInterface $tsx
) {}

/**
* @param iterable<string, mixed> $parameters
*
* @return SummarizedResult<CypherMap>
*/
public function run(string $statement, iterable $parameters = []): SummarizedResult
{
return $this->tsx->run($statement, $parameters);
}

/**
* @return SummarizedResult<CypherMap>
*/
public function runStatement(Statement $statement): SummarizedResult
{
return $this->tsx->runStatement($statement);
Expand All @@ -52,7 +40,7 @@ public function runStatement(Statement $statement): SummarizedResult
/**
* @param iterable<Statement> $statements
*
* @return CypherList<SummarizedResult<CypherMap>>
* @return CypherList<SummarizedResult>
*/
public function runStatements(iterable $statements): CypherList
{
Expand All @@ -62,7 +50,7 @@ public function runStatements(iterable $statements): CypherList
/**
* @param iterable<Statement> $statements
*
* @return CypherList<SummarizedResult<CypherMap>>
* @return CypherList<SummarizedResult>
*/
public function commit(iterable $statements = []): CypherList
{
Expand Down
4 changes: 2 additions & 2 deletions src/Bolt/BoltConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@
use Laudis\Neo4j\Common\Neo4jLogger;
use Laudis\Neo4j\Contracts\AuthenticateInterface;
use Laudis\Neo4j\Contracts\ConnectionInterface;
use Laudis\Neo4j\Contracts\FormatterInterface;
use Laudis\Neo4j\Databags\BookmarkHolder;
use Laudis\Neo4j\Databags\DatabaseInfo;
use Laudis\Neo4j\Databags\Neo4jError;
use Laudis\Neo4j\Enum\AccessMode;
use Laudis\Neo4j\Enum\ConnectionProtocol;
use Laudis\Neo4j\Exception\Neo4jException;
use Laudis\Neo4j\Formatter\SummarizedResultFormatter;
use Laudis\Neo4j\Types\CypherList;
use Psr\Http\Message\UriInterface;
use Psr\Log\LogLevel;
Expand All @@ -42,7 +42,7 @@
/**
* @implements ConnectionInterface<array{0: V4_4|V5|V5_1|V5_2|V5_3|V5_4|null, 1: Connection}>
*
* @psalm-import-type BoltMeta from FormatterInterface
* @psalm-import-type BoltMeta from SummarizedResultFormatter
*/
class BoltConnection implements ConnectionInterface
{
Expand Down
27 changes: 5 additions & 22 deletions src/Bolt/BoltDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,50 +23,33 @@
use Laudis\Neo4j\Common\Uri;
use Laudis\Neo4j\Contracts\AuthenticateInterface;
use Laudis\Neo4j\Contracts\DriverInterface;
use Laudis\Neo4j\Contracts\FormatterInterface;
use Laudis\Neo4j\Contracts\SessionInterface;
use Laudis\Neo4j\Databags\DriverConfiguration;
use Laudis\Neo4j\Databags\SessionConfiguration;
use Laudis\Neo4j\Formatter\OGMFormatter;
use Laudis\Neo4j\Formatter\SummarizedResultFormatter;
use Psr\Http\Message\UriInterface;
use Psr\Log\LogLevel;

/**
* Drives a singular bolt connections.
*
* @template T
*
* @implements DriverInterface<T>
*
* @psalm-import-type OGMResults from OGMFormatter
* @psalm-import-type OGMResults from SummarizedResultFormatter
*/
final class BoltDriver implements DriverInterface
{
/**
* @param FormatterInterface<T> $formatter
*
* @psalm-mutation-free
*/
public function __construct(
private readonly UriInterface $parsedUrl,
private readonly ConnectionPool $pool,
private readonly FormatterInterface $formatter
private readonly SummarizedResultFormatter $formatter
) {}

/**
* @template U
*
* @param FormatterInterface<U> $formatter
*
* @return (
* func_num_args() is 5
* ? self<U>
* : self<OGMResults>
* )
*
* @psalm-suppress MixedReturnTypeCoercion
*/
public static function create(string|UriInterface $uri, ?DriverConfiguration $configuration = null, ?AuthenticateInterface $authenticate = null, ?FormatterInterface $formatter = null): self
public static function create(string|UriInterface $uri, ?DriverConfiguration $configuration = null, ?AuthenticateInterface $authenticate = null, ?SummarizedResultFormatter $formatter = null): self
{
if (is_string($uri)) {
$uri = Uri::create($uri);
Expand All @@ -80,7 +63,7 @@ public static function create(string|UriInterface $uri, ?DriverConfiguration $co
return new self(
$uri,
ConnectionPool::create($uri, $authenticate, $configuration, $semaphore),
$formatter ?? OGMFormatter::create(),
$formatter ?? SummarizedResultFormatter::create(),
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Bolt/BoltResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Laudis\Neo4j\Bolt;

use Laudis\Neo4j\Formatter\SummarizedResultFormatter;
use function array_splice;
use function count;

Expand All @@ -21,10 +22,9 @@
use function in_array;

use Iterator;
use Laudis\Neo4j\Contracts\FormatterInterface;

/**
* @psalm-import-type BoltCypherStats from FormatterInterface
* @psalm-import-type BoltCypherStats from SummarizedResultFormatter
*
* @implements Iterator<int, list>
*/
Expand Down
29 changes: 12 additions & 17 deletions src/Bolt/BoltUnmanagedTransaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
namespace Laudis\Neo4j\Bolt;

use Bolt\enum\ServerState;
use Laudis\Neo4j\Contracts\FormatterInterface;
use Laudis\Neo4j\Contracts\UnmanagedTransactionInterface;
use Laudis\Neo4j\Databags\BookmarkHolder;
use Laudis\Neo4j\Databags\SessionConfiguration;
use Laudis\Neo4j\Databags\Statement;
use Laudis\Neo4j\Databags\SummarizedResult;
use Laudis\Neo4j\Databags\TransactionConfiguration;
use Laudis\Neo4j\Enum\TransactionState;
use Laudis\Neo4j\Exception\ClientException;
use Laudis\Neo4j\Formatter\SummarizedResultFormatter;
use Laudis\Neo4j\ParameterHelper;
use Laudis\Neo4j\Types\AbstractCypherSequence;
use Laudis\Neo4j\Types\CypherList;
Expand All @@ -33,26 +34,19 @@
/**
* Manages a transaction over the bolt protocol.
*
* @template T
*
* @implements UnmanagedTransactionInterface<T>
*
* @psalm-import-type BoltMeta from FormatterInterface
* @psalm-import-type BoltMeta from SummarizedResultFormatter
*/
final class BoltUnmanagedTransaction implements UnmanagedTransactionInterface
{
private TransactionState $state = TransactionState::ACTIVE;

/**
* @param FormatterInterface<T> $formatter
*/
public function __construct(
/** @psalm-readonly */
private readonly ?string $database,
/**
* @psalm-readonly
*/
private readonly FormatterInterface $formatter,
private readonly SummarizedResultFormatter $formatter,
/** @psalm-readonly */
private readonly BoltConnection $connection,
private readonly SessionConfiguration $config,
Expand All @@ -62,6 +56,8 @@ public function __construct(

/**
* @throws ClientException|Throwable
*
* @return CypherList<SummarizedResult>
*/
public function commit(iterable $statements = []): CypherList
{
Expand All @@ -81,10 +77,8 @@ public function commit(iterable $statements = []): CypherList

// Force the results to pull all the results.
// After a commit, the connection will be in the ready state, making it impossible to use PULL
$tbr = $this->runStatements($statements)->each(static function ($list) {
if ($list instanceof AbstractCypherSequence) {
$list->preload();
}
$tbr = $this->runStatements($statements)->each(static function (CypherList $list) {
$list->preload();
});

$this->connection->commit();
Expand Down Expand Up @@ -116,15 +110,15 @@ public function rollback(): void
/**
* @throws Throwable
*/
public function run(string $statement, iterable $parameters = [])
public function run(string $statement, iterable $parameters = []): SummarizedResult
{
return $this->runStatement(new Statement($statement, $parameters));
}

/**
* @throws Throwable
*/
public function runStatement(Statement $statement)
public function runStatement(Statement $statement): SummarizedResult
{
$parameters = ParameterHelper::formatParameters($statement->getParameters(), $this->connection->getProtocol());
$start = microtime(true);
Expand Down Expand Up @@ -162,10 +156,11 @@ public function runStatement(Statement $statement)

/**
* @throws Throwable
*
* @return CypherList<SummarizedResult>
*/
public function runStatements(iterable $statements): CypherList
{
/** @var list<T> $tbr */
$tbr = [];
foreach ($statements as $statement) {
$tbr[] = $this->runStatement($statement);
Expand Down
Loading