gomodel

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2019 License: GPL-3.0 Imports: 10 Imported by: 0

README

GoModel GitHub release (latest by date) Build Status Test coverage status GoDoc

GoModel is an experimental project aiming to implement the features offered by the Python Django ORM using Go.

Please notice that the project is on early development and so the public API is likely to change.

  1. Quick start
  2. Definitions
  3. Schema migrations
  4. Making queries
  5. Testing
  6. Benchmarks

Quick start

package main

import (
    "fmt"
    _ "github.com/lib/pq"  // Imports database driver.
    "github.com/moiseshiraldo/gomodel"
    "github.com/moiseshiraldo/gomodel/migration"
    "time"
)

// This is how you define models.
var User = gomodel.New(
    "User",
    gomodel.Fields{
        "email":   gomodel.CharField{MaxLength: 100, Index: true},
        "active":  gomodel.BooleanField{DefaultFalse: true},
        "created": gomodel.DateTimeField{AutoNowAdd: true},
    },
    gomodel.Options{},
)

// Models are grouped inside applications.
var app = gomodel.NewApp("main", "/home/project/main/migrations", User.Model)

func setup() {
    // You have to register an application to be able to use its models.
    gomodel.Register(app)
    // And finally open at least a default database connection.
    gomodel.Start(map[string]gomodel.Database{
        "default": {
            Driver:   "postgres",
            Name:     "test",
            User:     "local",
            Password: "local",
        },
    })
}

func checkError(err error) {
    if err != nil {
        panic(err)
    }
}

func main() {
    // Let's create a user.
    user, err := User.Objects.Create(gomodel.Values{"email": "user@test.com"})
    // You'll probably get an error if the users table doesn't exist in the
    // database yet. Check out the migration package for more information!
    checkError(err)

    if _, ok := user.GetIf("forename"); !ok {
        fmt.Println("That field doesn't exist!")
    }
    // But we know this one does and can't be null.
    created := user.Get("created").(time.Time)
    fmt.Printf("This user was created on year %d", created.Year())

    // Do we have any active ones?
    exists, err := User.Objects.Filter(gomodel.Q{"active": true}).Exists()
    checkError(err)
    if !exists {
        // It doesn't seem so, but we can change that.
        user.Set("active", true)
        err := user.Save()
        checkError(err)
    }
    
    // What about now?
    count, err := User.Objects.Filter(gomodel.Q{"active": true}).Count()
    checkError(err)
    fmt.Println("We have %d active users!", count)
    
    // Let's create another one!
    data := struct {
        Email  string
        Active bool
    } {"admin@test.com", true}
    _, err := User.Objects.Create(data)
    checkError(err)
    
    // And print some details about them.
    users, err := User.Objects.All().Load()
    for _, user := range users {
        fmt.Println(
            user.Display("email"), "was created at", user.Display("created"),
        )
    }
    
    // I wonder what happens if we try to get a random one...
    user, err = User.Objects.Get(gomodel.Q{"id": 17})
    if _, ok := err.(*gomodel.ObjectNotFoundError); ok {
        fmt.Println("Keep trying!")
    }
    
    // Enough for today, let's deactivate all the users.
    n, err := User.Objects.Filter(gomodel.Q{"active": true}).Update(
        gomodel.Values{"active": false}
    )
    checkError(err)
    fmt.Printf("%d users have been deactivated\n", n)
    
    // Or even better, kill 'em a... I mean delete them all.
    _, err := User.Objects.All().Delete()
    checkError(err)
}

Definitions

Applications

An application represents a group of models that share something in common (a feature, a package...), making it easier to export and reuse them. You can create application settings using the NewApp function:

var app = gomodel.NewApp("main", "/home/project/main/migrations", models...)

The first argument is the name of the application, which must be unique. The second one is the migrations path (check the migration package for more details), followed by the list of models belonging to the application.

Application settings can be registered with the Register function, that will validate the app details and the models, panicking on any definition error. A map of registered applications can be obtained calling Registry.

Models

A model represents a source of data inside an application, usually mapping to a database table. Models can be created using the New function:

var User = gomodel.New(
    "User",
    gomodel.Fields{
        "email": gomodel.CharField{MaxLength: 100, Index: true},
        "active": gomodel.BooleanField{DefaultFalse: true},
        "created": gomodel.DateTimeField{AutoNowAdd: true},
    },
    gomodel.Options{},
)

The first argument is the name of the model, which must be unique inside the application. The second one is the map of fields and the last one the model Options. The function returns a Dispatcher giving access to the model and the default Objects manager.

Please notice that the model must be registered to an application before making any queries.

Databases

A Database represents a single organized collection of structured information.

GoModel offers database-abstraction API that lets you create, retrieve, update and delete objects. The underlying communication is done via the database/sql package, so the corresponding driver must be imported. The bridge between the API and the the sql package is constructed implementing the Engine interface.

At the moment, there are engines available for the postgres and the sqlite3 drivers, as well as a mocker one that can be used for unit testing.

Once the Start function has been called, the Databases function can be used to get a map with all the available databases.

Containers

A container is just a Go variable where the data for a specific model instance is stored. It can be a struct or any type implementing the Builder interface. By default, a model will use the Values map to store data. That can be changed passing another container to the model definition options:

type userCont struct {
    email   string
    active  bool
    created time.Time
}

var User = gomodel.New(
    "User",
    gomodel.Fields{
        "email": gomodel.CharField{MaxLength: 100, Index: true},
        "active": gomodel.BooleanField{DefaultFalse: true},
        "created": gomodel.DateTimeField{AutoNowAdd: true},
    },
    gomodel.Options{
        Container: userCont{},
    },
)

A different container can also be set for specific queries:

qs := User.Objects.Filter(gomodel.Q{"active": true}).WithContainer(userCont{})
users, err := qs.Load()

Fields

Click a field name to see the documentation with all the options.

Recipient is the type used to store values on the default map container. Null Recipient is the type used when the column can be Null. Value is the returned type when any instance get method is called (nil for Null) for any of the underlying recipients of the field.

Name Recipient Null Recipient Value
IntegerField int32 gomodel.NullInt32 int32
CharField string sql.NullString string
BooleanField bool sql.NullBool bool
DateField gomodel.NullTime gomodel.NullTime time.Time
TimeField gomodel.NullTime gomodel.NullTime time.Time
DateTimeField gomodel.NullTime gomodel.NullTime time.Time

Making queries

CRUD

Operation Single object Multiple objects
Create user, err := User.Objects.Create(values) Not supported yet
Read user, err := User.Objects.Get(conditions) users, err := User.Objects.Filter(conditions).Load()
Update err := user.Save() n, err := User.Objects.Filter(conditions).Update(values)
Delete err := user.Delete() n, err := User.Objects.Filter(conditions).Delete()

Managers

A model Manager provides access to the database abstraction API that lets you perform CRUD operations.

By default, a Dispatcher provides access to the model manager through the Objects field. But you can define a custom model dispatcher with additional managers:

type activeManager {
    gomodel.Manager
}

// GetQuerySet overrides the default Manager method to return only active users.
func (m activeManager) GetQuerySet() QuerySet {
	return m.Manager.GetQuerySet().Filter(gomodel.Q{"active": true})
}

// Create overrides the default Manager method to set a created user as active.
func (m activeManager) Create(vals gomodel.Container) (*gomodel.Instance, error) {
    user, err := m.Manager.Create(vals)
    if err := nil {
        return user, err
    }
    user.Set("active", true)
    err = user.Save("active")
    return user, error
}

type customUserDispatcher struct {
    gomodel.Dispatcher
    Active activeManager
}

var userDispatcher = gomodel.New(
    "User",
    gomodel.Fields{
        "email": gomodel.CharField{MaxLength: 100, Index: true},
        "active": gomodel.BooleanField{DefaultFalse: true},
        "created": gomodel.DateTimeField{AutoNowAdd: true},
    },
    gomodel.Options{},
)

var User = customUserDispatcher{
    Dispatcher: userDispatcher,
    Active: activeUsersManager{userDispatcher.Objects},
}

And they can be accessed like the default manager:

user, err := User.Active.Create(gomodel.Values{"email": "user@test.com"})
user, err := User.Active.Get("email": "user@test.com")

QuerySets

A QuerySet is an interface that represents a collection of objects on the database and the methods to interact with them.

The default manager returns a GenericQuerySet, but you can define custom querysets with additional methods:

type UserQS struct {
    gomodel.GenericQuerySet
}

func (qs UserQuerySet) Adults() QuerySet {
    return qs.Filter(gomodel.Q{"dob <=": time.Now().AddDate(-18, 0, 0)})
}

type customUserDispatcher struct {
    gomodel.Dispatcher
    Objects Manager
}

var userDispatcher = gomodel.New(
    "User",
    gomodel.Fields{
        "email": gomodel.CharField{MaxLength: 100, Index: true},
        "active": gomodel.BooleanField{DefaultFalse: true},
        "dob": gomodel.DateField{},
    },
    gomodel.Options{},
)

var User = customUserDispatcher{
    Dispatcher: userDispatcher,
    Objects: Manager{userDispatcher.Model, UserQS{}},
}

Notice that you will have to cast the queryset to access the custom method:

qs := User.Objects.Filter(gomodel.Q{"active": true}).(UserQS).Adults()
activeAdults, err := qs.Load()

Conditioners

Most of the manager and queryset methods receive a Conditioner as an argument, which is just an interface that represents SQL predicates and the methods to combine them.

The Q type is the default implementation of the interface. A Q is just a map of values where the key is the column and operator part of the condition, separated by a blank space. The equal operator can be omitted:

qs := User.Objects.Filter(gomodel.Q{"active": true})

At the moment, only the simple comparison operators (=, >, <, >=, <=) are supported. You can check if a column is Null using the equal operator and passing the nil value.

Complex predicates can be constructed programmatically using the And, AndNot, Or, and OrNot methods:

conditions := gomodel.Q{"active": true}.AndNot(
    gomodel.Q{"pk >=": 100}.Or(gomodel.Q{"email": "user@test.com"}),
)

Multiple databases

You can pass multiple databases to the Start function:

gomodel.Start(map[string]gomodel.Database{
    "default": {
        Driver:   "postgres",
        Name:     "master",
        User:     "local",
        Password: "local",
    },
    "slave": {
        Driver:   "postgres",
        Name:     "slave",
        User:     "local",
        Password: "local",
    }
})

For single instances, you can select the target database with the SaveOn and DeleteOn methods:

err := user.SaveOn("slave")

For querysets, you can use the WithDB method:

users, err := User.Objects.All().WithDB("slave").Load()

Transactions

You can start a transaction using the Database BeingTx method:

db := gomodel.Databases()["default"]
tx, err := db.BeginTx()

Which returns a Transaction that can be used as a target for instances and querysets:

err := user.SaveOn(tx)
users, err := User.Objects.All().WithTx(tx).Load()

And commited or rolled back using the Commit and Rollback methods.

Testing

The mocker driver can be used to open a mocked database for unit testing:

gomodel.Start(map[string]gomodel.Database{
    "default": {
        Driver:   "mocker",
        Name:     "test",
    },
})

The underlying MockedEngine provides some useful tools for test assertions:

func TestCreate(t *testing.T) {
    db := gomodel.Databases()["default"]
    mockedEngine := db.Engine.(gomodel.MockedEngine)
    _, err := User.Objects.Create(gomodel.Values{"email": "user@test.com"})
    if err != nil {
        t.Fatal(err)
    }
    // Calls returns the number of calls to the given method name.
    if mockedEngine.Calls("InsertRow") != 1 {
        t.Error("expected engine InsertRow method to be called")
    }
    // The Args field contains the arguments for the last call to each method.
    insertValues := mockedEngine.Args.InsertRow.Values
    if _, ok := mockedEngine.Args.InsertRow.Values["email"]; !ok {
        t.Error("email field missing on insert arguments")
    }
}

You can also change the return values of the engine methods:

func TestCreateError(t *testing.T) {
    // Reset clears all the method calls, arguments and results.
    mockedEngine.Reset()
    // The Results fields can be used to set custom return values for each method.
    mockedEngine.Results.InsertRow.Err = fmt.Errorf("db error")
    _, err := User.Objects.Create(Values{"email": "user@test.com"})
    if _, ok := err.(*gomodel.DatabaseError); !ok {
        t.Errorf("expected gomodel.DatabaseError, got %T", err)
    }
})

Documentation

Overview

Package gomodel is an ORM that provides the resources to define data models and a database-abstraction API that lets you create, retrieve, update and delete objects.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClearRegistry

func ClearRegistry()

ClearRegistry removes all the registered applications.

func Databases

func Databases() map[string]Database

Databases returns a map with all the registered databases.

func Register

func Register(apps ...AppSettings)

Register validates the given application settings and their models and adds them to the registry. The function will panic on any validation error.

func Registry

func Registry() map[string]*Application

Registry returns a map containing all the registered applications.

func Start

func Start(options map[string]Database) error

Start opens a db connection for each database in the given map and stores them in the db registry. It will panic if any of the selected drivers is not supported or the connection fails to open.

func Stop

func Stop() error

Stop close all the db connections and removes them from the db registry.

Types

type AppSettings

type AppSettings struct {
	// Name is the application name, which must be unique.
	Name string
	// Path must be an existing directory path or blank if migrations won't be
	// managed by the gomodel/migration package. If relative, the full path will
	// be constructed from $GOPATH/src.
	Path string
	// Models is the list of models that will be registered to the application.
	Models []*Model
}

AppSettings holds the options te register a new application.

func NewApp

func NewApp(name string, path string, models ...*Model) AppSettings

NewApp returns an application settings struct constructed from the given arguments, ready to registered using the Register function.

The name is the applicatoin name, which must be unique.

The path must be an existing directory path or blank if migrations won't be managed by the gomodel/migration package. If relative, the full path will be constructed from $GOPATH/src.

The last argument is the list of models that will be registered to the app.

type Application

type Application struct {
	// contains filtered or unexported fields
}

Application holds a registered application and the validated models ready to interact with the database.

func (Application) FullPath

func (app Application) FullPath() string

FullPath returns the full path to the migrations directory.

func (Application) Models

func (app Application) Models() map[string]*Model

Models returns a map of models registered to the application.

func (Application) Name

func (app Application) Name() string

Name returns the application name.

func (Application) Path

func (app Application) Path() string

Path returns the migrations path for the application.

type BooleanField

type BooleanField struct {
	// Null is true if the field can have null values.
	Null bool `json:",omitempty"`
	// Blank is true if the field is not required. Only used for validation.
	Blank bool `json:",omitempty"`
	// Index is true if the field column should be indexed.
	Index bool `json:",omitempty"`
	// Column is the name of the db column. If blank, it will be the field name.
	Column string `json:",omitempty"`
	// Default is the default value for the field. Blank for no default.
	Default bool `json:",omitempty"`
	// DefaultFalse is true if false is the field default value.
	DefaultFalse bool `json:",omitempty"`
}

BooleanField implements the Field interface for true/false fields.

func (BooleanField) DBColumn

func (f BooleanField) DBColumn(name string) string

DBColumn implements the DBColumn method of the Field interface.

func (BooleanField) DataType

func (f BooleanField) DataType(dvr string) string

DataType implements the DataType method of the Field interface.

func (BooleanField) DefaultValue

func (f BooleanField) DefaultValue() (Value, bool)

DefaultValue implements the DefaultValue method of the Field interface.

func (BooleanField) DisplayValue

func (f BooleanField) DisplayValue(val Value) string

DisplayValue implements the DisplayValue method of the Field interface.

func (BooleanField) DriverValue

func (f BooleanField) DriverValue(v Value, dvr string) (interface{}, error)

DriverValue implements the DriverValue method of the Field interface.

func (BooleanField) HasIndex

func (f BooleanField) HasIndex() bool

HasIndex implements the HasIndex method of the Field interface.

func (BooleanField) IsAuto

func (f BooleanField) IsAuto() bool

IsAuto implements the IsAuto method of the Field interface.

func (BooleanField) IsAutoNow

func (f BooleanField) IsAutoNow() bool

IsAutoNow implements the IsAutoNow method of the Field interface.

func (BooleanField) IsAutoNowAdd

func (f BooleanField) IsAutoNowAdd() bool

IsAutoNowAdd implements the IsAutoNowAdd method of the Field interface.

func (BooleanField) IsNull

func (f BooleanField) IsNull() bool

IsNull implements the IsNull method of the Field interface.

func (BooleanField) IsPK

func (f BooleanField) IsPK() bool

IsPK implements the IsPK method of the Field interface.

func (BooleanField) IsUnique

func (f BooleanField) IsUnique() bool

IsUnique implements the IsUnique method of the Field interface.

func (BooleanField) Recipient

func (f BooleanField) Recipient() interface{}

Recipient implements the Recipient method of the Field interface.

func (BooleanField) Value

func (f BooleanField) Value(rec interface{}) Value

Value implements the Value method of the Field interface.

type Builder

type Builder interface {
	Getter
	Setter
	New() Builder
}

The Builder interface represents a model container that implements the Getter interface, the Setter interface and the New method to return a new empty container.

type CharField

type CharField struct {
	// PrimaryKey is true if the field is the model primary key.
	PrimaryKey bool `json:",omitempty"`
	// Unique is true if the field value must be unique.
	Unique bool `json:",omitempty"`
	// Null is true if the field can have null values.
	Null bool `json:",omitempty"`
	// Blank is true if the field is not required. Only used for validation.
	Blank bool `json:",omitempty"`
	// MaxLength is the max length accepted for field values.
	MaxLength int `json:",omitempty"`
	// Index is true if the field column should be indexed.
	Index bool `json:",omitempty"`
	// Column is the name of the db column. If blank, it will be the field name.
	Column string `json:",omitempty"`
	// Choices is a list of possible choices for the field.
	Choices []Choice `json:",omitempty"`
	// Default is the default value for the field. Blank for no default.
	Default string `json:",omitempty"`
	// DefaultEmpty is true if the empty string is the field default value.
	DefaultEmpty bool `json:",omitempty"`
}

