Warning: This is the Structable 4 development branch. For a stable release, use version 3.1.0. Structable development happens very slowly.
This library provides basic struct-to-table mapping for Go.
It is based on the Squirrel library.
Structable maps a struct (Record) to a database table via a structable.Recorder. It is intended to be used as a back-end tool for building systems like Active Record mappers.
It is designed to satisfy a CRUD-centered record management system, filling the following contract:
typeRecorderinterface{Bind(string, Record) Recorder// link struct to tableInterface() interface{} // Get the struct that has been linkedInsert() error// INSERT just one recordUpdate() error// UPDATE just one recordDelete() error// DELETE just one recordExists() (bool, error) // Check for just one recordExistsWhere(condinterface{}, args...interface{}) (bool, error) Load() error// SELECT just one recordLoadWhere(condinterface{}, args...interface{}) error// Alternate Load() }Squirrel already provides the ability to perform more complicated operations.
The usual way...
$ glide get github.com/Masterminds/structable $ # or... $ go get github.com/Masterminds/structable And import it via:
import "github.com/Masterminds/structable" Structable works by mapping a struct to columns in a database.
To annotate a struct, you do something like this:
typeStoolstruct{Idint`stbl:"id, PRIMARY_KEY, AUTO_INCREMENT"`Legsint`stbl:"number_of_legs"`Materialstring`stbl:"material"`Ignoredstring// will not be stored. No tag. }To manage instances of this struct, you do something like this:
stool:=new(Stool) stool.Material="Wood"db:=getDb() // Get a sql.Db. You're on the hook to do this part.// Create a new structable.Recorder and tell it to// bind the given struct as a row in the given table.r:=structable.New(db, "mysql").Bind("test_table", stool) // This will insert the stool into the test_table.err:=r.Insert()And of course you have Load(), Update(), Delete() and so on.
The target use case for Structable is to use it as a backend for an Active Record pattern. An example of this can be found in the structable_test.go file
Most of Structable focuses on individual objects, but there are helpers for listing objects:
// Get a list of things that have the same type as object.stool:=new(Stool) items, err:=structable.List(stool, offset, limit) // Customize a list of things that have the same type as object.fn=func(object structable.Describer, sql squirrel.SelectBuilder) (squirrel.SelectBuilder, error){returnsql.Limit(10), nil } items, err:=structable.ListWhere(stool, fn)For example, here is a function that uses ListWhere to get collection of definitions from a table described in a struct named Table:
func (s*SchemaInfo) Tables() ([]*Table, error){// Bind a new recorder. We use an empty object just to get the field// data for that struct.t:=&Table{} st:=structable.New(s.Queryer, s.Driver).Bind(t.TableName(), t) // We want to return no more than 10 of these.fn:=func(d structable.Describer, q squirrel.SelectBuilder) (squirrel.SelectBuilder, error){returnq.Limit(10), nil } // Fetch a list of Table structs.items, err:=structable.ListWhere(st, fn) iferr!=nil{return []*Table{}, err } // Because we get back a []Recorder, we need to get the original data// back out. We have to manually convert it back to its real type.tables:=make([]*Table, len(items)) fori, item:=rangeitems{tables[i] =item.Interface().(*Table) } returntables, nil }- MySQL (5.5)
- PostgreSQL (9.3, 9.4, 9.6)
- SQLite 3
It does not...
- Create or manage schemas.
- Guess or enforce table or column names. (You have to tell it how to map.)
- Provide relational mapping.
- Handle bulk operations (use Squirrel for that)
This software is licensed under an MIT-style license. See LICENSE.txt
