Save application and database code separately.
// Role belongs to app code, no compromises. type Role struct { Id int64 Code string }
Database model.
// Database has tables with columns. type Table struct { Name string Columns []string } var RoleTable = Table{ Name: "roles", Columns: []string{ "id", "code", }, }
Enter the code once to convert between the model and the database row.
// Database package needs to make it work. // Write a model to database row. type Writer struct { Role } func (w *Writer) Write() []interface{} { return []interface{}{ w.Role.Id, sql.NullString{ Valid: len(w.Role.Code) > 0, String: w.Role.String, }, } } // Read a database row into model. type Reader struct { Id int64 Code sql.NullString } func (r *Reader) Scan(row *sql.Row) error { return row.Scan( &r.Id, &r.Code, ) } func (r *Reader) Read() Role { return Role{ Id: r.Id, Code: r.Code.String, } }
Your schema is separate from the application model. When saving or loading, you can smooth out structures such as user contact information.
// Nested struct in app code. type User struct { TwitterProfile struct { Id string ScreenName string } } // Database row is normalized flat. var UserTable = Table{ Name: "users", Columns: []string{ "twitter_id", "twitter_screen_name", }, }
He is flexible. You can even scan join strings without intermediate structures.
type RowMux struct { vs []interface{} } func (mux *RowMux) Scan(vs ...interface{}) error { mux.vs = append(mux.vs, vs...) return nil } func (mux *RowMux) Mux(row *sql.Row) error { return row.Scan(mux.vs...) }
Ajcodez
source share