Skip to content

Instantly share code, notes, and snippets.

@dimroc
Last active January 26, 2019 01:03
Show Gist options
  • Save dimroc/cd124c0955aeccaac0542aa9f3b20f8e to your computer and use it in GitHub Desktop.
Save dimroc/cd124c0955aeccaac0542aa9f3b20f8e to your computer and use it in GitHub Desktop.
Reproduce issue where the underlying db will change the Scan type in `gorm`: https://github.com/jinzhu/gorm/issues/2276
package main
import (
"database/sql/driver"
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
func main() {
dbSqlite, err := gorm.Open("sqlite3", "test.db")
checkErr(err)
dbPostgres, err := gorm.Open("postgres", "postgres://localhost:5432/gorm?sslmode=disable")
checkErr(err)
run("sqlite3 Scan into []uint8", dbSqlite)
run("postgres Scan into []uint8", dbPostgres)
}
func run(label string, db *gorm.DB) {
db.LogMode(true)
instance := Table{CustomType: CustomType("hello world")}
checkErr(db.AutoMigrate(instance).Error)
checkErr(db.Save(&instance).Error)
var retrieved Table
err := db.First(&retrieved).Error
if err != nil {
fmt.Println(label, "failed", err)
} else {
fmt.Println(label, "success")
}
}
type Table struct {
gorm.Model
CustomType CustomType
}
type CustomType string
// Value returns this instance serialized for database storage.
func (ct CustomType) Value() (driver.Value, error) {
return string(ct), nil
}
// Scan reads the database value and returns an instance.
func (ct *CustomType) Scan(value interface{}) error {
temp, ok := value.([]uint8)
if !ok {
return fmt.Errorf("Unable to convert %v of %T to CustomType", value, value)
}
*ct = CustomType(temp)
return nil
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
dimroc@Dimitris-MBP-2018: gomod $ go run gorm_diff_types_repro.go
(/Users/dimroc/workspace/garbage/gomod/gorm_diff_types_repro.go:26)
[2019-01-25 20:00:31] [0.41ms] INSERT INTO "tables" ("created_at","updated_at","deleted_at","custom_type") VALUES ('2019-01-25 20:00:31','2019-01-25 20:00:31',NULL,'hello world')
[1 rows affected or returned ]
(/Users/dimroc/workspace/garbage/gomod/gorm_diff_types_repro.go:29)
[2019-01-25 20:00:31] [0.17ms] SELECT * FROM "tables" WHERE "tables"."deleted_at" IS NULL ORDER BY "tables"."id" ASC LIMIT 1
[1 rows affected or returned ]
sqlite3 Scan into []uint8 success
(/Users/dimroc/workspace/garbage/gomod/gorm_diff_types_repro.go:26)
[2019-01-25 20:00:31] [0.70ms] INSERT INTO "tables" ("created_at","updated_at","deleted_at","custom_type") VALUES ('2019-01-25 20:00:31','2019-01-25 20:00:31',NULL,'hello world') RETURNING "tables"."id"
[1 rows affected or returned ]
(/Users/dimroc/workspace/garbage/gomod/gorm_diff_types_repro.go:29)
[2019-01-25 20:00:31] sql: Scan error on column index 4, name "custom_type": Unable to convert hello world of string to CustomType
(/Users/dimroc/workspace/garbage/gomod/gorm_diff_types_repro.go:29)
[2019-01-25 20:00:31] [0.64ms] SELECT * FROM "tables" WHERE "tables"."deleted_at" IS NULL ORDER BY "tables"."id" ASC LIMIT 1
[1 rows affected or returned ]
postgres Scan into []uint8 failed sql: Scan error on column index 4, name "custom_type": Unable to convert hello world of string to CustomType
dimroc@Dimitris-MBP-2018: gomod $ vim gorm_diff_types_repro.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment