Skip to content

Commit 88ffd79

Browse files
MatanYadaevMatan Yadaev
andauthored
Support MariaDB (#52)
* add mariadb to ci * fix ci * remove matrix fail-fast * fix ci * fix mariadb issue * fix tests * fix docs * set fail-fast: false * fix test * fix phpstan * fix code coverage Co-authored-by: Matan Yadaev <[email protected]>
1 parent 056e574 commit 88ffd79

File tree

10 files changed

+98
-19
lines changed

10 files changed

+98
-19
lines changed

.github/workflows/pest-coverage.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010

1111
services:
12-
mysql:
12+
db:
1313
image: mysql:8.0
1414
env:
1515
MYSQL_ALLOW_EMPTY_PASSWORD: yes
@@ -33,5 +33,5 @@ jobs:
3333

3434
- name: Execute tests
3535
env:
36-
DB_PORT: ${{ job.services.mysql.ports['3306'] }}
36+
DB_PORT: ${{ job.services.db.ports['3306'] }}
3737
run: XDEBUG_MODE=coverage ./vendor/bin/pest --coverage --min=100

.github/workflows/pest.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ on: [ push, pull_request ]
44

55
jobs:
66
test:
7-
name: Pest - PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - ${{ matrix.dependency-version }}
7+
name: Pest - PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - DB ${{ matrix.db }} ${{ matrix.dependency-version }}
88

99
runs-on: ubuntu-latest
1010

1111
strategy:
12-
fail-fast: true
12+
fail-fast: false
1313
matrix:
1414
php: [ 8.1, 8.0 ]
1515
laravel: [ 9.*, 8.* ]
16+
db: [ 'mysql:8.0', 'mariadb:10.9' ]
1617
# dependency-version: [prefer-lowest, prefer-stable]
1718
dependency-version: [ prefer-stable ]
1819
include:
@@ -22,8 +23,8 @@ jobs:
2223
testbench: 7.*
2324

2425
services:
25-
mysql:
26-
image: mysql:8.0
26+
db:
27+
image: ${{ matrix.db }}
2728
env:
2829
MYSQL_ALLOW_EMPTY_PASSWORD: yes
2930
MYSQL_DATABASE: laravel_eloquent_spatial_test
@@ -48,5 +49,5 @@ jobs:
4849
4950
- name: Execute tests
5051
env:
51-
DB_PORT: ${{ job.services.mysql.ports['3306'] }}
52+
DB_PORT: ${{ job.services.db.ports['3306'] }}
5253
run: vendor/bin/pest

.github/workflows/phpstan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010

1111
strategy:
12-
fail-fast: true
12+
fail-fast: false
1313
matrix:
1414
php: [ 8.1, 8.0 ]
1515

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Laravel package to work with spatial data types and functions.
1010

11-
This package supports only MySQL 5.7 and 8.0.
11+
This package supports MySQL v8 and MariaDB v10.
1212

1313
## Installation
1414

phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ 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\(\)\.$#'
1516
excludePaths:
1617
- ./src/Factory.php
1718
checkMissingIterableValueType: true

src/GeometryCast.php

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

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

74+
$isMariaDb = $model->getConnection()->isMaria();
75+
76+
if ($isMariaDb) {
77+
// @codeCoverageIgnoreStart
78+
return DB::raw("ST_GeomFromText('{$wkt}', {$value->srid})");
79+
// @codeCoverageIgnoreEnd
80+
}
81+
7482
return DB::raw("ST_GeomFromText('{$wkt}', {$value->srid}, 'axis-order=long-lat')");
7583
}
7684

7785
private function extractWktFromExpression(Expression $expression): string
7886
{
79-
preg_match('/ST_GeomFromText\(\'(.+)\', .+, .+\)/', (string) $expression, $match);
87+
preg_match('/ST_GeomFromText\(\'(.+)\', .+(, .+)?\)/', (string) $expression, $match);
8088

8189
return $match[1];
8290
}
8391

8492
private function extractSridFromExpression(Expression $expression): int
8593
{
86-
preg_match('/ST_GeomFromText\(\'.+\', (.+), .+\)/', (string) $expression, $match);
94+
preg_match('/ST_GeomFromText\(\'.+\', (.+)(, .+)?\)/', (string) $expression, $match);
8795

8896
return (int) $match[1];
8997
}

src/SpatialBuilder.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,14 @@ protected function toExpression(Geometry|string $geometryOrColumn): Expression
265265
if ($geometryOrColumn instanceof Geometry) {
266266
$wkt = $geometryOrColumn->toWkt();
267267

268+
$isMariaDb = $this->getConnection()->isMaria();
269+
270+
if ($isMariaDb) {
271+
// @codeCoverageIgnoreStart
272+
return DB::raw("ST_GeomFromText('{$wkt}', {$geometryOrColumn->srid})");
273+
// @codeCoverageIgnoreEnd
274+
}
275+
268276
return DB::raw("ST_GeomFromText('{$wkt}', {$geometryOrColumn->srid}, 'axis-order=long-lat')");
269277
}
270278

tests/Objects/GeometryTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use Illuminate\Database\QueryException;
4+
use Illuminate\Support\Facades\DB;
45
use MatanYadaev\EloquentSpatial\Objects\LineString;
56
use MatanYadaev\EloquentSpatial\Objects\Point;
67
use MatanYadaev\EloquentSpatial\Tests\TestModels\TestPlace;
@@ -18,14 +19,14 @@
1819
$point = (new Point(91, 0, 4326));
1920
TestPlace::factory()->create(['point' => $point]);
2021
})->toThrow(QueryException::class);
21-
});
22+
})->skip(fn () => DB::isMaria());
2223

