Skip to content
Open
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ coverage
xml-coverage
composer.lock

.env
.env
.phpunit.result.cache
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@
"phpunit-with-coverage" : "XDEBUG_MODE=coverage php -d memory_limit=-1 vendor/bin/phpunit --configuration=phpunitCoverage.xml --testsuite=All --coverage-filter=src tests"
}

}
}
14 changes: 14 additions & 0 deletions phpUnit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php" colors="true" verbose="true">
<php>
<!-- Database Configuration -->
<env name="NEO4J_ADDRESS" value="https://6f72daa1.databases.neo4j.io" />
<env name="NEO4J_USERNAME" value="neo4j" />
<env name="NEO4J_PASSWORD" value="9lWmptqBgxBOz8NVcTJjgs3cHPyYmsy63ui6Spmw1d0" />
</php>
<testsuites>
<testsuite name="Application Test Suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
30 changes: 30 additions & 0 deletions phpunitCoverage.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd">
<!-- Define a basic testsuite -->
<testsuites>
<testsuite name="Default">
<directory>tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">src</directory>
</include>
</source>

<coverage processUncoveredFiles="true">
<include>
<directory>src</directory>
</include>
<report>
<clover outputFile="./coverage/clover.xml"/>
<cobertura outputFile="./coverage/cobertura.xml"/>
<crap4j outputFile="./coverage/crap4j.xml" threshold="50"/>
<html outputDirectory="./coverage/html" lowUpperBound="35" highLowerBound="70"/>
<php outputFile="./coverage/coverage.php"/>
<text outputFile="./coverage/coverage.txt" showUncoveredFiles="false" showOnlySummary="true"/>
<xml outputDirectory="./coverage/xml"/>
</report>
</coverage>
</phpunit>
69 changes: 64 additions & 5 deletions src/OGM.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@

namespace Neo4j\QueryAPI;

use DateTimeZone;
use Neo4j\QueryAPI\Objects\Point;
use Neo4j\QueryAPI\Objects\Node;
use Neo4j\QueryAPI\Objects\Relationship;
use Neo4j\QueryAPI\Objects\Path;
use InvalidArgumentException;
use Neo4j\QueryAPI\Objects\Temporal\Date;
use Neo4j\QueryAPI\Objects\Temporal\DateTime;
use Neo4j\QueryAPI\Objects\Temporal\DateTimeZoneId;
use Neo4j\QueryAPI\Objects\Temporal\Duration;
use Neo4j\QueryAPI\Objects\Temporal\LocalDateTime;
use Neo4j\QueryAPI\Objects\Temporal\LocalTime;
use Neo4j\QueryAPI\Objects\Temporal\Time;

final class OGM
{
Expand All @@ -21,14 +29,24 @@
}

return match ($data['$type']) {
'Integer', 'Float', 'String', 'Boolean', 'Duration', 'OffsetDateTime' => $data['_value'],
'Integer', 'Float', 'Boolean' => $data['_value'],
'Array', 'List' => is_array($data['_value']) ? array_map([$this, 'map'], $data['_value']) : [],
'Null' => null,
'Node' => $this->mapNode($data['_value']),
'Map' => is_array($data['_value']) ? $this->mapProperties($data['_value']) : [],
'Point' => $this->parsePoint($data['_value']),
'Relationship' => $this->mapRelationship($data['_value']),
'Path' => $this->mapPath($data['_value']),
'Date' => $this->mapDate($data['_value']),
'OffsetDateTime' => $this->mapDateTime($data['_value']),
'Time' => $this->mapTime($data['_value']),
'LocalTime' => $this->mapLocalTime($data['_value']),
'LocalDateTime' => $this->mapLocalDateTime($data['_value']),
'Duration' => $this->mapDuration($data['_value']),

'String' => $this->isValidTimeZone($data['_value'])
? new DateTimeZoneId($data['_value']) // Convert timezone strings to `DateTimeZoneId`
: $data['_value'],
default => throw new InvalidArgumentException('Unknown type: ' . json_encode($data, JSON_THROW_ON_ERROR)),
};
}
Expand All @@ -37,10 +55,10 @@
private function parsePoint(string $value): Point
{
if (preg_match('/SRID=(\d+);POINT(?: Z)? \(([-\d.]+) ([-\d.]+)(?: ([-\d.]+))?\)/', $value, $matches)) {
$srid = (int) $matches[1];
$x = (float) $matches[2];
$y = (float) $matches[3];
$z = isset($matches[4]) ? (float) $matches[4] : null;
$srid = (int)$matches[1];
$x = (float)$matches[2];
$y = (float)$matches[3];
$z = isset($matches[4]) ? (float)$matches[4] : null;

return new Point($x, $y, $z, $srid);
}
Expand Down Expand Up @@ -129,5 +147,46 @@
return $mappedProperties;
}

