Skip to content

Commit de5a041

Browse files
MatanYadaevMatan Yadaev
andauthored
[WIP] MySQL 5.7 support (#57)
* add mysql 5.7 to ci * Add `AxisOrder@supported` * Fix `AxisOrder@supported` parameter type * Fix tests * Remove unnecessary file * Test the axis order in databases that don't support setting it * Fix test Co-authored-by: Matan Yadaev <matan@zerolimits.io>
1 parent 7d9111b commit de5a041

File tree

9 files changed

+91
-30
lines changed

9 files changed

+91
-30
lines changed

.github/workflows/pest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
matrix:
1414
php: [ 8.1, 8.0 ]
1515
laravel: [ 9.*, 8.* ]
16-
db: [ 'mysql:8.0', 'mariadb:10.9' ]
16+
db: [ 'mysql:8.0', 'mysql:5.7', 'mariadb:10.9' ]
1717
# dependency-version: [prefer-lowest, prefer-stable]
1818
dependency-version: [ prefer-stable ]
1919
include:

.vscode/settings.json

Lines changed: 0 additions & 7 deletions
This file was deleted.

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"require": {
1313
"php": "^8.0",
1414
"ext-json": "*",
15+
"ext-pdo": "*",
1516
"laravel/framework": "^8.0|^9.0",
1617
"phayes/geophp": "^1.2"
1718
},

phpstan.neon

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ parameters:
1212
-
1313
message: '#^Access to an undefined property Pest\\Expectation\|Pest\\Support\\Extendable\:\:\$.+\.$#'
1414
path: tests/*.php
15-
- '#^Call to an undefined( static)? method .+\:\:isMaria\(\)\.$#'
1615
excludePaths:
1716
- ./src/Factory.php
1817
checkMissingIterableValueType: true

src/AxisOrder.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial;
6+
7+
use Illuminate\Database\ConnectionInterface;
8+
use Illuminate\Database\MySqlConnection;
9+
use PDO;
10+
11+
class AxisOrder
12+
{
13+
public function __construct() {}
14+
15+
public function supported(ConnectionInterface $connection): bool
16+
{
17+
/** @var MySqlConnection $connection */
18+
if ($this->isMariaDb($connection)) {
19+
// @codeCoverageIgnoreStart
20+
return false;
21+
// @codeCoverageIgnoreEnd
22+
}
23+
24+
if ($this->isMySql57($connection)) {
25+
// @codeCoverageIgnoreStart
26+
return false;
27+
// @codeCoverageIgnoreEnd
28+
}
29+
30+
return true;
31+
}
32+
33+
private function isMariaDb(MySqlConnection $connection): bool {
34+
return $connection->isMaria();
35+
}
36+
37+
private function isMySql57(MySqlConnection $connection): bool
38+
{
39+
/** @var string $version */
40+
$version = $connection->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION);
41+
42+
return version_compare($version, '5.8.0', '<');
43+
}
44+
}

src/GeometryCast.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ public function set($model, string $key, $value, array $attributes): Expression|
7171

7272
$wkt = $value->toWkt();
7373

74-
$isMariaDb = $model->getConnection()->isMaria();
74+
$connection = $model->getConnection();
7575

76-
if ($isMariaDb) {
76+
if (! (new AxisOrder)->supported($connection)) {
7777
// @codeCoverageIgnoreStart
7878
return DB::raw("ST_GeomFromText('{$wkt}', {$value->srid})");
7979
// @codeCoverageIgnoreEnd

src/SpatialBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,9 @@ protected function toExpression(Geometry|string $geometryOrColumn): Expression
291291
if ($geometryOrColumn instanceof Geometry) {
292292
$wkt = $geometryOrColumn->toWkt();
293293

294-
$isMariaDb = $this->getConnection()->isMaria();
294+
$connection = $this->getConnection();
295295

296-
if ($isMariaDb) {
296+
if (! (new AxisOrder)->supported($connection)) {
297297
// @codeCoverageIgnoreStart
298298
return DB::raw("ST_GeomFromText('{$wkt}', {$geometryOrColumn->srid})");
299299
// @codeCoverageIgnoreEnd

tests/Objects/GeometryTest.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use Illuminate\Database\QueryException;
44
use Illuminate\Support\Facades\DB;
5+
use MatanYadaev\EloquentSpatial\AxisOrder;
56
use MatanYadaev\EloquentSpatial\Objects\LineString;
67
use MatanYadaev\EloquentSpatial\Objects\Point;
78
use MatanYadaev\EloquentSpatial\Tests\TestModels\TestPlace;
@@ -19,14 +20,36 @@
1920
$point = (new Point(91, 0, 4326));
2021
TestPlace::factory()->create(['point' => $point]);
2122
})->toThrow(QueryException::class);
22-
})->skip(fn () => DB::isMaria());
23+
})->skip(fn () => ! (new AxisOrder)->supported(DB::connection()));
24+
25+
it('throws exception when generating geometry with invalid latitude - without axis-order', function (): void {
26+
expect(function (): void {
27+
$point = (new Point(91, 0, 4326));
28+
TestPlace::factory()->create(['point' => $point]);
29+
30+
TestPlace::query()
31+
->withDistanceSphere('point', new Point(1, 1, 4326))
32+
->firstOrFail();
33+
})->toThrow(QueryException::class);
34+
})->skip(fn () => (new AxisOrder)->supported(DB::connection()));
2335

2436
it('throws exception when generating geometry with invalid longitude', function (): void {
2537
expect(function (): void {
2638
$point = (new Point(0, 181, 4326));
2739
TestPlace::factory()->create(['point' => $point]);
2840
})->toThrow(QueryException::class);
29-
})->skip(fn () => DB::isMaria());
41+
})->skip(fn () => ! (new AxisOrder)->supported(DB::connection()));
42+
43+
it('throws exception when generating geometry with invalid longitude - without axis-order', function (): void {
44+
expect(function (): void {
45+
$point = (new Point(0, 181, 4326));
46+
TestPlace::factory()->create(['point' => $point]);
47+
48+
TestPlace::query()
49+
->withDistanceSphere('point', new Point(1, 1, 4326))
50+
->firstOrFail();
51+
})->toThrow(QueryException::class);
52+
})->skip(fn () => (new AxisOrder)->supported(DB::connection()));
3053

3154
it('throws exception when generating geometry from other geometry WKT', function (): void {
3255
expect(function (): void {

tests/SpatialBuilderTest.php

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use Illuminate\Foundation\Testing\DatabaseMigrations;
44
use Illuminate\Support\Facades\DB;
5+
use MatanYadaev\EloquentSpatial\AxisOrder;
56
use MatanYadaev\EloquentSpatial\Objects\LineString;
67
use MatanYadaev\EloquentSpatial\Objects\Point;
78
use MatanYadaev\EloquentSpatial\Objects\Polygon;
@@ -29,9 +30,9 @@
2930
->firstOrFail();
3031

3132
expect($testPlaceWithDistance->distance)->toBe(156897.79947260793);
32-
})->skip(fn () => DB::isMaria());
33+
})->skip(fn () => ! (new AxisOrder)->supported(DB::connection()));
3334

34-
it('calculates distance between column and geometry - MariaDB', function (): void {
35+
it('calculates distance between column and geometry - without axis-order', function (): void {
3536
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
3637

3738
/** @var TestPlace $testPlaceWithDistance */
@@ -40,7 +41,7 @@
4041
->firstOrFail();
4142

4243
expect($testPlaceWithDistance->distance)->toBe(1.4142135623730951);
43-
})->skip(fn () => ! DB::isMaria());
44+
})->skip(fn () => (new AxisOrder)->supported(DB::connection()));
4445

4546
it('calculates distance with alias', function (): void {
4647
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
@@ -51,9 +52,9 @@
5152
->firstOrFail();
5253

5354
expect($testPlaceWithDistance->distance_in_meters)->toBe(156897.79947260793);
54-
})->skip(fn () => DB::isMaria());
55+
})->skip(fn () => ! (new AxisOrder)->supported(DB::connection()));
5556