CharField implements the Field interface for small to medium-sized strings.

func (CharField) DBColumn

func (f CharField) DBColumn(name string) string

DBColumn implements the DBColumn method of the Field interface.

func (CharField) DataType

func (f CharField) DataType(driver string) string

DataType implements the DataType method of the Field interface.

func (CharField) DefaultValue

func (f CharField) DefaultValue() (Value, bool)

DefaultValue implements the DefaultValue method of the Field interface.

func (CharField) DisplayValue

func (f CharField) DisplayValue(val Value) string

DisplayValue implements the DisplayValue method of the Field interface.

func (CharField) DriverValue

func (f CharField) DriverValue(val Value, dvr string) (interface{}, error)

DriverValue implements the DriverValue method of the Field interface.

func (CharField) HasIndex

func (f CharField) HasIndex() bool

HasIndex implements the HasIndex method of the Field interface.

func (CharField) IsAuto

func (f CharField) IsAuto() bool

IsAuto implements the IsAuto method of the Field interface.

func (CharField) IsAutoNow

func (f CharField) IsAutoNow() bool

IsAutoNow implements the IsAutoNow method of the Field interface.

func (CharField) IsAutoNowAdd

func (f CharField) IsAutoNowAdd() bool

IsAutoNowAdd implements the IsAutoNowAdd method of the Field interface.

func (CharField) IsNull

func (f CharField) IsNull() bool

IsNull implements the IsNull method of the Field interface.

func (CharField) IsPK

func (f CharField) IsPK() bool

IsPK implements the IsPK method of the Field interface.

func (CharField) IsUnique

func (f CharField) IsUnique() bool

IsUnique implements the IsUnique method of the Field interface.

func (CharField) Recipient

func (f CharField) Recipient() interface{}

Recipient implements the Recipient method of the Field interface.

func (CharField) Value

func (f CharField) Value(rec interface{}) Value

Value implements the Value method of the Field interface.

type Choice

type Choice struct {
	Value Value  // Value is the choice value.
	Label string // Label is the choice label.
}

Choice holds a choice option for a Field.

type Conditioner

type Conditioner interface {
	// Root returns the first part of a composite predicate, that can be another
	// composite one if isChain is true or a simple one otherwise.
	//
	// For example, let's take the Conditioner representing this predicate:
	//  (username = 'alice' OR username = 'bob') AND isAdmin = FALSE
	//
	// The method should return isChain as true and a Conditioner representing:
	//  username = 'alice' OR username = 'bob'
	//
	// Whose Root method should return isChain as false and the Conditioner:
	//  username = 'alice'
	Root() (conditioner Conditioner, isChain bool)
	// Conditions returns a map of values representing a predicate consisting
	// of simple conditions joined by the AND operator, where the key is the
	// column and operator part of the condition.
	//
	// The = operator can be omitted. For example:
	//
	//   active = True AND id >= 10
	//
	// Would return: map[string]Value{"active": true, "id >=": 10}
	Conditions() map[string]Value
	// Next returns the next conditioner and the operator joining them:
	//  AND: isOr is false, isNot is false
	//  AND NOT: isOr is false, isNot is true
	//  OR: isOr is true, isNot is false
	//  OR NOT: isOr is true, isNot is true
	Next() (conditioner Conditioner, isOr bool, isNot bool)
	// And joins the given conditioner and the current one by the AND operator.
	And(conditioner Conditioner) Conditioner
	// AndNot joins the given conditioner and the current one by the AND NOT
	// operator.
	AndNot(conditioner Conditioner) Conditioner
	// Or joins the given conditioner and the current one by the OR operator.
	Or(conditioner Conditioner) Conditioner
	// OrNot joins the given conditioner and the current one by the OR NOT
	// operator.
	OrNot(conditioner Conditioner) Conditioner
}

The Conditioner interface defines the methods necessary to construct SQL predicates from the data types implementing the interface, and combine them to create composite predicates.

type Container

type Container interface{}

The Container interface represents a type that holds the field values for a model object. It should be either a type implementing the Builder interface or a struct with the necessary exported fields.

type ContainerError

type ContainerError struct {
	Trace ErrorTrace
}

ContainerError is raised when a model container related error occurs.

func (*ContainerError) Error

func (e *ContainerError) Error() string

Error implements the error interface.

type Database

type Database struct {
	// Engine is the interface providing the database-abstraction API.
	//
	// It's automatically set from the selected Driver.
	Engine
	// Driver is the name of the database/sql driver that will be used to
	// interact with the database.
	Driver string
	// Name is the name of the database used to open a connection.
	Name string
	// User is the user, if required, to open a db connection.
	User string
	// Password is the password, if required, to open a db connection.
	Password string
	// contains filtered or unexported fields
}

A Database holds the details required for the ORM to interact with the db.

func (Database) BeginTx

func (db Database) BeginTx() (*Transaction, error)

BeginTx starts and returns a new database Transaction.

func (Database) Id

func (db Database) Id() string

Id returns the database identifier in the gomodel registry.

type DatabaseError

type DatabaseError struct {
	Name  string // Name is the database key in the gomodel registry.
	Trace ErrorTrace
}

DatabaseError is raised when a database related error occurs.

func (*DatabaseError) Error

func (e *DatabaseError) Error() string

Error implements the error interface.

type DateField

type DateField struct {
	// PrimaryKey is true if the field is the model primary key.
	PrimaryKey bool `json:",omitempty"`
	// Unique is true if the field value must be unique.
	Unique bool `json:",omitempty"`
	// Null is true if the field can have null values.
	Null bool `json:",omitempty"`
	// AutoNow is true if the value is auto generated on row updates.
	AutoNow bool `json:",omitempty"`
	// AutoNowAdd is true if the value is auto generated on row inserts.
	AutoNowAdd bool `json:",omitempty"`
	// Blank is true if the field is not required. Only used for validation.
	Blank bool `json:",omitempty"`
	// Index is true if the field column should be indexed.
	Index bool `json:",omitempty"`
	// Column is the name of the db column. If blank, it will be the field name.
	Column string `json:",omitempty"`
	// Choices is a list of possible choices for the field.
	Choices []Choice `json:",omitempty"`
	// Default is the default value for the field. Blank for no default
	Default time.Time `json:",omitempty"`
}

DateField implements the Field interface for dates.

func (DateField) DBColumn

func (f DateField) DBColumn(name string) string

DBColumn implements the DBColumn method of the Field interface.

func (DateField) DataType

func (f DateField) DataType(dvr string) string

DataType implements the DataType method of the Field interface.

func (DateField) DefaultValue

func (f DateField) DefaultValue() (Value, bool)

DefaultValue implements the DefaultValue method of the Field interface.

func (DateField) DisplayValue

func (f DateField) DisplayValue(val Value) string

DisplayValue implements the DisplayValue method of the Field interface.

func (DateField) DriverValue

func (f DateField) DriverValue(v Value, dvr string) (interface{}, error)

DriverValue implements the DriverValue method of the Field interface.

func (DateField) HasIndex

func (f DateField) HasIndex() bool

HasIndex implements the HasIndex method of the Field interface.

func (DateField) IsAuto

func (f DateField) IsAuto() bool

IsAuto implements the IsAuto method of the Field interface.

func (DateField) IsAutoNow

func (f DateField) IsAutoNow() bool

IsAutoNow implements the IsAutoNow method of the Field interface.

func (DateField) IsAutoNowAdd

func (f DateField) IsAutoNowAdd() bool

IsAutoNowAdd implements the IsAutoNowAdd method of the Field interface.

func (DateField) IsNull

func (f DateField) IsNull() bool

IsNull implements the IsNull method of the Field interface.

func (DateField) IsPK

func (f DateField) IsPK() bool

IsPK implements the IsPK method of the Field interface.

func (DateField) IsUnique

func (f DateField) IsUnique() bool

IsUnique implements the IsUnique method of the Field interface.

func (DateField) MarshalJSON

func (f DateField) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (DateField) Recipient

func (f DateField) Recipient() interface{}

Recipient implements the Recipient method of the Field interface.

func (*DateField) UnmarshalJSON

func (f *DateField) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (DateField) Value

func (f DateField) Value(rec interface{}) Value

Value implements the Value method of the Field interface.

type DateTimeField

type DateTimeField struct {
	// PrimaryKey is true if the field is the model primary key.
	PrimaryKey bool `json:",omitempty"`
	// Unique is true if the field value must be unique.
	Unique bool `json:",omitempty"`
	// Null is true if the field can have null values.
	Null bool `json:",omitempty"`
	// AutoNow is true if the value is auto generated on row updates.
	AutoNow bool `json:",omitempty"`
	// AutoNowAdd is true if the value is auto generated on row inserts.
	AutoNowAdd bool `json:",omitempty"`
	// Blank is true if the field is not required. Only used for validation.
	Blank bool `json:",omitempty"`
	// Index is true if the field column should be indexed.
	Index bool `json:",omitempty"`
	// Column is the name of the db column. If blank, it will be the field name.
	Column string `json:",omitempty"`
	// Choices is a list of possible choices for the field.
	Choices []Choice `json:",omitempty"`
	// Default is the default value for the field. Blank for no default
	Default time.Time `json:",omitempty"`
}