private function mapDate(string $value): Date
{
$totalDaysSinceEpoch = (new \DateTime($value))->diff(new \DateTime('@0'))->days;

return new Date($totalDaysSinceEpoch);
}

private function mapDateTime(string $value): DateTime
{
return new DateTime($value);
}

private function mapDateTimeZoneId(string $value): DateTimeZoneId

Check warning on line 162 in src/OGM.php

View check run for this annotation

Codecov / codecov/patch

src/OGM.php#L162

Added line #L162 was not covered by tests

Check warning on line 162 in src/OGM.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/OGM.php#L162

Avoid unused private methods such as 'mapDateTimeZoneId'.
{
return new DateTimeZoneId($value);

Check warning on line 164 in src/OGM.php

View check run for this annotation

Codecov / codecov/patch

src/OGM.php#L164

Added line #L164 was not covered by tests
}

private function isValidTimeZone(string $value): bool
{
return in_array($value, timezone_identifiers_list(), true);
}

private function mapTime(mixed $_value): Time
{
return new Time($_value);

}

private function mapLocalTime(mixed $_value): LocalTime
{
return new LocalTime($_value);
}

private function mapLocalDateTime(mixed $_value): LocalDateTime
{
return new LocalDateTime($_value);
}

private function mapDuration(mixed $_value): Duration
{
return new Duration($_value);
}
}
35 changes: 35 additions & 0 deletions src/Objects/Temporal/Date.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Neo4j\QueryAPI\Objects\Temporal;

final class Date
{
public int $days;

public function __construct(int $days)
{
$this->days = $days;
}

/**
* Returns the number of days since the Unix epoch.
*/
public function getDays(): int
{
return $this->days;
}

/**
* Converts the stored date into a DateTimeImmutable.
*/
public function toDateTimeImmutable(): \DateTimeImmutable

Check warning on line 25 in src/Objects/Temporal/Date.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/Date.php#L25

Added line #L25 was not covered by tests
{
$dt = new \DateTimeImmutable('@0');
return $dt->modify(sprintf('+%d days', $this->days));

Check warning on line 28 in src/Objects/Temporal/Date.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/Date.php#L27-L28

Added lines #L27 - L28 were not covered by tests
}

public function __toString(): string

Check warning on line 31 in src/Objects/Temporal/Date.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/Date.php#L31

Added line #L31 was not covered by tests
{
return sprintf("Date(%d days since epoch)", $this->days);

Check warning on line 33 in src/Objects/Temporal/Date.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/Date.php#L33

Added line #L33 was not covered by tests
}
}
23 changes: 23 additions & 0 deletions src/Objects/Temporal/DateTime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Neo4j\QueryAPI\Objects\Temporal;