56-
it('calculates distance with alias - MariaDB', function (): void {
57+
it('calculates distance with alias - without axis-order', function (): void {
5758
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
5859

5960
/** @var TestPlace $testPlaceWithDistance */
@@ -62,7 +63,7 @@
6263
->firstOrFail();
6364

6465
expect($testPlaceWithDistance->distance_in_meters)->toBe(1.4142135623730951);
65-
})->skip(fn () => ! DB::isMaria());
66+
})->skip(fn () => (new AxisOrder)->supported(DB::connection()));
6667

6768
it('filters by distance', function (): void {
6869
$pointWithinDistance = new Point(0, 0, 4326);
@@ -77,9 +78,9 @@
7778

7879
expect($testPlacesWithinDistance)->toHaveCount(1);
7980
expect($testPlacesWithinDistance[0]->point)->toEqual($pointWithinDistance);
80-
})->skip(fn () => DB::isMaria());
81+
})->skip(fn () => ! (new AxisOrder)->supported(DB::connection()));
8182

82-
it('filters by distance - MariaDB', function (): void {
83+
it('filters by distance - without axis-order', function (): void {
8384
$pointWithinDistance = new Point(0, 0, 4326);
8485
$pointNotWithinDistance = new Point(50, 50, 4326);
8586
TestPlace::factory()->create(['point' => $pointWithinDistance]);
@@ -92,7 +93,7 @@
9293

9394
expect($testPlacesWithinDistance)->toHaveCount(1);
9495
expect($testPlacesWithinDistance[0]->point)->toEqual($pointWithinDistance);
95-
})->skip(fn () => ! DB::isMaria());
96+
})->skip(fn () => (new AxisOrder)->supported(DB::connection()));
9697

9798
it('orders by distance ASC', function (): void {
9899
$closerTestPlace = TestPlace::factory()->create(['point' => new Point(1, 1, 4326)]);
@@ -140,9 +141,9 @@
140141
->firstOrFail();
141142

142143
expect($testPlaceWithDistance->distance)->toBe(157249.59776850493);
143-
})->skip(fn () => DB::isMaria());
144+
})->skip(fn () =>! (new AxisOrder)->supported(DB::connection()));
144145

145-
it('calculates distance sphere column and geometry - MariaDB', function (): void {
146+
it('calculates distance sphere column and geometry - without axis-order', function (): void {
146147
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
147148

148149
/** @var TestPlace $testPlaceWithDistance */
@@ -151,7 +152,7 @@
151152
->firstOrFail();
152153

153154
expect($testPlaceWithDistance->distance)->toBe(157249.0357231545);
154-
})->skip(fn () => ! DB::isMaria());
155+
})->skip(fn () => (new AxisOrder)->supported(DB::connection()));
155156

156157
it('calculates distance sphere with alias', function (): void {
157158
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
@@ -162,9 +163,9 @@
162163
->firstOrFail();
163164

164165
expect($testPlaceWithDistance->distance_in_meters)->toBe(157249.59776850493);
165-
})->skip(fn () => DB::isMaria());
166+
})->skip(fn () => ! (new AxisOrder)->supported(DB::connection()));
166167

167-
it('calculates distance sphere with alias - MariaDB', function (): void {
168+
it('calculates distance sphere with alias - without axis-order', function (): void {
168169
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
169170

170171
/** @var TestPlace $testPlaceWithDistance */
@@ -173,7 +174,7 @@
173174
->firstOrFail();
174175

175176
expect($testPlaceWithDistance->distance_in_meters)->toBe(157249.0357231545);
176-
})->skip(fn () => ! DB::isMaria());
177+
})->skip(fn () => (new AxisOrder)->supported(DB::connection()));
177178

178179
it('filters distance sphere', function (): void {
179180
$pointWithinDistance = new Point(0, 0, 4326);

0 commit comments

Comments
 (0)