2324
it('throws exception when generating geometry with invalid longitude', function (): void {
2425
expect(function (): void {
2526
$point = (new Point(0, 181, 4326));
2627
TestPlace::factory()->create(['point' => $point]);
2728
})->toThrow(QueryException::class);
28-
});
29+
})->skip(fn () => DB::isMaria());
2930

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

tests/Objects/MultiLineStringTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
]),
100100
]);
101101

102-
$multiLineStringFromWkt = MultiLineString::fromWkt('MULTILINESTRING((180 0, 179 1))', );
102+
$multiLineStringFromWkt = MultiLineString::fromWkt('MULTILINESTRING((180 0, 179 1))');
103103

104104
expect($multiLineStringFromWkt)->toEqual($multiLineString);
105105
});

tests/SpatialBuilderTest.php

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use Illuminate\Foundation\Testing\DatabaseMigrations;
4+
use Illuminate\Support\Facades\DB;
45
use MatanYadaev\EloquentSpatial\Objects\LineString;
56
use MatanYadaev\EloquentSpatial\Objects\Point;
67
use MatanYadaev\EloquentSpatial\Objects\Polygon;
@@ -28,7 +29,18 @@
2829
->firstOrFail();
2930

3031
expect($testPlaceWithDistance->distance)->toBe(156897.79947260793);
31-
});
32+
})->skip(fn () => DB::isMaria());
33+
34+
it('calculates distance between column and geometry - MariaDB', function (): void {
35+
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
36+
37+
/** @var TestPlace $testPlaceWithDistance */
38+
$testPlaceWithDistance = TestPlace::query()
39+
->withDistance('point', new Point(1, 1, 4326))
40+
->firstOrFail();
41+
42+
expect($testPlaceWithDistance->distance)->toBe(1.4142135623730951);
43+
})->skip(fn () => ! DB::isMaria());
3244

3345
it('calculates distance with alias', function (): void {
3446
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
@@ -39,7 +51,18 @@
3951
->firstOrFail();
4052

4153
expect($testPlaceWithDistance->distance_in_meters)->toBe(156897.79947260793);
42-
});
54+
})->skip(fn () => DB::isMaria());
55+
56+
it('calculates distance with alias - MariaDB', function (): void {
57+
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
58+
59+
/** @var TestPlace $testPlaceWithDistance */
60+
$testPlaceWithDistance = TestPlace::query()
61+
->withDistance('point', new Point(1, 1, 4326), 'distance_in_meters')
62+
->firstOrFail();
63+
64+
expect($testPlaceWithDistance->distance_in_meters)->toBe(1.4142135623730951);
65+
})->skip(fn () => ! DB::isMaria());
4366

4467
it('filters by distance', function (): void {
4568
$pointWithinDistance = new Point(0, 0, 4326);
@@ -54,7 +77,22 @@
5477

5578
expect($testPlacesWithinDistance)->toHaveCount(1);
5679
expect($testPlacesWithinDistance[0]->point)->toEqual($pointWithinDistance);
57-
});
80+
})->skip(fn () => DB::isMaria());
81+
82+
it('filters by distance - MariaDB', function (): void {
83+
$pointWithinDistance = new Point(0, 0, 4326);
84+
$pointNotWithinDistance = new Point(50, 50, 4326);
85+
TestPlace::factory()->create(['point' => $pointWithinDistance]);
86+
TestPlace::factory()->create(['point' => $pointNotWithinDistance]);
87+
88+
/** @var TestPlace[] $testPlacesWithinDistance */
89+
$testPlacesWithinDistance = TestPlace::query()
90+
->whereDistance('point', new Point(1, 1, 4326), '<', 2)
91+
->get();
92+
93+
expect($testPlacesWithinDistance)->toHaveCount(1);
94+
expect($testPlacesWithinDistance[0]->point)->toEqual($pointWithinDistance);
95+
})->skip(fn () => ! DB::isMaria());
5896

5997
it('orders by distance ASC', function (): void {
6098
$closerTestPlace = TestPlace::factory()->create(['point' => new Point(1, 1, 4326)]);
@@ -102,7 +140,18 @@
102140
->firstOrFail();
103141

104142
expect($testPlaceWithDistance->distance)->toBe(157249.59776850493);
105-
});
143+
})->skip(fn () => DB::isMaria());
144+
145+
it('calculates distance sphere column and geometry - MariaDB', function (): void {
146+
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
147+
148+
/** @var TestPlace $testPlaceWithDistance */
149+
$testPlaceWithDistance = TestPlace::query()
150+
->withDistanceSphere('point', new Point(1, 1, 4326))
151+
->firstOrFail();
152+
153+
expect($testPlaceWithDistance->distance)->toBe(157249.0357231545);
154+
})->skip(fn () => ! DB::isMaria());
106155

107156
it('calculates distance sphere with alias', function (): void {
108157
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
@@ -113,7 +162,18 @@
113162
->firstOrFail();
114163

115164
expect($testPlaceWithDistance->distance_in_meters)->toBe(157249.59776850493);
116-
});
165+
})->skip(fn () => DB::isMaria());
166+
167+
it('calculates distance sphere with alias - MariaDB', function (): void {
168+
TestPlace::factory()->create(['point' => new Point(0, 0, 4326)]);
169+
170+
/** @var TestPlace $testPlaceWithDistance */
171+
$testPlaceWithDistance = TestPlace::query()
172+
->withDistanceSphere('point', new Point(1, 1, 4326), 'distance_in_meters')
173+
->firstOrFail();
174+
175+
expect($testPlaceWithDistance->distance_in_meters)->toBe(157249.0357231545);
176+
})->skip(fn () => ! DB::isMaria());
117177

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

0 commit comments

Comments
 (0)