Skip to content

Commit 0663e7f

Browse files
committed
Fix mariadb error regarding incorrect parameter count by separating queries based on database drivers.
1 parent fe243d6 commit 0663e7f

File tree

1 file changed

+99
-34
lines changed

1 file changed

+99
-34
lines changed

src/Traits/HasSpatial.php

+99-34
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,31 @@ public function scopeSelectDistanceTo(Builder $query, string $column, Point $poi
1818
$query->select('*');
1919
}
2020

21-
$query->selectRaw(
22-
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) as distance",
23-
[
24-
$point->getSrid(),
25-
$point->getLng(),
26-
$point->getLat(),
27-
$point->getSrid(),
28-
]
29-
);
21+
match (DB::connection()->getDriverName()) {
22+
'pgsql', 'mysql' => $this->selectDistanceToMysqlAndPostgres($query, $column, $point),
23+
'mariadb' => $this->selectDistanceToMariaDb($query, $column, $point),
24+
default => throw new \Exception('Unsupported database driver'),
25+
};
3026
}
3127

3228
public function scopeWithinDistanceTo(Builder $query, string $column, Point $point, int $distance): void
3329
{
34-
$query
35-
->whereRaw("ST_AsText({$column}) != ?", [
36-
'POINT(0 0)',
37-
])
38-
->whereRaw(
39-
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) <= ?",
40-
[
41-
...[
42-
$point->getSrid(),
43-
$point->getLng(),
44-
$point->getLat(),
45-
$point->getSrid(),
46-
],
47-
$distance,
48-
]
49-
);
30+
match (DB::connection()->getDriverName()) {
31+
'pgsql', 'mysql' => $this->withinDistanceToMysqlAndPostgres($query, $column, $point, $distance),
32+
'mariadb' => $this->withinDistanceToMariaDb($query, $column, $point, $distance),
33+
default => throw new \Exception('Unsupported database driver'),
34+
};
5035
}
5136

5237
public function scopeOrderByDistanceTo(Builder $query, string $column, Point $point, string $direction = 'asc'): void
5338
{
5439
$direction = strtolower($direction) === 'asc' ? 'asc' : 'desc';
5540

56-
$query->orderByRaw(
57-
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) " . $direction,
58-
[
59-
$point->getSrid(),
60-
$point->getLng(),
61-
$point->getLat(),
62-
$point->getSrid(),
63-
]
64-
);
41+
match (DB::connection()->getDriverName()) {
42+
'pgsql', 'mysql' => $this->orderByDistanceToMysqlAndPostgres($query, $column, $point, $direction),
43+
'mariadb' => $this->orderByDistanceToMariaDb($query, $column, $point, $direction),
44+
default => throw new \Exception('Unsupported database driver'),
45+
};
6546
}
6647

6748
public function newQuery(): Builder
@@ -85,4 +66,88 @@ public function getLocationCastedAttributes(): Collection
8566
{
8667
return collect($this->getCasts())->filter(fn ($cast) => $cast === LocationCast::class)->keys();
8768
}
69+
70+
private function selectDistanceToMysqlAndPostgres(Builder $query, string $column, Point $point): Builder
71+
{
72+
return $query->selectRaw(
73+
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) as distance",
74+
[
75+
$point->getSrid(),
76+
$point->getLng(),
77+
$point->getLat(),
78+
$point->getSrid(),
79+
]
80+
);
81+
}
82+
83+
private function selectDistanceToMariaDb(Builder $query, string $column, Point $point): Builder
84+
{
85+
return $query->selectRaw(
86+
"ST_Distance(ST_SRID({$column}), ST_SRID(Point(?, ?))) as distance",
87+
[
88+
$point->getLng(),
89+
$point->getLat(),
90+
]
91+
);
92+
}
93+
94+
private function withinDistanceToMysqlAndPostgres(Builder $query, string $column, Point $point, int $distance): Builder
95+
{
96+
return $query
97+
->whereRaw("ST_AsText({$column}) != ?", [
98+
'POINT(0 0)',
99+
])
100+
->whereRaw(
101+
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) <= ?",
102+
[
103+
...[
104+
$point->getSrid(),
105+
$point->getLng(),
106+
$point->getLat(),
107+
$point->getSrid(),
108+
],
109+
$distance,
110+
]
111+
);
112+
}
113+
114+
private function withinDistanceToMariaDb(Builder $query, string $column, Point $point, int $distance): Builder
115+
{
116+
return $query
117+
->whereRaw("ST_AsText({$column}) != ?", [
118+
'POINT(0 0)',
119+
])
120+
->whereRaw(
121+
"ST_Distance(ST_SRID({$column}), ST_SRID(Point(?, ?))) <= ?",
122+
[
123+
$point->getLng(),
124+
$point->getLat(),
125+
$distance,
126+
]
127+
);
128+
}
129+
130+
private function orderByDistanceToMysqlAndPostgres(Builder $query, string $column, Point $point, string $direction = 'asc'): Builder
131+
{
132+
return $query->orderByRaw(
133+
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) " . $direction,
134+
[
135+
$point->getSrid(),
136+
$point->getLng(),
137+
$point->getLat(),
138+
$point->getSrid(),
139+
]
140+
);
141+
}
142+
143+
private function orderByDistanceToMariaDb(Builder $query, string $column, Point $point, string $direction = 'asc'): Builder
144+
{
145+
return $query->orderByRaw(
146+
"ST_Distance(ST_SRID({$column}), ST_SRID(Point(?, ?))) " . $direction,
147+
[
148+
$point->getLng(),
149+
$point->getLat(),
150+
]
151+
);
152+
}
88153
}

0 commit comments

Comments
 (0)