maxmind/mmdbwriter

How to insert custom region data with ipaddr

intfish123 opened this issue · 2 comments

I want to insert some ips into a new mmdb file.
The code for inserting custom data:

writer, err := mmdbwriter.New(
	mmdbwriter.Options{
		DatabaseType: "GeoLite2-City",
		RecordSize:   24,
		Languages: []string{"en"},
	},
)
if err != nil {
	return err
}

nameId := 0
for i:=0; i<len(customData); i++ {
		record := mmdbtype.Map{}
		record["country"] = mmdbtype.Map{"geoname_id": mmdbtype.Uint64(nameId),"names":mmdbtype.Map{"en": mmdbtype.String(customData[i].Country)}}
		nameId++

		record["province"] = mmdbtype.Map{"geoname_id": mmdbtype.Uint64(nameId),"names":mmdbtype.Map{"en": mmdbtype.String(customData[i].Province)}}
		nameId++

		record["city"] = mmdbtype.Map{"geoname_id": mmdbtype.Uint64(nameId),"names":mmdbtype.Map{"en": mmdbtype.String(customData[i].City)}}
		nameId++

		record["county"] = mmdbtype.Map{"geoname_id": mmdbtype.Uint64(nameId),"names":mmdbtype.Map{"en": mmdbtype.String(customData[i].County)}}
		nameId++

		tmpIp := net.ParseIP(customData[i].ipVal)
		writer.Insert(&net.IPNet{IP: tmpIp, Mask: tmpIp.DefaultMask()}, record)
}
fh, err := os.Create("out/out.mmdb")
if err != nil {
	log.Fatal(err)
}
_, err = writer.WriteTo(fh)
if err != nil {
	log.Fatal(err)
}

Then I search ip for testing:

city, err := geoip2Reader.City(net.ParseIP(ipStr))
	if err == nil {
		marshal, _ := json.Marshal(city)
		zap.S().Info(string(marshal))
	}

The result of searching is not correct.
Am I doing something wrong?

There is no field in GeoIP2 City called province. That should be replaced with subdivisions, which is an array of objects. See, e.g., this.

I rewrote my code like this, But it still doesn't work, you can try it:

writer, err := mmdbwriter.New(
	mmdbwriter.Options{
		DatabaseType: "GeoLite2-City",
			RecordSize: 24,
			IPVersion: 4,
			IncludeReservedNetworks: true,
			Languages: []string{"zh-CN"},
	},
)
if err != nil {
	return err
}

nameId := 0
for i:=0; i<len(customData); i++ {
	record := mmdbtype.Map{}
	record["continent"] = mmdbtype.Map{
		"geoname_id": mmdbtype.Uint64(nameId),
		"code": mmdbtype.String(""),
		"names":mmdbtype.Map{"zh-CN": mmdbtype.String("")},
	}
	nameId++

	record["country"] = mmdbtype.Map{
		"geoname_id": mmdbtype.Uint64(nameId),
		"iso_code": mmdbtype.String(""),
		"names":mmdbtype.Map{"zh-CN": mmdbtype.String(customData[i].Country)},
	}
	nameId++

	record["subdivisions"] = mmdbtype.Slice{
		mmdbtype.Map{
			"geoname_id": mmdbtype.Uint64(nameId),
			"iso_code": mmdbtype.String(""),
			"names":mmdbtype.Map{"zh-CN": mmdbtype.String(customData[i].Province)},
	  },
	}
	nameId++

	record["city"] = mmdbtype.Map{
		"geoname_id": mmdbtype.Uint64(nameId),
		"names":mmdbtype.Map{"zh-CN": mmdbtype.String(customData[i].City)},
	}
	nameId++

	record["county"] = mmdbtype.Map{
		"geoname_id": mmdbtype.Uint64(nameId),
		"names":mmdbtype.Map{"zh-CN": mmdbtype.String(customData[i].County)},
	}
	nameId++

	record["location"] = mmdbtype.Map{
		"accuracy_radius": mmdbtype.Uint16(0),
		"latitude": mmdbtype.Float64(0),
		"longitude": mmdbtype.Float64(0),
		"metro_code": mmdbtype.Uint64(0),
		"time_zone": mmdbtype.String(""),
	}
	nameId++

	record["postal"] = mmdbtype.Map{
		"code": mmdbtype.String(""),
	}
	nameId++

	record["registered_country"] = mmdbtype.Map{
		"geoname_id": mmdbtype.Uint64(nameId),
		"is_in_european_union": mmdbtype.Bool(false),
		"iso_code": mmdbtype.String(""),
		"names": mmdbtype.Map{"zh-CN": mmdbtype.String("")},
	}
	nameId++

	record["represented_country"] = mmdbtype.Map{
		"geoname_id": mmdbtype.Uint64(nameId),
		"is_in_european_union": mmdbtype.Bool(false),
		"iso_code": mmdbtype.String(""),
		"type": mmdbtype.String(""),
		"names": mmdbtype.Map{"zh-CN": mmdbtype.String("")},
	}
	nameId++
	nameId++

	tmpIp := net.ParseIP(customData[i].ipVal)
	writer.Insert(&net.IPNet{IP: tmpIp, Mask: tmpIp.DefaultMask()}, record)
}
fh, err := os.Create("out/out.mmdb")
if err != nil {
	log.Fatal(err)
}
_, err = dbWriter.WriteTo(fh)
if err != nil {
	log.Fatal(err)
}