DateTimeField implements the Field interface for datetime values.

func (DateTimeField) DBColumn

func (f DateTimeField) DBColumn(name string) string

DBColumn implements the DBColumn method of the Field interface.

func (DateTimeField) DataType

func (f DateTimeField) DataType(dvr string) string

DataType implements the DataType method of the Field interface.

func (DateTimeField) DefaultValue

func (f DateTimeField) DefaultValue() (Value, bool)

DefaultValue implements the DefaultValue method of the Field interface.

func (DateTimeField) DisplayValue

func (f DateTimeField) DisplayValue(val Value) string

DisplayValue implements the DisplayValue method of the Field interface.

func (DateTimeField) DriverValue

func (f DateTimeField) DriverValue(v Value, dvr string) (interface{}, error)

DriverValue implements the DriverValue method of the Field interface.

func (DateTimeField) HasIndex

func (f DateTimeField) HasIndex() bool

HasIndex implements the HasIndex method of the Field interface.

func (DateTimeField) IsAuto

func (f DateTimeField) IsAuto() bool

IsAuto implements the IsAuto method of the Field interface.

func (DateTimeField) IsAutoNow

func (f DateTimeField) IsAutoNow() bool

IsAutoNow implements the IsAutoNow method of the Field interface.

func (DateTimeField) IsAutoNowAdd

func (f DateTimeField) IsAutoNowAdd() bool

IsAutoNowAdd implements the IsAutoNowAdd method of the Field interface.

func (DateTimeField) IsNull

func (f DateTimeField) IsNull() bool

IsNull implements the IsNull method of the Field interface.

func (DateTimeField) IsPK

func (f DateTimeField) IsPK() bool

IsPK implements the IsPK method of the Field interface.

func (DateTimeField) IsUnique

func (f DateTimeField) IsUnique() bool

IsUnique implements the IsUnique method of the Field interface.

func (DateTimeField) MarshalJSON

func (f DateTimeField) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (DateTimeField) Recipient

func (f DateTimeField) Recipient() interface{}

Recipient implements the Recipient method of the Field interface.

func (DateTimeField) Value

func (f DateTimeField) Value(rec interface{}) Value

Value implements the Value method of the Field interface.

type Dispatcher

type Dispatcher struct {
	*Model
	Objects Manager
}

A Dispatcher embedds a Model definition and holds the default Objects Manager that gives access to the methods to interact with the database.

func New

func New(name string, fields Fields, options Options) *Dispatcher

New creates a new model definition with the given arguments. It returns a Dispatcher embedding the model and holding the default Objects Manager.

The model won't be ready to interact with the database until it's been registered to an application using either the Register function or the homonymous model method.

func (Dispatcher) New

func (d Dispatcher) New(values Container) (*Instance, error)

New returns an Instance of the embedded model, populating the fields with the values argument. If no value is provided for a field, it will try to get a default value from the model definition.

type Engine

type Engine interface {
	// Start opens a connection using the given Database details and returns
	// a new Engine holding the connection.
	Start(Database) (Engine, error)
	// Stop closes the db connection held by the engine.
	Stop() error
	// TxSupport indicates whether the engine supports transactions or not.
	TxSupport() bool
	// DB returns the underlying *sql.DB or nil if not applicable.
	DB() *sql.DB
	// BeginTx starts a new transaction and returns a new Engine holding it.
	BeginTx() (Engine, error)
	// Tx returns the underlying *sql.Tx or nil if not applicable.
	Tx() *sql.Tx
	// CommitTx commits the transaction held by the engine.
	CommitTx() error
	// RollbackTx rolls back the transaction held by the engine.
	RollbackTx() error
	// CreateTable creates the table for the given model. If force is true, the
	// method should return an error if the table already exists.
	CreateTable(model *Model, force bool) error
	// RenameTable renames the table from the given old model to the new one.
	RenameTable(old *Model, new *Model) error
	// DropTable drops the table for the given model.
	DropTable(model *Model) error
	// AddIndex creates a new index for the given model and fields.
	AddIndex(model *Model, name string, fields ...string) error
	// DropIndex drops the named index for the given model.
	DropIndex(model *Model, name string) error
	// AddColumns creates the columns for the given fields on the model table.
	AddColumns(model *Model, fields Fields) error
	// DropColumns drops the columns given by fields from the model table.
	DropColumns(model *Model, fields ...string) error
	// SelectQuery returns the SELECT SQL query details for the given model and
	// query options.
	SelectQuery(model *Model, options QueryOptions) (Query, error)
	// GetRows returns the Rows resulting from querying the database with
	// the query options, where options.Start is the first row index (starting
	// at 0) and options.End the last row index (-1 for all rows).
	GetRows(model *Model, options QueryOptions) (Rows, error)
	// InsertRow inserts the given values in the model table.
	InsertRow(model *Model, values Values) (int64, error)
	// UpdateRows updates the model rows selected by the given conditioner with
	// the given values.
	UpdateRows(model *Model, values Values, options QueryOptions) (int64, error)
	// DeleteRows deletes the model rows selected by the given conditioner.
	DeleteRows(model *Model, options QueryOptions) (int64, error)
	// CountRows counts the model rows selected by the given conditioner.
	CountRows(model *Model, options QueryOptions) (int64, error)
	// Exists returns whether any model row exists for the given conditioner.
	Exists(model *Model, options QueryOptions) (bool, error)
}

Engine is the interface providing the database-abstraction API methods.

type ErrorTrace

type ErrorTrace struct {
	App   *Application
	Model *Model
	Field string
	Err   error
}

ErrorTrace holds the context information of a gomodel error.

func (ErrorTrace) String

func (e ErrorTrace) String() string

String implements the fmt.Stringer interface.

type Field

type Field interface {
	// IsPK returns true if the field is the model primary key.
	IsPK() bool
	// IsUnique returns true if the model field value must be unique.
	IsUnique() bool
	// IsNull returns true if the model field value can be null.
	IsNull() bool
	// IsAuto returns true if the field is an auto incremented one.
	IsAuto() bool
	// If IsAutoNow returns true, the field value will be time.Now() every
	// time a new row is inserted.
	IsAutoNow() bool
	// If IsAutoNowAdd returns true, the field value will be time.now() every
	// time a row is updated.
	IsAutoNowAdd() bool
	// If HasIndex returns true, the field column will be indexed.
	HasIndex() bool
	// DBColumn receives the model field name and returns the database column
	// name.
	DBColumn(fieldName string) string
	// DataType returns the field column type for the given driver.
	DataType(driver string) string
	// DefaultValue returns a default value for the field when hasDefault is
	// true.
	DefaultValue() (val Value, hasDefault bool)
	// Recipient returns a pointer to the variable that will hold a field value
	// coming from the database.
	Recipient() interface{}
	// Value receives the recipient holding the field value for a particular
	// instance, and returns the Value that will be presented when the Instance
	// Get method is called.
	Value(recipient interface{}) Value
	// DriverValue receives a field value and returns the value that should
	// be used on database queries for the given driver.
	DriverValue(val Value, driver string) (interface{}, error)
	// DisplayValue returns the string representation of the given value.
	DisplayValue(val Value) string
}

Field is the interface that represents a model field.

type Fields

type Fields map[string]Field

Fields represents the fields map of a model.

func (Fields) MarshalJSON

func (fields Fields) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*Fields) UnmarshalJSON

func (fields *Fields) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface. An error is returned if the field type is not registered.

type GenericQuerySet

type GenericQuerySet struct {
	// contains filtered or unexported fields
}

GenericQuerySet implements the QuerySet interface.

func (GenericQuerySet) Count

func (qs GenericQuerySet) Count() (int64, error)

Count implements the Count method of the QuerySet interface.

func (GenericQuerySet) Delete

func (qs GenericQuerySet) Delete() (int64, error)

Delete implements the Delete method of the QuerySet interface.

func (GenericQuerySet) Exclude

func (qs GenericQuerySet) Exclude(c Conditioner) QuerySet

Exclude implements the Exclude method of the QuerySet interface.

func (GenericQuerySet) Exists

func (qs GenericQuerySet) Exists() (bool, error)

Exists implements the Exists method of the QuerySet interface.

func (GenericQuerySet) Filter

func (qs GenericQuerySet) Filter(c Conditioner) QuerySet

Filter implements the Filter method of the QuerySet interface.

func (GenericQuerySet) Get

func (qs GenericQuerySet) Get(c Conditioner) (*Instance, error)

Get implements the Get method of the QuerySet interface.

func (GenericQuerySet) Load

func (qs GenericQuerySet) Load() ([]*Instance, error)

