gorm + pg + inet === 最近 SQL 有儲存 IP 的需求,使用的是 cockroachDB,由於 protocol 跟 postgreSQL 一樣,所以先從 PG 著手,會發現有 [inet](https://www.postgresql.org/docs/current/datatype-net-types.html) 跟 cidr 可以使用,而在 golang 裡要如何使用 inet 與 cidr 呢?這個留到後面再煩惱,先把連線建立起來。 那就來試試吧,先啟動一個 CRDB,為了方便沒有使用憑證 ```shell= $ cockroach start-single-node \ --insecure \ --listen-addr=localhost:26257 \ --http-addr=localhost:8083 ``` 啟動後可以看到連線資訊 `postgresql:...` 記起來等一下連線可以使用 接著寫個小程式連線,使用 gorm 連線,可以在 [gorm](https://gorm.io/docs/connecting_to_the_database.html#PostgreSQL) 的官網找到範例程式 ```go= package main import ( "log" "gorm.io/driver/postgres" "gorm.io/gorm" ) func main() { dsn := "postgresql://localhost:26257/defaultdb?sslmode=disable&user=root" _, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { log.Fatal(err) } } ``` 接著如何使 golang 與 inet 產生連結? 尋找 [pgx](https://github.com/jackc/pgx/blob/c81bba8690f02264a7db0fa05900f2b4dc00ebdc/README.md?plain=1#L66) 會發現可以直接使用 `netip.Addr`,這真是太棒了,馬上來試試! 建立一個 ip 的 struct ``` type IP struct { gorm.Model IP netip.Addr Answer string } ``` 接著建立 migration ```go= var Migrations = []*gormigrate.Migration{ { ID: "20240515IP", Migrate: func(db *gorm.DB) error { return db.AutoMigrate(IP{}) }, Rollback: func(db *gorm.DB) error { return db.Migrator().DropTable(IP{}) }, }, } func main() { // ... m := gormigrate.New(db, gormigrate.DefaultOptions, Migrations) if err := m.Migrate(); err != nil { log.Fatal(err) } } ``` 會遇到錯誤 ``` [error] invalid field found for struct main.IP's field IP: define a valid foreign key for relations or implement the Valuer/Scanner interface ```