Documentation
¶
Overview ¶
The `model` package essentially provides a lightweight object relational model (ORM) based on sqlite3 intended to support the needs of the `container` package. Each entity (table) is modeled by a struct. Each field (column) is described using tags:
`sql:"pk"` The primary key. `sql:"key"` The field is part of the natural key. `sql:"fk:T(F)"` Foreign key `T` = model type, `F` = model field. `sql:"unique(G)"` Unique index. `G` = unique-together fields. `sql:"const"` The field is immutable and not included on update.
Each struct must implement the `Model` interface. Basic CRUD operations may be performed on each model using the `DB` interface which together with the `Model` interface provides value-added features and optimizations.
Examples:
Define a model.
type Person struct { ID string `sql:"pk"` First string `sql:"key"` Last string `sql:"key" Age int `sql:""` } func (p *Person) Pk() string {...} func (p *Person) Equals(other Model) bool {...} func (p *Person) Labels() {...} func (p *Person) String() string {...}
Insert the model:
person := &Person{ First: "Elmer", Last: "Fudd", Age: 55, } err := DB.Insert(person)
In the event the primary key (PK) field is not populated, the DB will derive (generate) its value as a sha1 of the natural key fields.
Update the model:
person.Age = 62 err := DB.Update(person)
Delete the model by natural key:
person := &Person{ First: "Elmer", Last: "Fudd", } err := DB.Delete(person)
Get (fetch) a single model by natural key. This will populate the fields with data from the DB.
person := &Person{ First: "Elmer", Last: "Fudd", } err := DB.Get(person)
List (fetch) all models.
persons := []Person{} err := DB.List(&persons, ListOptions{})
List (fetch) specific models. The `ListOptions` may be used to qualify or paginate the List() result set. All predicates may be combined.
Count (only):
err := DB.List(&persons, ListOptions{Count: true})
Paginate the result:
err := DB.List( &persons, ListOptions{ Page: { Offset: 3, // page 3. Limit: 10, // 10 models per page. }, })
List specific models. List persons with the last name of "Fudd" and legal to vote.
err := DB.List( &persons, ListOptions{ Predicate: And( Eq("Name", "Fudd"), Gt("Age": 17), }, })
Index ¶
- Constants
- Variables
- type AndPredicate
- type Base
- type Client
- func (r *Client) Begin() (*Tx, error)
- func (r *Client) Close(purge bool) error
- func (r *Client) Count(model Model, predicate Predicate) (int64, error)
- func (r *Client) Delete(model Model) error
- func (r *Client) EndWatch(watch *Watch)
- func (r *Client) Get(model Model) error
- func (r *Client) Insert(model Model) error
- func (r *Client) Journal() *Journal
- func (r *Client) List(list interface{}, options ListOptions) error
- func (r *Client) Open(purge bool) error
- func (r *Client) Update(model Model) error
- func (r *Client) Watch(model Model, handler EventHandler) (*Watch, error)
- type CompoundPredicate
- type DB
- type DBTX
- type EqPredicate
- type Event
- type EventHandler
- type FK
- type Field
- func (f *Field) AsValue(object interface{}) (value interface{}, err error)
- func (f *Field) DDL() string
- func (f *Field) Fk() *FK
- func (f *Field) Key() bool
- func (f *Field) Mutable() bool
- func (f *Field) Param() string
- func (f *Field) Pk() bool
- func (f *Field) Ptr() interface{}
- func (f *Field) Pull() interface{}
- func (f *Field) Push()
- func (f *Field) Unique() []string
- func (f *Field) Validate() error
- type GtPredicate
- type Journal
- func (r *Journal) Commit()
- func (r *Journal) Created(model Model)
- func (r *Journal) Deleted(model Model)
- func (r *Journal) Disable()
- func (r *Journal) Enable()
- func (r *Journal) Enabled() bool
- func (r *Journal) End(watch *Watch)
- func (r *Journal) Unstage()
- func (r *Journal) Updated(model Model, updated Model)
- func (r *Journal) Watch(model Model, handler EventHandler) (*Watch, error)
- type Label
- type LabelPredicate
- type Labeler
- type Labels
- type ListOptions
- type LtPredicate
- type Model
- type NeqPredicate
- type OrPredicate
- type Page
- type Predicate
- type Row
- type SimplePredicate
- type Table
- func (t Table) Constraints(fields []*Field) []string
- func (t Table) Count(model interface{}, predicate Predicate) (int64, error)
- func (t Table) DDL(model interface{}) ([]string, error)
- func (t Table) Delete(model interface{}) error
- func (t Table) Fields(model interface{}) ([]*Field, error)
- func (t Table) Get(model interface{}) error
- func (t Table) Insert(model interface{}) error
- func (t Table) KeyFields(fields []*Field) []*Field
- func (t Table) List(list interface{}, options ListOptions) error
- func (t Table) MutableFields(fields []*Field) []*Field
- func (t Table) Name(model interface{}) string
- func (t Table) Params(fields []*Field) []interface{}
- func (t Table) PkField(fields []*Field) *Field
- func (t Table) SetPk(fields []*Field) error
- func (t Table) Update(model interface{}) error
- func (t Table) Validate(fields []*Field) error
- type TmplData
- type Tx
- func (r *Tx) Commit() (err error)
- func (r *Tx) Count(model Model, predicate Predicate) (int64, error)
- func (r *Tx) Delete(model Model) error
- func (r *Tx) End() (err error)
- func (r *Tx) Get(model Model) error
- func (r *Tx) Insert(model Model) error
- func (r *Tx) List(list interface{}, options ListOptions) error
- func (r *Tx) Update(model Model) error
- type Watch
Constants ¶
const (
Pragma = "PRAGMA foreign_keys = ON"
)
const (
Tag = "sql"
)
Variables ¶
var ( Created int8 = 0x01 Updated int8 = 0x02 Deleted int8 = 0x04 )
Event Actions.
var ( // Must have PK. MustHavePkErr = errors.New("must have PK field") // Parameter must be pointer error. MustBePtrErr = errors.New("must be pointer") // Must be slice pointer. MustBeSlicePtrErr = errors.New("must be slice pointer") // Parameter must be struct error. MustBeObjectErr = errors.New("must be object") // Field type error. FieldTypeErr = errors.New("field type must be (int, str, bool") // PK field type error. PkTypeErr = errors.New("pk field must be (int, str)") // Generated PK error. GenPkTypeErr = errors.New("PK field must be `str` when generated") // Invalid field referenced in predicate. PredicateRefErr = errors.New("predicate referenced unknown field") // Invalid predicate for type of field. PredicateTypeErr = errors.New("predicate type not valid for field") // Invalid predicate value. PredicateValueErr = errors.New("predicate value not valid") )
Errors
var DeleteSQL = `
DELETE FROM {{.Table}}
WHERE
{{ .Pk.Name }} = {{ .Pk.Param }}
;
`
var FkRegex = regexp.MustCompile(`(fk):(.+)(\()(.+)(\))`)
Regex used for `fk:<table>(field)` tags.
var GetSQL = `` /* 143-byte string literal not displayed */
var IndexDDL = `` /* 141-byte string literal not displayed */
var InsertSQL = `` /* 196-byte string literal not displayed */
SQL templates.
var LabelSQL = `` /* 246-byte string literal not displayed */
Label SQL.
var ListSQL = `` /* 426-byte string literal not displayed */
var NotFound = sql.ErrNoRows
Errors.
var TableDDL = `` /* 177-byte string literal not displayed */
DDL templates.
var UniqueRegex = regexp.MustCompile(`(unique)(\()(.+)(\))`)
Regex used for `unique(group)` tags.
var UpdateSQL = `` /* 159-byte string literal not displayed */
Functions ¶
This section is empty.
Types ¶
type Base ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Database client.
func (*Client) Begin ¶
Begin a transaction. Example:
tx, _ := client.Begin() defer tx.End() client.Insert(model) client.Insert(model) tx.Commit()
func (*Client) List ¶
func (r *Client) List(list interface{}, options ListOptions) error
List models. The `list` must be: *[]Model.
type CompoundPredicate ¶
type CompoundPredicate struct { // List of predicates. Predicates []Predicate }
Compound predicate.
type DB ¶
type DB interface { // Open and build the schema. Open(bool) error // Close. Close(bool) error // Get the specified model. Get(Model) error // List models based on the type of slice. List(interface{}, ListOptions) error // Count based on the specified model. Count(Model, Predicate) (int64, error) // Begin a transaction. Begin() (*Tx, error) // Insert a model. Insert(Model) error // Update a model. Update(Model) error // Delete a model. Delete(Model) error // Watch a model collection. Watch(Model, EventHandler) (*Watch, error) // End a watch. EndWatch(watch *Watch) // The journal Journal() *Journal }
Database client.
type DBTX ¶
type DBTX interface { Exec(string, ...interface{}) (sql.Result, error) Query(string, ...interface{}) (*sql.Rows, error) QueryRow(string, ...interface{}) *sql.Row }
Database client interface. Support model methods taking either sql.DB or sql.Tx.
type Event ¶
type Event struct { // The event subject. Model Model // The event action (created|updated|deleted). Action int8 // The updated model. Updated Model }
Model event.
type EventHandler ¶
type EventHandler interface { // A model has been created. Created(Event) // A model has been updated. Updated(Event) // A model has been deleted. Deleted(Event) // An error has occurred delivering an event. Error(error) // An event watch has ended. End() }
Event handler.
type Field ¶
type Field struct { // reflect.Value of the field. Value *reflect.Value // Tags. Tag string // Field name. Name string // contains filtered or unexported fields }
Model (struct) Field Tags:
`sql:"pk"` The primary key. `sql:"key"` The field is part of the natural key. `sql:"fk:T(F)"` Foreign key `T` = model type, `F` = model field. `sql:"unique(G)"` Unique index. `G` = unique-together fields. `sql:"const"` The field is immutable and not included on update.
func (*Field) Pull ¶
func (f *Field) Pull() interface{}
Pull from model. Populate the appropriate `staging` field using the model field value.
type Journal ¶
type Journal struct {
// contains filtered or unexported fields
}
Event manager.
func (*Journal) Disable ¶
func (r *Journal) Disable()
Disable the journal. End all watches and discard staged events.
type Label ¶
type Label struct { PK string `sql:"pk"` Parent string `sql:"key"` Kind string `sql:"key"` Name string `sql:"key"` Value string `sql:""` }
Label model
type LabelPredicate ¶
type LabelPredicate struct { // Labels Labels // contains filtered or unexported fields }
Label predicate.
type Labeler ¶ added in v0.1.1
type Labeler struct { }
Labeler.
type ListOptions ¶
type ListOptions struct { // Pagination. Page *Page // Sort by field position. Sort []int // Predicate Predicate Predicate // contains filtered or unexported fields }
List options.
func (*ListOptions) Build ¶
func (l *ListOptions) Build(table string, fields []*Field) error
Validate options.
func (*ListOptions) Param ¶
func (l *ListOptions) Param(name string, value interface{}) string
Get an appropriate parameter name. Builds a parameter and adds it to the options.param list.
func (*ListOptions) Params ¶
func (l *ListOptions) Params() []interface{}
Get params referenced by the predicate.
type Model ¶
type Model interface { // Get the primary key. Pk() string // Get description of the model. String() string // Equal comparison. Equals(other Model) bool // Get labels. // Optional and may return nil. Labels() Labels }
Model Each model represents a table in the DB.
type Predicate ¶
type Predicate interface { // Build the predicate. Build(*ListOptions) error // Get the SQL expression. Expr() string }
List predicate.
type Row ¶
type Row interface {
Scan(...interface{}) error
}
Database interface. Support model `Scan` taking either sql.Row or sql.Rows.
type SimplePredicate ¶
type SimplePredicate struct { // Field name. Field string // Field value. Value interface{} // contains filtered or unexported fields }
Simple predicate.
type Table ¶
type Table struct { // Database connection. DB DBTX }
Represents a table in the DB. Using reflect, the model is inspected to determine the table name and columns. The column definition is specified using field tags:
pk - Primary key. key - Natural key. fk:<table>(field) - Foreign key. unique(<group>) - Unique constraint collated by <group>. const - Not updated.
func (Table) Count ¶
Count the models in the DB. Qualified by the model field values and list options. Expects natural keys to be set. Else, ALL models counted.
func (Table) Delete ¶
Delete the model in the DB. Expects the primary key (PK) or natural keys to be set.
func (Table) Get ¶
Get the model in the DB. Expects the primary key (PK) or natural keys to be set. Fetch the row and populate the fields in the model.
func (Table) List ¶
func (t Table) List(list interface{}, options ListOptions) error
List the model in the DB. Qualified by the list options.
func (Table) MutableFields ¶
Get the mutable `Fields` for the model.
type TmplData ¶
type TmplData struct { // Table name. Table string // Fields. Fields []*Field // Constraint DDL. Constraints []string // Natural key fields. Keys []*Field // Primary key. Pk *Field // List options. Options *ListOptions // Count Count bool }
Template data.
type Tx ¶
type Tx struct {
// contains filtered or unexported fields
}
Database transaction.
func (*Tx) Commit ¶
Commit a transaction. Staged changes are committed in the DB. This will end the transaction.
func (*Tx) List ¶ added in v0.1.1
func (r *Tx) List(list interface{}, options ListOptions) error
List models. The `list` must be: *[]Model.
type Watch ¶
type Watch struct { // Model to be watched. Model Model // Event handler. Handler EventHandler // contains filtered or unexported fields }
Model event watch.