Skip to content

Conversation

@Cubixmeister
Copy link

This patch adds support for storing struct fields in database as serialized JSON.
I've tested it against MySQL and SQLite.

Simplistic example:

type JsonRow struct {
    Id   int
    Data *JsonField `db:"Data,json"`
}

type JsonField struct {
    Name string
    Age  int
}

func main() {
    db, _ := sql.Open("mymysql", "...")
    dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}
    dbmap.AddTableWithName(JsonRow{}, "json_test").SetKeys(true, "Id")
    dbmap.CreateTables()

    dbmap.Insert(&JsonRow{10, &JsonField{Name: "Karol", Age: 44}})
    dbmap.Insert(&JsonRow{0, &JsonField{Name: "Radek", Age: 23}})
    dbmap.Insert(&JsonRow{0, nil})

    var rows []JsonRow
    _, err := dbmap.Select(&rows, "SELECT * FROM json_test")
    fmt.Println(err)
    for i, v := range rows {
        fmt.Printf("> %d: %d %+v\n", i, v.Id, v.Data)
    }
}

@Cubixmeister
Copy link
Author

Travis is failing because of old MySQL version without JSON type support :(

@nelsam
Copy link
Member

nelsam commented Feb 7, 2017

I'd like to move away from having special cases for types in the code - there are too many branching code paths, already. Instead, consider using sql.Scanner and driver.Valuer here.

type JSONField struct {
    Name string `json:"name"`
    Age int `json:"age"`
}

func (f JSONField) Value() (driver.Value, error) {
    return json.Marshal(f)
}

func (f *JSONField) Scan(v interface{}) error {
    return json.Unmarshal(v.([]byte), f)
}

type JSONRow struct {
    ID int `db:"id"`
    Data JSONField `db:"data"`
}

For the database type of the field, we do need to be adding an interface type to gorp, unfortunately. We have SqlTyper, but it's not something we can use for generic data types - it's only allowed to return a driver.Value.

@icholy icholy mentioned this pull request Oct 18, 2017
@nelsam nelsam closed this Aug 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants