64 lines
1.2 KiB
Go
64 lines
1.2 KiB
Go
package geo
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// ErrInvalidIP is returned when an IP cannot be parsed.
|
|
var ErrInvalidIP = errors.New("invalid ip address")
|
|
|
|
// ErrNotFound is returned when a backend cannot resolve the IP.
|
|
var ErrNotFound = errors.New("location not found")
|
|
|
|
type Backend string
|
|
|
|
const (
|
|
BackendMMDB Backend = "mmdb"
|
|
BackendPostgres Backend = "postgres"
|
|
)
|
|
|
|
type Config struct {
|
|
Backend Backend
|
|
MMDBPath string
|
|
DatabaseURL string
|
|
LookupQuery string
|
|
}
|
|
|
|
type Resolver interface {
|
|
Lookup(string) (Location, error)
|
|
Close() error
|
|
}
|
|
|
|
type Location struct {
|
|
IP string
|
|
Country string
|
|
Region string
|
|
City string
|
|
Address string
|
|
Latitude float64
|
|
Longitude float64
|
|
}
|
|
|
|
func NewResolver(cfg Config) (Resolver, error) {
|
|
switch cfg.Backend {
|
|
case "", BackendMMDB:
|
|
return newMMDBResolver(cfg.MMDBPath)
|
|
case BackendPostgres:
|
|
return newPostgresResolver(cfg.DatabaseURL, cfg.LookupQuery)
|
|
default:
|
|
return nil, fmt.Errorf("unsupported backend %q", cfg.Backend)
|
|
}
|
|
}
|
|
|
|
func buildAddress(parts ...string) string {
|
|
addressParts := make([]string, 0, len(parts))
|
|
for _, part := range parts {
|
|
if part != "" {
|
|
addressParts = append(addressParts, part)
|
|
}
|
|
}
|
|
return strings.Join(addressParts, ", ")
|
|
}
|