Load implements the Load method of the QuerySet interface.

func (GenericQuerySet) Model

func (qs GenericQuerySet) Model() *Model

Model implements the Model method of the QuerySet interface.

func (GenericQuerySet) New

func (qs GenericQuerySet) New(m *Model, parent QuerySet) QuerySet

New implements the New method of the QuerySet interface.

func (GenericQuerySet) Only

func (qs GenericQuerySet) Only(fields ...string) QuerySet

Only implements the Only method of the QuerySet interface.

func (GenericQuerySet) Query

func (qs GenericQuerySet) Query() (Query, error)

Query implements the Query method of the QuerySet interface.

func (GenericQuerySet) Slice

func (qs GenericQuerySet) Slice(start int64, end int64) ([]*Instance, error)

Slice implemetns the Slice method of the QuerySet interface.

func (GenericQuerySet) Update

func (qs GenericQuerySet) Update(container Container) (int64, error)

Update implements the Update method of the QuerySet interface.

func (GenericQuerySet) WithContainer

func (qs GenericQuerySet) WithContainer(container Container) QuerySet

WithContainer implements the WithContainer method of the QuerySet interface.

func (GenericQuerySet) WithDB

func (qs GenericQuerySet) WithDB(database string) QuerySet

WithDB implements the WithDB method of the QuerySet interface.

func (GenericQuerySet) WithTx

func (qs GenericQuerySet) WithTx(tx *Transaction) QuerySet

WithTx implements the WithTx method of the QuerySet interface.

func (GenericQuerySet) Wrap

func (qs GenericQuerySet) Wrap(parent GenericQuerySet) QuerySet

Wrap implements the Wrap method of the QuerySet interface.

type Getter

type Getter interface {
	Get(name string) (val Value, ok bool)
}

Getter is the interface that wraps the basic Get method for model containers.

Get returns the value of the given field, and a boolean indicating whether the the field was found or not.

type Indexes

type Indexes map[string][]string

The Indexes type describes the indexes of a model, where the key is the index name and the value the list of indexes fields.

type Instance

type Instance struct {
	// contains filtered or unexported fields
}

An Instance represents a particular model object and offers some methods to interact with its field values and the database.

func (Instance) Container

func (i Instance) Container() Container

Container returns the container holding the values of this model object.

func (Instance) Delete

func (i Instance) Delete() error

Delete removes the object from the table on the default database.

func (Instance) DeleteOn

func (i Instance) DeleteOn(target interface{}) error

Delete removes the object from the table on the given target, that can be a *Transaction or a string representing a database identifier.

func (Instance) Display

func (i Instance) Display(name string) string

Display returns the string representation of the value for the given field name, blank if not found.

func (Instance) Get

func (i Instance) Get(name string) Value

Get returns the value for the given field name, or nil if not found.

func (Instance) GetIf

func (i Instance) GetIf(name string) (val Value, hasField bool)

GetIf returns the value for the given field name, and a hasField boolean indicating if the field was actually found in the underlying container.

func (Instance) Model

func (i Instance) Model() *Model

Model returns the model represented by this object.

func (Instance) Save

func (i Instance) Save(fields ...string) error

Save propagates the instance field values to the database. If no field names are provided, all fields will be saved.

The method will try to update the row matching the instance pk. If no row is updated, a new one will be inserted.

If the pk field is auto incremented and the pk has the zero value, a new row will be inserted.

func (Instance) SaveOn

func (i Instance) SaveOn(target interface{}, fields ...string) error

SaveOn works as Save, but the changes are propagated to the given target, that can be a *Transaction or a string representing a database identifier.

func (Instance) Set

func (i Instance) Set(name string, val Value) error

Set updates the named instance field with the given value. The change doesn't propagate to the database unless the Save method is called.

func (Instance) SetValues

func (i Instance) SetValues(values Container) error

SetValues updates the instance with the given values. The changes don't propagate to the database unless the Save method is called.

type IntegerField

type IntegerField struct {
	// PrimaryKey is true if the field is the model primary key.
	PrimaryKey bool `json:",omitempty"`
	// Unique is true if the field value must be unique.
	Unique bool `json:",omitempty"`
	// Null is true if the field can have null values.
	Null bool `json:",omitempty"`
	// Auto is true if the field value will be auto incremented.
	Auto bool `json:",omitempty"`
	// Blank is true if the field is not required. Only used for validation.
	Blank bool `json:",omitempty"`
	// Index is true if the field column should be indexed.
	Index bool `json:",omitempty"`
	// Column is the name of the db column. If blank, it will be the field name.
	Column string `json:",omitempty"`
	// Choices is a list of possible choices for the field.
	Choices []Choice `json:",omitempty"`
	// Default is the default value for the field. Blank for no default.
	Default int32 `json:",omitempty"`
	// DefaultZero is true if zero is the field default value.
	DefaultZero bool `json:",omitempty"`
}

IntegerField implements the Field interface for small to medium-sized strings.

func (IntegerField) DBColumn

func (f IntegerField) DBColumn(name string) string

DBColumn implements the DBColumn method of the Field interface.

func (IntegerField) DataType

func (f IntegerField) DataType(dvr string) string

DataType implements the DataType method of the Field interface.

func (IntegerField) DefaultValue

func (f IntegerField) DefaultValue() (Value, bool)

DefaultValue implements the DefaultValue method of the Field interface.

func (IntegerField) DisplayValue

func (f IntegerField) DisplayValue(val Value) string

DisplayValue implements the DisplayValue method of the Field interface.

func (IntegerField) DriverValue

func (f IntegerField) DriverValue(v Value, dvr string) (interface{}, error)

DriverValue implements the DriverValue method of the Field interface.

func (IntegerField) HasIndex

func (f IntegerField) HasIndex() bool

HasIndex implements the HasIndex method of the Field interface.

func (IntegerField) IsAuto

func (f IntegerField) IsAuto() bool

IsAuto implements the IsAuto method of the Field interface.

func (IntegerField) IsAutoNow

func (f IntegerField) IsAutoNow() bool

IsAutoNow implements the IsAutoNow method of the Field interface.

func (IntegerField) IsAutoNowAdd

func (f IntegerField) IsAutoNowAdd() bool

IsAutoNowAdd implements the IsAutoNowAdd method of the Field interface.

func (IntegerField) IsNull

func (f IntegerField) IsNull() bool

IsNull implements the IsNull method of the Field interface.

func (IntegerField) IsPK

func (f IntegerField) IsPK() bool

IsPK implements the IsPK method of the Field interface.

func (IntegerField) IsUnique

func (f IntegerField) IsUnique() bool

IsUnique implements the IsUnique method of the Field interface.

func (IntegerField) Recipient

func (f IntegerField) Recipient() interface{}

Recipient implements the Recipient method of the Field interface.

func (IntegerField) Value

func (f IntegerField) Value(rec interface{}) Value

Value implements the Value method of the Field interface.

type Manager

type Manager struct {
	// Model is the model making the queries.
	Model *Model
	// QuerySet is the base queryset for the manager.
	QuerySet QuerySet
}

A Manager is the interface through which database query operations are provided to models.

func (Manager) All

func (m Manager) All() QuerySet

All returns a QuerySet representing all objects.

func (Manager) Create

func (m Manager) Create(values Container) (*Instance, error)

Create makes a new object with the given values, saves it to the default database and returns the instance representing the object.

func (Manager) CreateOn

func (m Manager) CreateOn(
	target interface{},
	values Container,
) (*Instance, error)

CreateOn works as Create, but saves the object on the given target, that can be a *Transaction or a string representing a database identifier.

func (Manager) Exclude

func (m Manager) Exclude(c Conditioner) QuerySet

Exclude returns a QuerySet exluding objects by the given conditioner.

func (Manager) Filter

func (m Manager) Filter(c Conditioner) QuerySet

Filter returns a QuerySet filtered by the given conditioner.

func (Manager) Get

func (m Manager) Get(c Conditioner) (*Instance, error)

Get returns an instance representing the single object matching the given conditioner.

If no object is found, *ObjectNotFoundError is returned.

If multiple objects match the conditions, *MultipleObjectsError is returned.

func (Manager) GetQuerySet

func (m Manager) GetQuerySet() QuerySet

GetQuerySet calls the New method of the base QuerySet and returns the result.

func (Manager) WithContainer

func (m Manager) WithContainer(container Container) QuerySet

WithContainer returns a QuerySet with the given Container type as a base.

type MockedEngine

type MockedEngine struct {
	Args    *MockedEngineArgs
	Results *MockedEngineResults
	// contains filtered or unexported fields
}

MockedEngine mocks the Engine interface and can be used to write unit tests without having to open a database connection.

func (MockedEngine) AddColumns

func (e MockedEngine) AddColumns(model *Model, fields Fields) error

AddColumns mocks the AddColumns method of the Engine interface.

func (MockedEngine) AddIndex

func (e MockedEngine) AddIndex(m *Model, name string, fields ...string) error

AddIndex mocks the AddIndex method of the Engine interface.

func (MockedEngine) BeginTx

