feat: Add location search
This commit is contained in:
+53
-1
@@ -35,7 +35,11 @@ func Open(path string) (Provider, error) {
|
||||
}
|
||||
|
||||
func (p Provider) Close() error {
|
||||
return p.db.Db.(*sql.DB).Close()
|
||||
if err := p.db.Db.(*sql.DB).Close(); err != nil {
|
||||
return fmt.Errorf("failed to close cities database: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type locationRow struct {
|
||||
@@ -46,6 +50,7 @@ type locationRow struct {
|
||||
CountryCode string `db:"country_code"`
|
||||
Latitude float64 `db:"latitude"`
|
||||
Longitude float64 `db:"longitude"`
|
||||
DistanceSq float64 `db:"distance_sq"`
|
||||
}
|
||||
|
||||
func (p Provider) SearchLocations(ctx context.Context, query string) ([]prayer.Location, error) {
|
||||
@@ -66,6 +71,7 @@ func (p Provider) SearchLocations(ctx context.Context, query string) ([]prayer.L
|
||||
goqu.I("country_code"),
|
||||
goqu.I("latitude"),
|
||||
goqu.I("longitude"),
|
||||
goqu.V(0).As("distance_sq"),
|
||||
).
|
||||
Where(
|
||||
goqu.Or(
|
||||
@@ -97,3 +103,49 @@ func (p Provider) SearchLocations(ctx context.Context, query string) ([]prayer.L
|
||||
|
||||
return locations, nil
|
||||
}
|
||||
|
||||
func (p Provider) SearchLocationsByCoords(ctx context.Context, coords prayer.Coordinates) ([]prayer.Location, error) {
|
||||
q := p.db.
|
||||
From("cities").
|
||||
Select(
|
||||
goqu.I("geoname_id"),
|
||||
goqu.I("name"),
|
||||
goqu.I("ascii_name"),
|
||||
goqu.COALESCE(goqu.I("alternate_names"), "").As("alternate_names"),
|
||||
goqu.I("country_code"),
|
||||
goqu.I("latitude"),
|
||||
goqu.I("longitude"),
|
||||
goqu.L(
|
||||
"((latitude - ?) * (latitude - ?) + (longitude - ?) * (longitude - ?))",
|
||||
coords.Latitude,
|
||||
coords.Latitude,
|
||||
coords.Longitude,
|
||||
coords.Longitude,
|
||||
).As("distance_sq"),
|
||||
).
|
||||
Order(
|
||||
goqu.I("distance_sq").Asc(),
|
||||
goqu.I("population").Desc(),
|
||||
).
|
||||
Limit(50)
|
||||
|
||||
var rows []locationRow
|
||||
if err := q.ScanStructsContext(ctx, &rows); err != nil {
|
||||
return nil, fmt.Errorf("failed to query locations by coordinates from cities database: %w", err)
|
||||
}
|
||||
|
||||
locations := make([]prayer.Location, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
locations = append(locations, prayer.Location{
|
||||
ID: row.ID,
|
||||
Name: row.Name,
|
||||
ASCIIName: row.ASCIIName,
|
||||
AlternateNames: row.AlternateNames,
|
||||
CountryCode: row.CountryCode,
|
||||
Latitude: row.Latitude,
|
||||
Longitude: row.Longitude,
|
||||
})
|
||||
}
|
||||
|
||||
return locations, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user