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
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ composer require neo4j-php/query-api

## Client Installation

If you plan on using the HTTP drivers, make sure you have psr-7, psr-17, and psr-18 implementations included in your project.
If you don't have any, you can install them via Composer:
This client uses the HTTP protocol, make sure you have psr-7, psr-17, and psr-18 implementations included in your project.
If you don't have any, you can install one of the many options via Composer:

```sh
composer require psr/http-message psr/http-factory psr/http-client
composer require guzzlehttp/guzzle
```

> **_NOTE:_** PSR-17 and PSR-18 are essential for HTTP client communication. Other compatible clients like Guzzle can also be used.
Expand Down Expand Up @@ -121,19 +121,18 @@ Cypher values and types map to these php types and classes:
| Authentication | Yes |
| Transaction | Yes |
| HTTP | Yes |
| Cluster | Partly* |
| Cluster | Partly * |
| Aura | Yes |
| Bookmarks | Yes |
| Bolt | No |

> **_NOTE:_** It supports neo4j databases versions > 5.25 or Neo4j Aura (which has QueryAPI enabled.)
> \* Client side routing is only supported in the Neo4j driver


**_NOTE:_** *_It supports neo4j databases versions > 5.25 or Neo4j Aura (which has QueryAPI enabled.)_*

## Contributing

Please see CONTRIBUTING for details.
Please see [CONTRIBUTING.md](./Contributing.md) for details.

## Security

Expand All @@ -142,8 +141,10 @@ If you discover any security-related issues, please email *[email protected]*
## Credits