func (e MockedEngine) BeginTx() (Engine, error)

BeginTx mocks the BeginTx method of the Engine interface. It returns the same MockedEngine.

func (MockedEngine) Calls

func (e MockedEngine) Calls(method string) int

Calls returns the number of calls made to method.

func (MockedEngine) CommitTx

func (e MockedEngine) CommitTx() error

CommitTx mocks the CommitTx method of the Engine interface.

func (MockedEngine) CountRows

func (e MockedEngine) CountRows(m *Model, opt QueryOptions) (int64, error)

CountRows mocks the CountRows method of the Engine interface.

func (MockedEngine) CreateTable

func (e MockedEngine) CreateTable(model *Model, force bool) error

CreateTable mocks the CreateTable method of the Engine interface.

func (MockedEngine) DB

func (e MockedEngine) DB() *sql.DB

DB mocks the DB method of the Engine interface. It always returns nil.

func (MockedEngine) DeleteRows

func (e MockedEngine) DeleteRows(m *Model, opt QueryOptions) (int64, error)

DeleteRows mocks the DeleteRows method of the Engine interface.

func (MockedEngine) DropColumns

func (e MockedEngine) DropColumns(model *Model, fields ...string) error

DropColumns mocks the DropColumns method of the Engine interface.

func (MockedEngine) DropIndex

func (e MockedEngine) DropIndex(model *Model, name string) error

DropIndex mocks the DropIndex method of the Engine interface.

func (MockedEngine) DropTable

func (e MockedEngine) DropTable(model *Model) error

DropTable mocks the DropTable method of the Engine interface.

func (MockedEngine) Exists

func (e MockedEngine) Exists(m *Model, opt QueryOptions) (bool, error)

Exists mocks the Exists method of the Engine interface.

func (MockedEngine) GetRows

func (e MockedEngine) GetRows(model *Model, opt QueryOptions) (Rows, error)

GetRows mocks the GetRows method of the Engine interface.

func (MockedEngine) InsertRow

func (e MockedEngine) InsertRow(model *Model, values Values) (int64, error)

InsertRow mocks the InsertRow method of the Engine interface.

func (MockedEngine) RenameTable

func (e MockedEngine) RenameTable(old *Model, new *Model) error

RenameTable mocks the RenameTable method of the Engine interface.

func (MockedEngine) Reset

func (e MockedEngine) Reset()

Reset sets all calls, results and arguments back to zero values.

func (MockedEngine) RollbackTx

func (e MockedEngine) RollbackTx() error

RollbackTx mocks the RollbackTx method of the Engine interface.

func (MockedEngine) SelectQuery

func (e MockedEngine) SelectQuery(m *Model, opt QueryOptions) (Query, error)

SelectQuery mocks the SelectQuery method of the Engine interface.

func (MockedEngine) Start

func (e MockedEngine) Start(db Database) (Engine, error)

Start implements the Start method of the Engine interface.

func (MockedEngine) Stop

func (e MockedEngine) Stop() error

Stop mocks the Stop method of the Engine interface.

func (MockedEngine) Tx

func (e MockedEngine) Tx() *sql.Tx

Tx mocks the Tx method of the Engine interface. It always returns nil.

func (MockedEngine) TxSupport

func (e MockedEngine) TxSupport() bool

TxSupport mocks the TxSupport of the Engine interface.

func (MockedEngine) UpdateRows

func (e MockedEngine) UpdateRows(
	model *Model,
	values Values,
	options QueryOptions,
) (int64, error)

UpdateRows mocks the UpdateRows method of the Engine interface.

type MockedEngineArgs

type MockedEngineArgs struct {
	CreateTable *Model
	RenameTable struct {
		Old *Model
		New *Model
	}
	DropTable *Model
	AddIndex  struct {
		Model  *Model
		Name   string
		Fields []string
	}
	DropIndex struct {
		Model *Model
		Name  string
	}
	AddColumns struct {
		Model  *Model
		Fields Fields
	}
	DropColumns struct {
		Model  *Model
		Fields []string
	}
	SelectQuery struct {
		Model   *Model
		Options QueryOptions
	}
	GetRows struct {
		Model   *Model
		Options QueryOptions
	}
	InsertRow struct {
		Model  *Model
		Values Values
	}
	UpdateRows struct {
		Model   *Model
		Values  Values
		Options QueryOptions
	}
	DeleteRows struct {
		Model   *Model
		Options QueryOptions
	}
	CountRows struct {
		Model   *Model
		Options QueryOptions
	}
	Exists struct {
		Model   *Model
		Options QueryOptions
	}
}

MockedEngineArgs holds the arguments of the Engine interface methods when they've been called from a MockedEngine.

func (*MockedEngineArgs) Reset

func (a *MockedEngineArgs) Reset()

Reset sets all the arguments back to zero values.

type MockedEngineResults

type MockedEngineResults struct {
	Stop        error
	TxSupport   bool
	BeginTx     error
	CommitTx    error
	RollbackTx  error
	CreateTable error
	RenameTable error
	CopyTable   error
	DropTable   error
	AddIndex    error
	DropIndex   error
	AddColumns  error
	DropColumns error
	SelectQuery struct {
		Query Query
		Err   error
	}
	GetRows struct {
		Rows Rows
		Err  error
	}
	InsertRow struct {
		Id  int64
		Err error
	}
	UpdateRows struct {
		Number int64
		Err    error
	}
	DeleteRows struct {
		Number int64
		Err    error
	}
	CountRows struct {
		Number int64
		Err    error
	}
	Exists struct {
		Result bool
		Err    error
	}
}

MockedEngineResults holds the results of the Engine interface methods to be returned by a MockedEngine.

func (*MockedEngineResults) Reset

func (r *MockedEngineResults) Reset()

Reset sets all the results back to zero values.

type Model

type Model struct {
	// contains filtered or unexported fields
}

A Model represents a single basic data structure of an application and how to map that data to the database schema.

func (*Model) AddField

func (m *Model) AddField(name string, field Field) error

AddField adds a new Field to the model definition. It returns an error if the field name already exists or if a duplicate primary key is added.

This method should only be used to modify a model state during migration operations or to construct models programatically. Changing the model definition after it has been registered could cause unexpected errors.

func (*Model) AddIndex

func (m *Model) AddIndex(name string, fields ...string) error

AddIndex adds a new index to the model definition. It returns an error if the name is duplicate or any of the indexed fields doesn't exist.

This method should only be used to modify a model state during migration operations or to construct models programatically. Changing the model definition after it has been registered could cause unexpected errors.

func (Model) App

func (m Model) App() *Application

App returns the Application containing the model.

func (Model) Container

func (m Model) Container() Container

Container returns a new zero value of the model Container.

func (Model) Fields

func (m Model) Fields() Fields

Fields returns the model Fields map.

func (Model) Indexes

func (m Model) Indexes() Indexes

Indexes returns the model Indexes map.

func (Model) Name

func (m Model) Name() string

Name returns the model name.

func (*Model) Register

func (m *Model) Register(app *Application) error

Register validates the model definition, calls the SetupPrimaryKey and SetupIndexes methods, and adds the model to the given app.

func (*Model) RemoveField

func (m *Model) RemoveField(name string) error

RemoveField removes the named field from the model definition. It returns an error if the fields is the primary key, the field is indexed or it doesn't exist.

This method should only be used to modify a model state during migration operations or to construct models programatically. Changing the model definition after it has been registered could cause unexpected errors.

func (*Model) RemoveIndex

func (m *Model) RemoveIndex(name string) error

RemoveIndex removes the named index from the model definition. It returns an error if the index doesn't exist.

This method should only be used to modify a model state during migration operations or to construct models programatically. Changing the model definition after it has been registered could cause unexpected errors.

func (*Model) SetupIndexes

func (m *Model) SetupIndexes() error

SetupIndexes validates the model Indexes definition and adds individually indexes fields.

This method ia automatically called when a model is registered and should only be used to modify a model state during migration operations.

func (*Model) SetupPrimaryKey

func (m *Model) SetupPrimaryKey() error

SetupPrimaryKey searches the model fields for a primary key. If not found, it will add an auto incremented IntegerField called id.

This method ia automatically called when a model is registered and should only be used to modify a model state during migration operations.

func (Model) Table

func (m Model) Table() string

Table returns the name of the database table.

type MultipleObjectsError

type MultipleObjectsError struct {
	Trace ErrorTrace
}

MultipleObjectsError is raised when the Get returns more than one object.

func (*MultipleObjectsError) Error

func (e *MultipleObjectsError) Error() string

Error implements the error interface.

type NullInt32

type NullInt32 struct {
	Int32 int32
	Valid bool // Valid is true if Int32 is not NULL
}

NullInt32 represents an int32 that may be null. TODO: remove for Golang 1.13

func (*NullInt32) Scan

func (n *NullInt32) Scan(value interface{}) error

Scan implements the Scanner interface.

func (NullInt32) Value

func (n NullInt32) Value() (driver.Value, error)

Value implements the driver Valuer interface.

type NullTime

type NullTime struct {
	Time  time.Time
	Valid bool
}

NullTime represents a time.Time that may be null.

func (*NullTime) Scan

func (d *NullTime) Scan(value interface{}) error

Scan implements the Scanner interface.

func (NullTime) Value

func (d NullTime) Value() (driver.Value, error)

Value implements the driver Valuer interface.

type ObjectNotFoundError

type ObjectNotFoundError struct {
	Trace ErrorTrace
}

ObjectNotFoundError is raised when the Get returns no objects.

func (*ObjectNotFoundError) Error

func (e *ObjectNotFoundError) Error() string

Error implements the error interface.

type Options

type Options struct {
	// Table is the name of the database Table for the model. If blank, the
	// table will be {app_name}_{model_name} all lowercase.
	Table string
	// Container is a value of the type that will be used to hold the model
	// field when a new instance is created. If nil, the Values type will be
	// the default Container.
	Container Container
	// Indexes is used to declare composite indexes. Indexes with one column
	// should be defined at field level.
	Indexes Indexes
}

Options holds extra model options.

type PostgresEngine

type PostgresEngine struct {
	// contains filtered or unexported fields
}

PostgresEngine implements the Engine interface for the postgres driver.

func (PostgresEngine) AddColumns

func (e PostgresEngine) AddColumns(model *Model, fields Fields) error

AddColumns implements the AddColumns method of the Engine interface.

func (PostgresEngine) AddIndex

func (e PostgresEngine) AddIndex(m *Model, name string, fields ...string) error

AddIndex implements the AddIndex method of the Engine interface.

func (PostgresEngine) BeginTx

func (e PostgresEngine) BeginTx() (Engine, error)

BeginTx implements the BeginTx method of the Engine interface.

func (PostgresEngine) CommitTx

func (e PostgresEngine) CommitTx() error

CommitTx implements the CommitTx method of the Engine interface.

func (PostgresEngine) CountRows

func (e PostgresEngine) CountRows(m *Model, opt QueryOptions) (int64, error)

CountRows implement the CountRows method of the Engine interface.

func (PostgresEngine) CreateTable

func (e PostgresEngine) CreateTable(model *Model, force bool) error

CreateTable implements the CreateTable method of the Engine interface.

func (PostgresEngine) DB

func (e PostgresEngine) DB() *sql.DB

DB implements the DB method of the Engine interface.

func (PostgresEngine) DeleteRows

func (e PostgresEngine) DeleteRows(m *Model, opt QueryOptions) (int64, error)

DeleteRows implements the DeleteRows method of the engine interface.

func (PostgresEngine) DropColumns

func (e PostgresEngine) DropColumns(model *Model, fields ...string) error

DropColumns implements the DropColumns method of the Engine interface.

func (PostgresEngine) DropIndex

func (e PostgresEngine) DropIndex(model *Model, name string) error

DropIndex implements the DropIndex method of the Engine interface.

func (PostgresEngine) DropTable

func (e PostgresEngine) DropTable(model *Model) error

DropTable implements the DropTable method of the Engine interface.

func (PostgresEngine) Exists

func (e PostgresEngine) Exists(m *Model, opt QueryOptions) (bool, error)

Exsists implements the Exists method of the Engine interface.

func (PostgresEngine) GetRows

func (e PostgresEngine) GetRows(model *Model, opt QueryOptions) (Rows, error)

GetRows implements the GetRows method of the Engine interface.

func (PostgresEngine) InsertRow

func (e PostgresEngine) InsertRow(model *Model, values Values) (int64, error)

InsertRow implements the InsertRow method of the Engine interface.

func (PostgresEngine) RenameTable

func (e PostgresEngine) RenameTable(old *Model, new *Model) error

RenameTable implements the RenameTable method of the Engine interface.

func (PostgresEngine) RollbackTx

func (e PostgresEngine) RollbackTx() error

RollbackTx implements the RollbackTx method of the Engine interface.

func (PostgresEngine) SelectQuery

func (e PostgresEngine) SelectQuery(m *Model, opt QueryOptions) (Query, error)

SelectQuery implements the SelectQuery method of the Engine interface.

func (PostgresEngine) Start

func (e PostgresEngine) Start(db Database) (Engine, error)

Start implements the Start method of the Engine interface.

func (PostgresEngine) Stop

func (e PostgresEngine) Stop() error

Stop implements the Stop method of the Engine interface.

func (PostgresEngine) Tx

func (e PostgresEngine) Tx() *sql.Tx

Tx implements the Tx method of the Engine interface.

func (PostgresEngine) TxSupport

func (e PostgresEngine) TxSupport() bool

TxSupport implements the TxSupport method of the Engine interface.

func (PostgresEngine) UpdateRows

func (e PostgresEngine) UpdateRows(
	model *Model,
	values Values,
	options QueryOptions,
) (int64, error)

UpdateRows implements the UpdateRows method of the Engine interface.

type Q

type Q map[string]Value

Q is a map of values that implements the Conditioner interface for predicates consisting of simple conditions joined by the AND operator.

func (Q) And

func (q Q) And(next Conditioner) Conditioner

And implements Conditioner interface.

func (Q) AndNot

func (q Q) AndNot(next Conditioner) Conditioner

AndNot implements Conditioner interface.

func (Q) Conditions

func (q Q) Conditions() map[string]Value

Conditions implements Conditioner interface.

func (Q) Next

func (q Q) Next() (Conditioner, bool, bool)

Next implements Conditioner interface.

func (Q) Or

func (q Q) Or(next Conditioner) Conditioner

Or implements Conditioner interface.

func (Q) OrNot

func (q Q) OrNot(next Conditioner) Conditioner

OrNot implements Conditioner interface.

func (Q) Root

func (q Q) Root() (Conditioner, bool)

Root implements Conditioner interface.

type Query

type Query struct {
	Stmt string        // Stmt is the prepared statement.
	Args []interface{} // Args is the list of values for the statement.
}

A Query holds the details of a database query.

type QueryOptions

type QueryOptions struct {
	// Conditioner holds the conditions to be applied on the query.
	Conditioner Conditioner
	// Fields are the columns that will be selected on the query.
	Fields []string
	// Start represents the first row index to be selected, starting at 0.
	Start int64
	// End represents the row index to stop the selection.
	End int64
}

QueryOptions holds common arguments for some Engine interface methods.

type QuerySet

type QuerySet interface {
	// New returns a QuerySet representing all the objects from the given model.
	//
	// The parent will be the type used for all methods returning another
	// QuerySet.
	New(model *Model, parent QuerySet) QuerySet
	// Wrap takes a GenericQuerySet, encloses it and returns a custom type.
	//
	// This method is used to create custom QuerySets by embedding a
	// GenericQuerySet, whose methods will call Wrap and return the custom type.
	Wrap(qs GenericQuerySet) QuerySet
	// Model returns the QuerySet model.
	Model() *Model
	// WithContainer returns a QuerySet with the given Container type as a base.
	WithContainer(container Container) QuerySet
	// WithDB returns a QuerySet where all database operations will be applied
	// on the database identified by the given name.
	WithDB(database string) QuerySet
	// WithTx returns a QuerySet where all database operations will be applied
	// on the given transaction.
	WithTx(tx *Transaction) QuerySet
	// Filter returns a new QuerySet with the given conditioner applied to
	// the collections of objects represented by this QuerySet.
	Filter(c Conditioner) QuerySet
	// Exclude takes the current collection of objects, excludes the ones
	// matching the given conditioner and returns a new QuerySet.
	Exclude(c Conditioner) QuerySet
	// Only returns a QuerySet that will select only the given fields when
	// loaded.
	Only(fields ...string) QuerySet
	// Query returns the SELECT query details for the current QuerySet.
	Query() (Query, error)
	// Load retrieves the collection of objects represented by the QuerySet from
	// the database, and returns a list of instances.
	Load() ([]*Instance, error)
	// Slice retrieves the collection of objects represented by the QuerySet
	// from the start to the end parameters. If end is -1, it will retrieve
	// all objects from the given start.
	Slice(start int64, end int64) ([]*Instance, error)
	// Get returns an instance representing the single object from the current
	// collection matching the given conditioner.
	//
	// If no object is found, *ObjectNotFoundError is returned.
	//
	// If multiple objects match the conditions, *MultipleObjectsError is
	// returned.
	Get(c Conditioner) (*Instance, error)
	// Exists returns true if the collection of objects represented by the
	// QuerySet matches at least one row in the database.
	Exists() (bool, error)
	// Count returns the number of rows matching the collection of objects
	// represented by the QuerySet.
	Count() (int64, error)
	// Update modifies the database rows matching the collection of objects
	// represented by the QuerySet with the given values.
	Update(values Container) (int64, error)
	// Delete removes the database rows matching the collection of objects
	// represented by the QuerySet.
	Delete() (int64, error)
}

The QuerySet interface represents a collection of objects from the database, defining the methods to interact with those objects, narrow down the collection and retrieve them.

type QuerySetError

type QuerySetError struct {
	Trace ErrorTrace
}