final class DateTime
{
private \DateTimeImmutable $dateTime;

public function __construct(string $dateTime)
{
$this->dateTime = new \DateTimeImmutable($dateTime);
}

public function getDateTime(): \DateTimeImmutable
{
return $this->dateTime;
}

public function __toString(): string

Check warning on line 19 in src/Objects/Temporal/DateTime.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/DateTime.php#L19

Added line #L19 was not covered by tests
{
return $this->dateTime->format('c');

Check warning on line 21 in src/Objects/Temporal/DateTime.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/DateTime.php#L21

Added line #L21 was not covered by tests
}
}
23 changes: 23 additions & 0 deletions src/Objects/Temporal/DateTimeZoneId.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Neo4j\QueryAPI\Objects\Temporal;

final class DateTimeZoneId
{
private string $zoneId;

public function __construct(string $zoneId)
{
$this->zoneId = $zoneId;
}

public function getZoneId(): string
{
return $this->zoneId;
}

public function __toString(): string

Check warning on line 19 in src/Objects/Temporal/DateTimeZoneId.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/DateTimeZoneId.php#L19

Added line #L19 was not covered by tests
{
return $this->zoneId;

Check warning on line 21 in src/Objects/Temporal/DateTimeZoneId.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/DateTimeZoneId.php#L21

Added line #L21 was not covered by tests
}
}
23 changes: 23 additions & 0 deletions src/Objects/Temporal/Duration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Neo4j\QueryAPI\Objects\Temporal;

final class Duration
{
private string $duration;

public function __construct(string $duration)
{
$this->duration = $duration;
}

public function getDuration(): string
{
return $this->duration;
}

public function __toString(): string
{
return $this->duration;
}
}
24 changes: 24 additions & 0 deletions src/Objects/Temporal/LocalDateTime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Neo4j\QueryAPI\Objects\Temporal;

final class LocalDateTime
{
private \DateTimeImmutable $localDateTime;

public function __construct(string $localDateTime)
{
$this->localDateTime = new \DateTimeImmutable($localDateTime);
}

public function getLocalDateTime(): \DateTimeImmutable
{
return $this->localDateTime;
}

public function __toString(): string

Check warning on line 19 in src/Objects/Temporal/LocalDateTime.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/LocalDateTime.php#L19

Added line #L19 was not covered by tests
{
// Adjust the format as necessary (without timezone info)
return $this->localDateTime->format('Y-m-d\TH:i:s');

Check warning on line 22 in src/Objects/Temporal/LocalDateTime.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/LocalDateTime.php#L22

Added line #L22 was not covered by tests
}
}
23 changes: 23 additions & 0 deletions src/Objects/Temporal/LocalTime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Neo4j\QueryAPI\Objects\Temporal;

final class LocalTime
{
private string $localTime;

public function __construct(string $localTime)
{
$this->localTime = $localTime;
}

public function getLocalTime(): string
{
return $this->localTime;
}

public function __toString(): string

Check warning on line 19 in src/Objects/Temporal/LocalTime.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/LocalTime.php#L19

Added line #L19 was not covered by tests
{
return $this->localTime;

Check warning on line 21 in src/Objects/Temporal/LocalTime.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/LocalTime.php#L21

Added line #L21 was not covered by tests
}
}
23 changes: 23 additions & 0 deletions src/Objects/Temporal/Time.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Neo4j\QueryAPI\Objects\Temporal;

final class Time
{
private string $time; // You might later parse this into components if needed.

public function __construct(string $time)
{
$this->time = $time;
}

public function getTime(): string
{
return $this->time;
}

public function __toString(): string

Check warning on line 19 in src/Objects/Temporal/Time.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/Time.php#L19

Added line #L19 was not covered by tests
{
return $this->time;

Check warning on line 21 in src/Objects/Temporal/Time.php

View check run for this annotation

Codecov / codecov/patch

src/Objects/Temporal/Time.php#L21

Added line #L21 was not covered by tests
}
}
2 changes: 1 addition & 1 deletion src/Results/ResultRow.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
final class ResultRow implements ArrayAccess, Countable, IteratorAggregate
{
/** @var array<string, TValue> */
private array $data;
public array $data;

public function __construct(array $data)
{
Expand Down
Loading