package geo import ( "errors" "net" "github.com/oschwald/geoip2-golang" ) type mmdbResolver struct { db *geoip2.Reader } func newMMDBResolver(dbPath string) (Resolver, error) { if dbPath == "" { return nil, errors.New("mmdb path is required") } db, err := geoip2.Open(dbPath) if err != nil { return nil, err } return &mmdbResolver{db: db}, nil } func (r *mmdbResolver) Close() error { return r.db.Close() } func (r *mmdbResolver) Lookup(ipStr string) (Location, error) { ip := net.ParseIP(ipStr) if ip == nil { return Location{}, ErrInvalidIP } record, err := r.db.City(ip) if err != nil { return Location{}, err } country := record.Country.Names["en"] region := "" if len(record.Subdivisions) > 0 { region = record.Subdivisions[0].Names["en"] } city := record.City.Names["en"] return Location{ IP: ip.String(), Country: country, Region: region, City: city, Address: buildAddress(city, region, country), Latitude: record.Location.Latitude, Longitude: record.Location.Longitude, }, nil }