abh / geoip

GeoIP API for Golang
MIT License
234 stars 66 forks source link

Expose opened database type #31

Open ykhrustalev opened 6 years ago

ykhrustalev commented 6 years ago

It would be great to expose opened database type available via GeoIP.databaseType https://github.com/maxmind/geoip-api-c/blob/master/libGeoIP/GeoIP.h#L65.

Actual need lies in the fact that underline C library produces warning message to stdout in case API method is not supported on a given database type.

In my particular case I have a code which is intended to work with either country or city databases (yes, still legacy, there are reasons for that) and it tries to derive country code via all possible APIs. It is not quite straight forward to get the database type using the provided APIs.

Here is a snippet for country code

package main

import (
    "github.com/abh/geoip"
    "log"
    "path/filepath"
)

func main() {
    TestDb("GeoIPCity.dat")
    TestDb("GeoIP.dat")
}

func TestDb(path string) {
    ip := "109.106.142.207" // RU

    log.Printf("====")
    db, err := geoip.Open(path)
    if err != nil {
        log.Fatal(err.Error())
    }

    if db == nil {
        log.Fatal("nil pointer geo database")
    }

    // GeoIPCity.dat -> GetRecord
    // GeoIP.dat -> GetCountry

    log.Println("GetRecord before")
    record := db.GetRecord(ip)
    if record != nil {
        log.Printf("code = %s", record.CountryCode)
    }
    log.Println("GetRecord after")

    log.Println("GetCountry before")
    code, _ := db.GetCountry(ip)
    log.Printf("code = %s", code)
    log.Println("GetCountry after")
}

Possible workaround could be using reflection.

import (
  "reflect"
  "log"
)

func FindDatabaseType(db *geoip.GeoIP) {
    t := reflect.ValueOf(*db)
    val := t.FieldByName("db")
    dbType := val.Elem().FieldByName("databaseType")
    log.Printf("databaseType = %d", dbType.Int())
}

But making it explicit will be a more simple approach.

Pretty similar problem was addressed here https://github.com/balabit/syslog-ng/issues/1446

I am happy to submit PR for that.

ykhrustalev commented 6 years ago

looks like there is a PR with relevant change already https://github.com/horgh/geoip/commit/a3009019ae85b371b25dfd32a7027f3df6191c90

abh commented 6 years ago

A PR with a unit test would be good!

I agree it’s the best way to implement this, even if it is not a great API. I don’t think there’s anything worthwhile doing to fix the API, the awkwardness is just the C api shining through.

Ask