- Created with ❤️ by Nagels
- [Ghlen Nagels](https://www.linkedin.com/in/ghlen/), [Kiran Chandani](https://www.linkedin.com/in/kiran-chandani-5628a1213/), [Pratiksha Zalte]()
- [Kiran Chandani](https://www.linkedin.com/in/kiran-chandani-5628a1213/),
- [Pratiksha Zalte](https://github.com/p123-stack),
- [Ghlen Nagels](https://www.linkedin.com/in/ghlen/)

## License

The MIT License (MIT). Please see License File for more information.
The MIT License (MIT). Please see [License File](LICENSE) for more information.
5 changes: 4 additions & 1 deletion phpunit.dist.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php">
<phpunit bootstrap="tests/bootstrap.php"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
>
<!-- Test Suite Configuration -->
<testsuites>
<testsuite name="Application Test Suite">
Expand Down
2 changes: 1 addition & 1 deletion src/Neo4jRequestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\StreamFactoryInterface;

class Neo4jRequestFactory
final class Neo4jRequestFactory
{
public function __construct(
private RequestFactoryInterface $psr17Factory,
Expand Down
2 changes: 1 addition & 1 deletion src/OGM.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Neo4j\QueryAPI\Objects\Path;
use InvalidArgumentException;

class OGM
final class OGM
{
/**
* @param array<array-key, mixed> $data
Expand Down
2 changes: 1 addition & 1 deletion src/Objects/Authentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Neo4j\QueryAPI\Authentication\BearerAuthentication;
use Neo4j\QueryAPI\Authentication\NoAuth;

class Authentication
final class Authentication
{
public static function basic(string $username, string $password): AuthenticateInterface
{
Expand Down
2 changes: 1 addition & 1 deletion src/Objects/Path.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Represents a path in a Neo4j graph, consisting of nodes and relationships.
*/

class Path
final class Path
{
/**
* @var Node[] Array of nodes in the path.
Expand Down
2 changes: 1 addition & 1 deletion src/Objects/Person.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @psalm-suppress UnusedClass
* Represents a Person node in the Neo4j graph.
*/
class Person extends Node
final class Person extends Node
{
/**
* Person constructor.
Expand Down
2 changes: 1 addition & 1 deletion src/Objects/Point.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/**
* Represents a point with x, y, z coordinates, and SRID (Spatial Reference System Identifier).
*/
class Point
final class Point
{
/**
* @param float $x The x coordinate of the point.
Expand Down
2 changes: 1 addition & 1 deletion src/Objects/ProfiledQueryPlanArguments.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Neo4j\QueryAPI\Objects;

class ProfiledQueryPlanArguments
final class ProfiledQueryPlanArguments
{
public function __construct(
public readonly ?int $globalMemory = null,
Expand Down
2 changes: 1 addition & 1 deletion src/Objects/Relationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Represents a relationship in a Neo4j graph, with a type and associated properties.
*/

class Relationship
final class Relationship
{
/**
* @var string The type of the relationship (e.g., "FRIENDS_WITH", "WORKS_FOR").
Expand Down
2 changes: 1 addition & 1 deletion src/Objects/ResultCounters.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Neo4j\QueryAPI\Objects;

class ResultCounters
final class ResultCounters
{
public function __construct(
private readonly bool $containsUpdates = false,
Expand Down
2 changes: 1 addition & 1 deletion src/Results/ResultSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @template TValue
* @implements IteratorAggregate<int, ResultRow>
*/
class ResultSet implements IteratorAggregate, Countable
final class ResultSet implements IteratorAggregate, Countable
{
/**
* @param list<ResultRow> $rows
Expand Down
5 changes: 3 additions & 2 deletions tests/CreatesQueryAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@
use Neo4j\QueryAPI\Enums\AccessMode;
use Neo4j\QueryAPI\Neo4jQueryAPI;
use Neo4j\QueryAPI\Objects\Authentication;
use Neo4j\QueryAPI\Objects\Bookmarks;

trait CreatesQueryAPI
{
protected Neo4jQueryAPI $api;

protected function createQueryAPI(AccessMode $accessMode = AccessMode::WRITE): void
protected function createQueryAPI(AccessMode $accessMode = AccessMode::WRITE, ?Bookmarks $bookmarks = null): void
{
$neo4jAddress = getenv('NEO4J_ADDRESS');
if (!is_string($neo4jAddress) || trim($neo4jAddress) === '') {
throw new \RuntimeException('NEO4J_ADDRESS is not set or is invalid.');
}

$this->api = Neo4jQueryAPI::create(
new Configuration(baseUri: $neo4jAddress, accessMode: $accessMode),
new Configuration(baseUri: $neo4jAddress, bookmarks: $bookmarks ?? new Bookmarks([]), accessMode: $accessMode),
Authentication::fromEnvironment()
);
}
Expand Down
25 changes: 25 additions & 0 deletions tests/Integration/BookmarksIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace Neo4j\QueryAPI\Tests\Integration;

use Neo4j\QueryAPI\Configuration;
use Neo4j\QueryAPI\Exception\Neo4jException;
use Neo4j\QueryAPI\Neo4jQueryAPI;
use Neo4j\QueryAPI\Tests\CreatesQueryAPI;
use PHPUnit\Framework\TestCase;
use Neo4j\QueryAPI\Objects\Bookmarks;
Expand Down Expand Up @@ -34,4 +37,26 @@ public function testCreateBookmarks(): void
$this->assertCount(1, $result);
}


public function testInvalidBookmarkThrowsException(): void
{
$exceptionCaught = false;

$invalidBookmark = new Bookmarks(['invalid:bookmark']);
$this->createQueryAPI(bookmarks: $invalidBookmark);

try {
$this->api->run('MATCH (n) RETURN n');
} catch (Neo4jException $e) {
$exceptionCaught = true;
$this->assertEquals('Parsing of supplied bookmarks failed with message: Illegal base64 character 3a', $e->getMessage());
$this->assertEquals('InvalidBookmark', $e->getName());
$this->assertEquals('Transaction', $e->getSubType());
$this->assertEquals('ClientError', $e->getType());
}

$this->assertTrue($exceptionCaught);
}


}
9 changes: 3 additions & 6 deletions tests/Integration/Neo4jOGMTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@

namespace Neo4j\QueryAPI\Tests\Integration;

use Neo4j\QueryAPI\Objects\Path;
use Neo4j\QueryAPI\OGM;
use PHPUnit\Framework\TestCase;

/**
* @api
*/
class Neo4jOGMTest extends TestCase
final class Neo4jOGMTest extends TestCase
{
/** @psalm-suppress PropertyNotSetInConstructor */
private OGM $ogm;

#[\Override]
Expand Down Expand Up @@ -84,11 +81,11 @@ public function testWithPath(): void
];

$path = $this->ogm->map($pathData);
$this->assertInstanceOf(Path::class, $path);

$this->assertCount(2, $path->nodes);
$this->assertCount(1, $path->relationships);
$this->assertEquals('A', $path->nodes[0]->getProperties()['name']['_value']);
$this->assertEquals('B', $path->nodes[1]->getProperties()['name']['_value']);
}

}