QuerySetError is raised when a QuerySet related error occurs.

func (*QuerySetError) Error

func (e *QuerySetError) Error() string

Error implements the error interface.

type Rows

type Rows interface {
	// Close closes the rows.
	Close() error
	// Err returns the error, if any, that was encountered during iteration.
	Err() error
	// Next prepares the next result row for reading with the Scan method. It
	// returns true on success, or false if there is no next result row or an
	// error happened while preparing it.
	Next() bool
	// Scan copies the columns in the current row into the values pointed at
	// by dest. The number of values in dest must be the same as the number of
	// columns in Rows.
	Scan(dest ...interface{}) error
}

Rows is an interface wrapping the sql.Rows methods, allowing custom types to be returned by the Engine GetRows method.

type Setter

type Setter interface {
	Set(name string, val Value, field Field) error
}

Setter is the interface that wraps the basic Set method for model containers.

Set receives the name, the value and the Field definition, and returns any error.

type SqliteEngine

type SqliteEngine struct {
	// contains filtered or unexported fields
}

SqliteEngine implements the Engine interface for the sqlite3 driver.

func (SqliteEngine) AddColumns

func (e SqliteEngine) AddColumns(model *Model, fields Fields) error

AddColumns implements the AddColumns method of the Engine interface.

func (SqliteEngine) AddIndex

func (e SqliteEngine) AddIndex(m *Model, name string, fields ...string) error

AddIndex implements the AddIndex method of the Engine interface.

func (SqliteEngine) BeginTx

func (e SqliteEngine) BeginTx() (Engine, error)

BeginTx implemetns the BeginTx method of the Engine interface.

func (SqliteEngine) CommitTx

func (e SqliteEngine) CommitTx() error

CommitTx implements the CommitTx method of the Engine interface.

func (SqliteEngine) CountRows

func (e SqliteEngine) CountRows(m *Model, opt QueryOptions) (int64, error)

CountRows implement the CountRows method of the Engine interface.

func (SqliteEngine) CreateTable

func (e SqliteEngine) CreateTable(model *Model, force bool) error

CreateTable implements the CreateTable method of the Engine interface.

func (SqliteEngine) DB

func (e SqliteEngine) DB() *sql.DB

DB implements the DB method of the Engine interface.

func (SqliteEngine) DeleteRows

func (e SqliteEngine) DeleteRows(m *Model, opt QueryOptions) (int64, error)

DeleteRows implements the DeleteRows method of the engine interface.

func (SqliteEngine) DropColumns

func (e SqliteEngine) DropColumns(model *Model, fields ...string) error

DropColumns implements the DropColumns method of the Engine interface.

Since sqlite3 doesn't support dropping columns, it will perform the operation by creating a new table.

func (SqliteEngine) DropIndex

func (e SqliteEngine) DropIndex(model *Model, name string) error

DropIndex implements the DropIndex method of the Engine interface.

func (SqliteEngine) DropTable

func (e SqliteEngine) DropTable(model *Model) error

DropTable implements the DropTable method of the Engine interface.

func (SqliteEngine) Exists

func (e SqliteEngine) Exists(m *Model, opt QueryOptions) (bool, error)

Exsists implements the Exists method of the Engine interface.

func (SqliteEngine) GetRows

func (e SqliteEngine) GetRows(model *Model, opt QueryOptions) (Rows, error)

GetRows implements the GetRows method of the Engine interface.

func (SqliteEngine) InsertRow

func (e SqliteEngine) InsertRow(model *Model, values Values) (int64, error)

InsertRow implements the InsertRow method of the Engine interface.

func (SqliteEngine) RenameTable

func (e SqliteEngine) RenameTable(old *Model, new *Model) error

RenameTable implements the RenameTable method of the Engine interface.

func (SqliteEngine) RollbackTx

func (e SqliteEngine) RollbackTx() error

RollbackTx implements the RollbackTx method of the Engine interface.

func (SqliteEngine) SelectQuery

func (e SqliteEngine) SelectQuery(m *Model, opt QueryOptions) (Query, error)

SelectQuery implements the SelectQuery method of the Engine interface.

func (SqliteEngine) Start

func (e SqliteEngine) Start(db Database) (Engine, error)

Start implemetns the Start method of the Engine interface.

func (SqliteEngine) Stop

func (e SqliteEngine) Stop() error

Stop implements the Stop method of the Engine interface.

func (SqliteEngine) Tx

func (e SqliteEngine) Tx() *sql.Tx

Tx implements the Tx method of the Engine interface.

func (SqliteEngine) TxSupport

func (e SqliteEngine) TxSupport() bool

TxSupport implements the TxSupport method of the Engine interface.

func (SqliteEngine) UpdateRows

func (e SqliteEngine) UpdateRows(
	model *Model,
	values Values,
	options QueryOptions,
) (int64, error)

UpdateRows implements the UpdateRows method of the Engine interface.

type TimeField

type TimeField struct {
	// PrimaryKey is true if the field is the model primary key.
	PrimaryKey bool `json:",omitempty"`
	// Unique is true if the field value must be unique.
	Unique bool `json:",omitempty"`
	// Null is true if the field can have null values.
	Null bool `json:",omitempty"`
	// AutoNow is true if the value is auto generated on row updates.
	AutoNow bool `json:",omitempty"`
	// AutoNowAdd is true if the value is auto generated on row inserts.
	AutoNowAdd bool `json:",omitempty"`
	// Blank is true if the field is not required. Only used for validation.
	Blank bool `json:",omitempty"`
	// Index is true if the field column should be indexed.
	Index bool `json:",omitempty"`
	// Column is the name of the db column. If blank, it will be the field name.
	Column string `json:",omitempty"`
	// Choices is a list of possible choices for the field.
	Choices []Choice `json:",omitempty"`
	// Default is the default value for the field. Blank for no default
	Default time.Time `json:",omitempty"`
}

TimeField implements the Field interface for time values.

func (TimeField) DBColumn

func (f TimeField) DBColumn(name string) string

DBColumn implements the DBColumn method of the Field interface.

func (TimeField) DataType

func (f TimeField) DataType(dvr string) string

DataType implements the DataType method of the Field interface.

func (TimeField) DefaultValue

func (f TimeField) DefaultValue() (Value, bool)

DefaultValue implements the DefaultValue method of the Field interface.

func (TimeField) DisplayValue

func (f TimeField) DisplayValue(val Value) string

DisplayValue implements the DisplayValue method of the Field interface.

func (TimeField) DriverValue

func (f TimeField) DriverValue(v Value, dvr string) (interface{}, error)

DriverValue implements the DriverValue method of the Field interface.

func (TimeField) HasIndex

func (f TimeField) HasIndex() bool

HasIndex implements the HasIndex method of the Field interface.

func (TimeField) IsAuto

func (f TimeField) IsAuto() bool

IsAuto implements the IsAuto method of the Field interface.

func (TimeField) IsAutoNow

func (f TimeField) IsAutoNow() bool

IsAutoNow implements the IsAutoNow method of the Field interface.

func (TimeField) IsAutoNowAdd

func (f TimeField) IsAutoNowAdd() bool

IsAutoNowAdd implements the IsAutoNowAdd method of the Field interface.

func (TimeField) IsNull

func (f TimeField) IsNull() bool

IsNull implements the IsNull method of the Field interface.

func (TimeField) IsPK

func (f TimeField) IsPK() bool

IsPK implements the IsPK method of the Field interface.

func (TimeField) IsUnique

func (f TimeField) IsUnique() bool

IsUnique implements the IsUnique method of the Field interface.

func (TimeField) MarshalJSON

func (f TimeField) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (TimeField) Recipient

func (f TimeField) Recipient() interface{}

Recipient implements the Recipient method of the Field interface.

func (*TimeField) UnmarshalJSON

func (f *TimeField) UnmarshalJSON(data []byte) error

func (TimeField) Value

func (f TimeField) Value(rec interface{}) Value

Value implements the Value method of the Field interface.

type Transaction

type Transaction struct {
	// Engine is the interface providing the database-abstraction API.
	Engine
	// DB is the Database where the transaction was created.
	DB Database
}

Transaction holds a database transaction.

func (Transaction) Commit

func (tx Transaction) Commit() error

Commit commits the transaction.

func (Transaction) Rollback

func (tx Transaction) Rollback() error

Rollback rolls back the transction.

type Value

type Value interface{}

Value represents a value for a model field.

type Values

type Values map[string]Value

Values is a map of field values that implements the Builder interface and is used as the default model Container.

func (Values) Get

func (vals Values) Get(key string) (Value, bool)

Get implements the Getter interface.

func (Values) New

func (vals Values) New() Builder

New implements the Builder interface.

func (Values) Set

func (vals Values) Set(key string, val Value, field Field) error

Set implements the Setter interface.

Directories

Path Synopsis
Package migration provides the tools to detect and manage the changes made to application models, store them in version control and apply them to the database schema.
Package migration provides the tools to detect and manage the changes made to application models, store them in version control and apply them to the database schema.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL