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
13 changes: 13 additions & 0 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,30 @@

namespace Neo4j\QueryAPI;

use InvalidArgumentException;
use Neo4j\QueryAPI\Objects\Bookmarks;
use Neo4j\QueryAPI\Enums\AccessMode;

final class Configuration
{
/**
* Constructor for Configuration class.
*
* @param string $baseUri The base URI for the Neo4j instance.
* @param string $database The name of the database to connect to.
* @param bool $includeCounters Whether to include counters in the response.
* @param Bookmarks $bookmarks Bookmarks for tracking queries.
* @param AccessMode $accessMode The access mode for the connection (read/write).
*
* @throws InvalidArgumentException if $baseUri is empty.
*/
public function __construct(
public readonly string $baseUri,
public readonly string $database = 'neo4j',
public readonly bool $includeCounters = true,
public readonly Bookmarks $bookmarks = new Bookmarks([]),
public readonly AccessMode $accessMode = AccessMode::WRITE,
) {

}
}
56 changes: 41 additions & 15 deletions src/Neo4jQueryAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Discovery\Psr18ClientDiscovery;
use http\Exception\RuntimeException;
use InvalidArgumentException;
use Neo4j\QueryAPI\Exception\Neo4jException;
use Psr\Http\Client\ClientInterface;
use Neo4j\QueryAPI\Authentication\AuthenticateInterface;
Expand All @@ -15,36 +16,63 @@

final class Neo4jQueryAPI
{
private Configuration $config;

public function __construct(
private ClientInterface $client,
private ResponseParser $responseParser,
private Neo4jRequestFactory $requestFactory
private ClientInterface $client,
private ResponseParser $responseParser,
private Neo4jRequestFactory $requestFactory,
?Configuration $config = null
) {
$this->config = $config ?? new Configuration(baseUri: 'http://myaddress'); // Default configuration if not provided
}

/**
* @api
*/
public static function login(string $address, AuthenticateInterface $auth = null): self
public static function login(string $address = null, ?AuthenticateInterface $auth = null, ?Configuration $config = null): self
{
$config = $config ?? new Configuration(baseUri: $address ?? '');
if (
trim($config->baseUri) !== '' &&
$address !== null &&
trim($address) !== '' &&
$config->baseUri !== $address
) {
throw new InvalidArgumentException(sprintf('Address (%s) as argument is different from address in configuration (%s)', $config->baseUri, $address));
}

$client = Psr18ClientDiscovery::find();

return new self(
client: $client,
responseParser: new ResponseParser(
ogm: new OGM()
),
responseParser: new ResponseParser(new OGM()),
requestFactory: new Neo4jRequestFactory(
psr17Factory: Psr17FactoryDiscovery::findRequestFactory(),
streamFactory: Psr17FactoryDiscovery::findStreamFactory(),
configuration: new Configuration(
baseUri: $address
),
configuration: $config,
auth: $auth ?? Authentication::fromEnvironment()
)
),
config: $config
);
}

/**
* @api
*/
public function create(Configuration $configuration, AuthenticateInterface $auth = null): self
{
return self::login(auth: $auth, config: $configuration);
}

public function getConfig(): Configuration
{
return $this->config;
}

/**
* Executes a Cypher query.
*/
public function run(string $cypher, array $parameters = []): ResultSet
{
$request = $this->requestFactory->buildRunQueryRequest($cypher, $parameters);
Expand All @@ -54,13 +82,13 @@ public function run(string $cypher, array $parameters = []): ResultSet
} catch (RequestExceptionInterface $e) {
$this->handleRequestException($e);
}

return $this->responseParser->parseRunQueryResponse($response);
}

public function beginTransaction(): Transaction
{
$request = $this->requestFactory->buildBeginTransactionRequest();
$response = $this->client->sendRequest($request);

try {
$response = $this->client->sendRequest($request);
Expand All @@ -82,8 +110,6 @@ public function beginTransaction(): Transaction
);
}



/**
* Handles request exceptions by parsing error details and throwing a Neo4jException.
*
Expand All @@ -96,7 +122,7 @@ private function handleRequestException(RequestExceptionInterface $e): void
$response = method_exists($e, 'getResponse') ? $e->getResponse() : null;

if ($response instanceof ResponseInterface) {
$errorResponse = json_decode((string)$response->getBody(), true);
$errorResponse = json_decode((string) $response->getBody(), true);
throw Neo4jException::fromNeo4jResponse($errorResponse, $e);
}

Expand Down
42 changes: 42 additions & 0 deletions tests/Integration/Neo4jQueryAPITest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Neo4j\QueryAPI\Tests\Integration;

use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use Neo4j\QueryAPI\Neo4jQueryAPI;
use Neo4j\QueryAPI\Objects\Authentication;
use Neo4j\QueryAPI\Configuration;

final class Neo4jQueryAPITest extends TestCase
{
public function testLoginWithValidConfiguration(): void
{
$config = new Configuration(baseUri: 'http://valid.address');

$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Address (http://valid.address) as argument is different from address in configuration (http://myaddress)');

Neo4jQueryAPI::login('http://myaddress', Authentication::fromEnvironment(), $config);
}

public function testLoginWithNullConfiguration(): void
{
$config = null;

$api = Neo4jQueryAPI::login('http://myaddress', Authentication::fromEnvironment(), $config);

$this->assertInstanceOf(Neo4jQueryAPI::class, $api);
$this->assertEquals('http://myaddress', $api->getConfig()->baseUri);
}

public function testConfigOnly(): void
{
$config = new Configuration(baseUri: 'http://valid.address');

$api = Neo4jQueryAPI::login(auth: Authentication::fromEnvironment(), config: $config);

$this->assertInstanceOf(Neo4jQueryAPI::class, $api);
$this->assertEquals('http://valid.address', $api->getConfig()->baseUri);
}
}