Skip to content

Commit

Permalink
Fix mariadb error regarding incorrect parameter count by separating q…
Browse files Browse the repository at this point in the history
…ueries based on database drivers.
  • Loading branch information
tkaratug committed Nov 27, 2024
1 parent fe243d6 commit 0663e7f
Showing 1 changed file with 99 additions and 34 deletions.
133 changes: 99 additions & 34 deletions src/Traits/HasSpatial.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,31 @@ public function scopeSelectDistanceTo(Builder $query, string $column, Point $poi
$query->select('*');
}

$query->selectRaw(
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) as distance",
[
$point->getSrid(),
$point->getLng(),
$point->getLat(),
$point->getSrid(),
]
);
match (DB::connection()->getDriverName()) {
'pgsql', 'mysql' => $this->selectDistanceToMysqlAndPostgres($query, $column, $point),
'mariadb' => $this->selectDistanceToMariaDb($query, $column, $point),
default => throw new \Exception('Unsupported database driver'),
};
}

public function scopeWithinDistanceTo(Builder $query, string $column, Point $point, int $distance): void
{
$query
->whereRaw("ST_AsText({$column}) != ?", [
'POINT(0 0)',
])
->whereRaw(
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) <= ?",
[
...[
$point->getSrid(),
$point->getLng(),
$point->getLat(),
$point->getSrid(),
],
$distance,
]
);
match (DB::connection()->getDriverName()) {
'pgsql', 'mysql' => $this->withinDistanceToMysqlAndPostgres($query, $column, $point, $distance),
'mariadb' => $this->withinDistanceToMariaDb($query, $column, $point, $distance),
default => throw new \Exception('Unsupported database driver'),
};
}

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

$query->orderByRaw(
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) " . $direction,
[
$point->getSrid(),
$point->getLng(),
$point->getLat(),
$point->getSrid(),
]
);
match (DB::connection()->getDriverName()) {
'pgsql', 'mysql' => $this->orderByDistanceToMysqlAndPostgres($query, $column, $point, $direction),
'mariadb' => $this->orderByDistanceToMariaDb($query, $column, $point, $direction),
default => throw new \Exception('Unsupported database driver'),
};
}

public function newQuery(): Builder
Expand All @@ -85,4 +66,88 @@ public function getLocationCastedAttributes(): Collection
{
return collect($this->getCasts())->filter(fn ($cast) => $cast === LocationCast::class)->keys();
}

private function selectDistanceToMysqlAndPostgres(Builder $query, string $column, Point $point): Builder
{
return $query->selectRaw(
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) as distance",
[
$point->getSrid(),
$point->getLng(),
$point->getLat(),
$point->getSrid(),
]
);
}

private function selectDistanceToMariaDb(Builder $query, string $column, Point $point): Builder
{
return $query->selectRaw(
"ST_Distance(ST_SRID({$column}), ST_SRID(Point(?, ?))) as distance",
[
$point->getLng(),
$point->getLat(),
]
);
}

private function withinDistanceToMysqlAndPostgres(Builder $query, string $column, Point $point, int $distance): Builder
{
return $query
->whereRaw("ST_AsText({$column}) != ?", [
'POINT(0 0)',
])
->whereRaw(
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) <= ?",
[
...[
$point->getSrid(),
$point->getLng(),
$point->getLat(),
$point->getSrid(),
],
$distance,
]
);
}

private function withinDistanceToMariaDb(Builder $query, string $column, Point $point, int $distance): Builder
{
return $query
->whereRaw("ST_AsText({$column}) != ?", [
'POINT(0 0)',
])
->whereRaw(
"ST_Distance(ST_SRID({$column}), ST_SRID(Point(?, ?))) <= ?",
[
$point->getLng(),
$point->getLat(),
$distance,
]
);
}

private function orderByDistanceToMysqlAndPostgres(Builder $query, string $column, Point $point, string $direction = 'asc'): Builder
{
return $query->orderByRaw(
"ST_Distance(ST_SRID({$column}, ?), ST_SRID(Point(?, ?), ?)) " . $direction,
[
$point->getSrid(),
$point->getLng(),
$point->getLat(),
$point->getSrid(),
]
);
}

private function orderByDistanceToMariaDb(Builder $query, string $column, Point $point, string $direction = 'asc'): Builder
{
return $query->orderByRaw(
"ST_Distance(ST_SRID({$column}), ST_SRID(Point(?, ?))) " . $direction,
[
$point->getLng(),
$point->getLat(),
]
);
}
}

0 comments on commit 0663e7f

Please sign in to comment.