feat: Add location search

This commit is contained in:
2026-02-21 01:50:59 +03:00
parent 26af8af8a9
commit a53b200c21
5 changed files with 327 additions and 105 deletions
+53 -1
View File
@@ -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
}