title: golang - Save enum type to SQL database "panic: sql: converting Exec argument #1's type: non-Value type int returned from Value"
body: <p>In my current go project (~5K LOC), I am using sqlite3 as my underlying database layer, and I am using gorm as my ORM engine. One of the models is a <code>Platform</code> with a field of <code>PlatformType</code> enum type. Here's a code snippet to demonstrate my problem.</p>
  
  <pre><code>package main
  
  import (
      _ "github.com/jinzhu/gorm/dialects/sqlite"
      "github.com/jinzhu/gorm"
      "database/sql/driver"
      "fmt"
  )
  
  /****************************\
      Object Layer
  \****************************/
  
  // Platform ID 
  type PlatformID string
  
  func (u *PlatformID) Scan(value interface{}) error { *u = PlatformID(value.([]byte)); return nil }
  func (u PlatformID) Value() (driver.Value, error)  { return string(u), nil }
  
  // Platform Type enumeration
  type PlatformType int
  const (
      PLATFORM_TYPE_NOT_A_VALUE PlatformType = iota
      PLATFORM_TYPE_TYPE1
      PLATFORM_TYPE_TYPE2 
  )
  
  var types = [...]string {
      "Not a type",
      "Type1",
      "Type2",
  }
  
  func (platform_type PlatformType) String() string {
      return types[platform_type]
  }
  
  func (u *PlatformType) Scan(value interface{}) error { *u = PlatformType(value.(int)); return nil }
  func (u PlatformType) Value() (driver.Value, error)  { return int(u), nil }
  
  // Platform descriptor.
  type Platform struct {
      ID              PlatformID          `json:"ID" gorm:"type:varchar(100);unique;not null"`                // Assigned by LCBO.
      Type            PlatformType        `json:"Type" gorm:"type:integer"`   
  }
  
  type PlatformStore interface {
      Init() error
      Save(platform *Platform) error
  }
  
  /****************************\
      Persist Layer
  \****************************/
  func NewSqlite3Store(dbname string) *gorm.DB {
      db, err := gorm.Open("sqlite3", dbname)
      if err != nil {
          panic("failed to connect database")
      }
      return db
  }
  
  type DBPlatformStore struct {
      db *gorm.DB
  }
  
  func NewDBPlatformStore(db *gorm.DB) PlatformStore {
      return &amp;DBPlatformStore{
          db: db,
      }
  }
  
  func (store *DBPlatformStore) Init() error {
      err := store.db.AutoMigrate(&amp;Platform{}).Error
      if err != nil {
          panic(err)
      }
      return err
  }
  
  func (store *DBPlatformStore) Save(platform *Platform) error {
      err := store.db.Create(platform).Error
      if err != nil {
          panic(err)
      }
      return err
  }
  
  /****************************\
      Application Layer
  \****************************/
  func main() {
      db := NewSqlite3Store("enum_test.db")
      platformStore := NewDBPlatformStore(db)
  
      fmt.Println("Initialize Database")
      err := platformStore.Init()
      if err != nil {
          panic(err)
      }
  
      platform := new(Platform)
      platform.ID = "12345"
      platform.Type = PLATFORM_TYPE_TYPE1
  
      platformStore.Save(platform)
  }
  </code></pre>
  
  <p>After running the code above, I got a runtime error "sql: converting Exec argument #1's type: non-Value type int returned from Value"</p>
  
  <pre><code>]# go run enumtest.go
  Initialize Database
  panic: sql: converting Exec argument #1's type: non-Value type int returned from Value
  
  goroutine 1 [running]:
  panic(0x66d380, 0xc8203ae350)
          /*/panic.go:481 +0x3e6
  main.(*DBPlatformStore).Save(0xc820020b20, 0xc820304500, 0x0, 0x0)
          /*/enumtest.go:84 +0x9f
  main.main()
          /*/enumtest.go:106 +0x247
  exit status 2
  </code></pre>
  
  <p>And I checked my database, the <code>platforms</code> table has been created successfully.</p>
  
  <pre><code>]# sqlite3 enum_test.db
  sqlite&gt; .schema platforms
  CREATE TABLE "platforms" ("id" varchar(100) NOT NULL UNIQUE,"type" integer , PRIMARY KEY ("id"));
  </code></pre>
  
  <p>The (not-so) trivial question is <strong>how do I modify my code so that I can correctly save the entry to database</strong>.</p>
  
  <p>My bigger question is: <strong>How to save a customized GO enum type to a sql database?</strong>(with a ORM engine hopefully)</p>