Documentation ¶
Index ¶
- Constants
- Variables
- func DefaultColumnizer(in string) string
- func DefaultPluralizer(in string) string
- func ToColumnName(in string) string
- func ToTableName(object interface{}) (name string)
- type Changes
- type ConvertParameters
- type DB
- type Field
- type Model
- func (m Model) Assign(target interface{}, lotsOfChanges ...Changes) (out []Changes, err error)
- func (m Model) Changes(in RawChanges) (out Changes)
- func (m Model) Count(values ...interface{}) (count int, err error)
- func (m Model) CreatedAt() Changes
- func (m Model) Delete(values ...interface{}) SQLWithValues
- func (m Model) DropSchema() string
- func (m Model) Exists(values ...interface{}) (exists bool, err error)
- func (m Model) FieldByName(name string) *Field
- func (m Model) Find(values ...interface{}) SQLWithValues
- func (m Model) Insert(lotsOfChanges ...Changes) func(...string) SQLWithValues
- func (m Model) MustAssign(i interface{}, lotsOfChanges ...Changes) []Changes
- func (m Model) MustCount(values ...interface{}) int
- func (m Model) MustExists(values ...interface{}) bool
- func (m Model) NewSQLWithValues(sql string, values ...interface{}) SQLWithValues
- func (m Model) Permit(fieldNames ...string) *ModelWithPermittedFields
- func (m Model) PermitAllExcept(fieldNames ...string) *ModelWithPermittedFields
- func (m Model) Schema() string
- func (m Model) Select(fields string, values ...interface{}) SQLWithValues
- func (m *Model) SetConnection(db DB) *Model
- func (m *Model) SetLogger(logger logger.Logger) *Model
- func (m *Model) SetOptions(options ...interface{}) *Model
- func (m Model) String() string
- func (m Model) TableName() string
- func (m Model) Update(lotsOfChanges ...Changes) func(...interface{}) SQLWithValues
- func (m Model) UpdatedAt() Changes
- type ModelWithPermittedFields
- func (m ModelWithPermittedFields) Bind(ctx interface{ ... }, target interface{}) (Changes, error)
- func (m ModelWithPermittedFields) Filter(inputs ...interface{}) (out Changes)
- func (m ModelWithPermittedFields) MustBind(ctx interface{ ... }, target interface{}) Changes
- func (m ModelWithPermittedFields) PermittedFields() (out []string)
- type ModelWithTableName
- type RawChanges
- type Result
- type Row
- type Rows
- type SQLWithValues
- func (s SQLWithValues) ExecTx(tx Tx, ctx context.Context, dest ...interface{}) (err error)
- func (s SQLWithValues) Execute(dest ...interface{}) error
- func (s SQLWithValues) ExecuteInTransaction(txOpts *TxOptions, dest ...interface{}) error
- func (s SQLWithValues) MustExecute(dest ...interface{})
- func (s SQLWithValues) MustExecuteInTransaction(txOpts *TxOptions, dest ...interface{})
- func (s SQLWithValues) MustQuery(target interface{})
- func (s SQLWithValues) MustQueryRow(dest ...interface{})
- func (s SQLWithValues) MustQueryRowInTransaction(txOpts *TxOptions, dest ...interface{})
- func (s SQLWithValues) Query(target interface{}) error
- func (s SQLWithValues) QueryRow(dest ...interface{}) error
- func (s SQLWithValues) QueryRowInTransaction(txOpts *TxOptions, dest ...interface{}) error
- func (s SQLWithValues) QueryTx(tx Tx, ctx context.Context, dest ...interface{}) (rows Rows, err error)
- func (s SQLWithValues) String() string
- type Scannable
- type Tx
- type TxOptions
Constants ¶
const ( LevelSerializable = "serializable" LevelRepeatableRead = "repeatable read" LevelReadCommitted = "read committed" LevelReadUncommitted = "read uncommitted" )
Variables ¶
var ( ErrInvalidTarget = errors.New("target must be pointer of a struct or pointer of a slice of structs") ErrNoConnection = errors.New("no connection") ErrTypeAssertionFailed = errors.New("type assertion failed") )
var ( // Function to convert a name to table or column name used in database, // by default uses DefaultColumnizer which converts "CamelCase" to "snake_case". Columnizer func(string) string = DefaultColumnizer // Function to convert table name to its plural form. // By default, table name uses plural form. Pluralizer func(string) string = DefaultPluralizer )
var (
ErrMustBePointer = errors.New("must be pointer")
)
Functions ¶
func DefaultColumnizer ¶
Default function to convert "CamelCase" struct name to "snake_case" column name used in database. For example, "FullName" will be converted to "full_name".
func DefaultPluralizer ¶
Default function to convert a word to its plural form. Add "es" for "s" or "o" ending, "y" ending will be replaced with "ies", for other endings, add "s". For example, "product" will be converted to "products".
func ToColumnName ¶
Function to convert struct name to name used in database, using the Columnizer function.
func ToTableName ¶
func ToTableName(object interface{}) (name string)
Get table name from a struct. If a struct has "TableName() string" function, then the return value of the function will be used. If a struct has a field named "__TABLE_NAME__", then value of the field tag will be used. Otherwise, the name of the struct will be used. If name is empty, "error_no_table_name" is returned. Examples:
- type Product struct{}; func (_ Product) TableName() string { return "foobar" }; ToTableName(Product{}) == "foobar"
- ToTableName(struct { __TABLE_NAME__ string `users` }{}) == "users"
- type Product struct{}; ToTableName(Product{}) == "products"
- ToTableName(struct{}{}) == "error_no_table_name"
Types ¶
type ConvertParameters ¶
type DB ¶
type DB interface { Close() error Exec(query string, args ...interface{}) (Result, error) Query(query string, args ...interface{}) (Rows, error) QueryRow(query string, args ...interface{}) Row BeginTx(ctx context.Context, isolationLevel string) (Tx, error) ErrNoRows() error ErrGetCode(err error) string }
type Field ¶
type Field struct { Name string // struct field name ColumnName string // column name (or jsonb key name) in database JsonName string // key name in json input and output Jsonb string // jsonb column name in database DataType string // data type in database Exported bool // false if field name is lower case (unexported) }
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is a database table and it is created from struct. Table name is inferred from the name of thea struct, the tag of __TABLE_NAME__ field or its TableName() receiver. Column names are inferred from struct field names or theirs "column" tags. Both table names and field names are in snake_case by default.
func NewModel ¶
func NewModel(object interface{}, options ...interface{}) (m *Model)
Initialize a Model from a struct. For available options, see SetOptions().
func NewModelSlim ¶
func NewModelSlim(object interface{}, options ...interface{}) (m *Model)
Initialize a Model from a struct without parsing fields of the struct. Useful if you are calling functions that don't need fields, for example:
db.NewModelSlim(models.User{}, conn).MustCount()
For available options, see SetOptions().
func NewModelTable ¶
Initialize a Model by defining table name only. Useful if you are calling functions that don't need fields, for example:
db.NewModelTable("users", conn).MustCount()
For available options, see SetOptions().
func (Model) Assign ¶
Assign changes to target object. Useful if you want to validate your struct.
func create(c echo.Context) error { var user models.User m := db.NewModel(user, conn) changes := m.MustAssign( &user, m.Permit("Name").Filter(c.Request().Body), ) if err := c.Validate(user); err != nil { panic(err) } var id int m.Insert(changes...)("RETURNING id").MustQueryRow(&id) // ... }
func (Model) Changes ¶
func (m Model) Changes(in RawChanges) (out Changes)
Convert RawChanges to Changes.
m := db.NewModel(struct { Age *int `json:"age"` }{}) m.Changes(map[string]interface{}{ "age": 99, })
func (Model) Count ¶
Create and execute a SELECT COUNT(*) statement, return number of rows. You can provide conditions (like WHERE, ORDER BY, LIMIT) to the statement as the first argument. The rest arguments are for any placeholder parameters in the statement.
func (Model) Delete ¶
func (m Model) Delete(values ...interface{}) SQLWithValues
Delete builds a DELETE statement. You can add extra clause (like WHERE, RETURNING) to the statement as the first argument. The rest arguments are for any placeholder parameters in the statement.
var ids []int db.NewModelTable("reports", conn).Delete("RETURNING id").MustQuery(&ids)
func (Model) DropSchema ¶
Generate DROP TABLE ("DROP TABLE IF EXISTS <table_name>;") SQL statement from a Model.
func (Model) Exists ¶
Create and execute a SELECT 1 AS one statement. Returns true if record exists, false if not exists.
func (Model) FieldByName ¶
Get field by struct field name, nil will be returned if no such field.
func (Model) Find ¶
func (m Model) Find(values ...interface{}) SQLWithValues
Create a SELECT query statement with all fields of a Model. You can provide conditions (like WHERE, ORDER BY, LIMIT) to the statement as the first argument. The rest arguments are for any placeholder parameters in the statement. If you want to use other data type than the type of struct passed in NewModel(), see Select().
// put results into a slice var users []models.User db.NewModel(models.User{}, conn).Find().MustQuery(&users) // put results into a struct var user models.User db.NewModel(models.User{}, conn).Find("WHERE id = $1", 1).MustQuery(&user)
func (Model) Insert ¶
func (m Model) Insert(lotsOfChanges ...Changes) func(...string) SQLWithValues
Insert builds an INSERT INTO statement with fields and values in the changes, returns a function with optional string argument which you can add extra clause (like ON CONFLICT or RETURNING) to the statement.
var id int m.Insert(changes...)("RETURNING id").MustQueryRow(&id)
func (Model) MustAssign ¶
MustAssign is like Assign but panics if assign operation fails.
func (Model) MustExists ¶
MustExists is like Exists but panics if existence check operation fails. Returns true if record exists, false if not exists.
func (Model) NewSQLWithValues ¶
func (m Model) NewSQLWithValues(sql string, values ...interface{}) SQLWithValues
Create new SQLWithValues with SQL statement as first argument, The rest arguments are for any placeholder parameters in the statement.
func (Model) Permit ¶
func (m Model) Permit(fieldNames ...string) *ModelWithPermittedFields
Permits list of field names of a Model to limit Filter() which fields should be allowed for mass updating. If no field names are provided ("Permit()"), no fields are permitted.
func (Model) PermitAllExcept ¶
func (m Model) PermitAllExcept(fieldNames ...string) *ModelWithPermittedFields
Permits all available fields except provided of a Model to limit Filter() which fields should be allowed for mass updating. If no field names are provided ("PermitAllExcept()"), all available fields are permitted.
func (Model) Schema ¶
Generate CREATE TABLE SQL statement from a Model.
| Go Type | PostgreSQL Data Type | |------------------------------------------------|----------------------| | int8 / int16 / int32 / uint8 / uint16 / uint32 | integer | | int64 / uint64 / int / uint | bigint | | time.Time | timestamptz | | float32 / float64 / decimal.Decimal | numeric | | bool | boolean | | other | text |
You can use "dataType" tag to customize the data type. "NOT NULL" is added if the struct field is not a pointer. You can also set SQL statements before or after this statement by defining "BeforeCreateSchema() string" (for example the CREATE EXTENSION statement) or "AfterCreateSchema() string" (for example the CREATE INDEX statement) function for the struct.
db.NewModel(struct { __TABLE_NAME__ string `users` Id int Name string Age *int CreatedAt time.Time DeletedAt *time.Time `dataType:"timestamptz"` FullName string `jsonb:"meta"` NickName string `jsonb:"meta"` }{}).Schema() // CREATE TABLE users ( // id SERIAL PRIMARY KEY, // name text DEFAULT ''::text NOT NULL, // age bigint DEFAULT 0, // created_at timestamptz DEFAULT NOW() NOT NULL, // deleted_at timestamptz, // meta jsonb DEFAULT '{}'::jsonb NOT NULL // );
func (Model) Select ¶
func (m Model) Select(fields string, values ...interface{}) SQLWithValues
Select is like Find but you can choose what columns to retrieve.
// put results into a slice var names []string db.NewModelTable("users", conn).Select("name", "ORDER BY id ASC").MustQuery(&names) // put results into a map var id2name map[int]string db.NewModelTable("users", conn).Select("id, name", "ORDER BY id ASC").MustQuery(&id2name) // put results into a slice of custom struct var users []struct { name string id int } db.NewModelTable("users", conn).Select("name, id", "ORDER BY id ASC").MustQuery(&users)
func (*Model) SetConnection ¶
Set a database connection for the Model. ErrNoConnection is returned if no connection is set.
func (*Model) SetLogger ¶
Set the logger for the Model. Use logger.StandardLogger if you want to use Go's built-in standard logging package. By default, no logger is used, so the SQL statements are not printed to the console.
func (*Model) SetOptions ¶
SetOptions sets database connection (see SetConnection()) and/or logger (see SetLogger()).
func (Model) Update ¶
func (m Model) Update(lotsOfChanges ...Changes) func(...interface{}) SQLWithValues
Update builds an UPDATE statement with fields and values in the changes, returns a function with optional conditions (like WHERE) to the statement as the first argument. The rest arguments are for any placeholder parameters in the statement.
var rowsAffected int m.Update(changes...)("WHERE user_id = $1", 1).MustExecute(&rowsAffected)
type ModelWithPermittedFields ¶
type ModelWithPermittedFields struct { *Model // contains filtered or unexported fields }
func (ModelWithPermittedFields) Bind ¶
func (m ModelWithPermittedFields) Bind(ctx interface{ Bind(interface{}) error }, target interface{}) (Changes, error)
Bind data of permitted fields to target structure using echo.Context#Bind function. The "target" must be a pointer to struct.
// request with ?name=x&age=10 func list(c echo.Context) error { obj := struct { Name string `query:"name"` Age int `query:"age"` }{} m := db.NewModel(obj) fmt.Println(m.Permit("Name").Bind(c, &obj)) fmt.Println(obj) // "Name" is "x" and "Age" is 0 (default), because only "Name" is permitted to change // ... }
func (ModelWithPermittedFields) Filter ¶
func (m ModelWithPermittedFields) Filter(inputs ...interface{}) (out Changes)
Filter keeps data of permitted fields set by Permit() from multiple inputs. Inputs can be RawChanges (map[string]interface{}) or JSON-encoded data (string, []byte or io.Reader), their keys must be fields' JSON names. Input can also be a struct. The "Changes" outputs can be arguments for Insert() or Update().
m := db.NewModel(struct { Age *int `json:"age"` }{}) m.Permit("Age").Filter( db.RawChanges{ "age": 10, }, map[string]interface{}{ "age": 20, }, `{"age": 30}`, []byte(`{"age": 40}`), strings.NewReader(`{"age": 50}`), struct{ Age int }{60}, ) // Age is 60
func (ModelWithPermittedFields) MustBind ¶
func (m ModelWithPermittedFields) MustBind(ctx interface{ Bind(interface{}) error }, target interface{}) Changes
MustBind is like Bind but panics if bind operation fails.
func (ModelWithPermittedFields) PermittedFields ¶
func (m ModelWithPermittedFields) PermittedFields() (out []string)
Returns list of permitted field names.
type ModelWithTableName ¶
type ModelWithTableName interface {
TableName() string
}
type RawChanges ¶
type RawChanges map[string]interface{}
type SQLWithValues ¶
type SQLWithValues struct {
// contains filtered or unexported fields
}
SQLWithValues can be created with Model.NewSQLWithValues(sql, values...)
func (SQLWithValues) ExecTx ¶
func (s SQLWithValues) ExecTx(tx Tx, ctx context.Context, dest ...interface{}) (err error)
ExecTx executes a query in a transaction without returning any rows. You can get number of rows affected by providing pointer of int or int64 to the optional dest.
func (SQLWithValues) Execute ¶
func (s SQLWithValues) Execute(dest ...interface{}) error
Execute executes a query without returning any rows by an UPDATE, INSERT, or DELETE. You can get number of rows affected by providing pointer of int or int64 to the optional dest. For use cases, see Update().
func (SQLWithValues) ExecuteInTransaction ¶
func (s SQLWithValues) ExecuteInTransaction(txOpts *TxOptions, dest ...interface{}) error
ExecuteInTransaction is like Execute but executes the statement in a transaction, you can define IsolationLevel and statements Before and/or After it.
func (SQLWithValues) MustExecute ¶
func (s SQLWithValues) MustExecute(dest ...interface{})
MustExecute is like Execute but panics if execute operation fails.
func (SQLWithValues) MustExecuteInTransaction ¶
func (s SQLWithValues) MustExecuteInTransaction(txOpts *TxOptions, dest ...interface{})
MustExecuteInTransaction is like ExecuteInTransaction but panics if execute operation fails.
func (SQLWithValues) MustQuery ¶
func (s SQLWithValues) MustQuery(target interface{})
MustQuery is like Query but panics if query operation fails.
func (SQLWithValues) MustQueryRow ¶
func (s SQLWithValues) MustQueryRow(dest ...interface{})
MustQueryRow is like QueryRow but panics if query row operation fails.
func (SQLWithValues) MustQueryRowInTransaction ¶
func (s SQLWithValues) MustQueryRowInTransaction(txOpts *TxOptions, dest ...interface{})
MustQueryRowInTransaction is like QueryRowInTransaction but panics if query row operation fails.
func (SQLWithValues) Query ¶
func (s SQLWithValues) Query(target interface{}) error
Query executes the SQL query and put the results into the target. If target is pointer of a struct, at most one row of the query is returned. If target is a pointer of a slice, all rows of the query are returned. If target is a pointer of a map, first column in the SELECT list will be the key of the map, and the second column is the value of the map. For use cases, see Find() and Select().
func (SQLWithValues) QueryRow ¶
func (s SQLWithValues) QueryRow(dest ...interface{}) error
QueryRow gets results from the first row, and put values of each column to corresponding dest. For use cases, see Insert().
var u struct { name string id int } db.NewModelTable("users", conn).Select("name, id").MustQueryRow(&u.name, &u.id)
func (SQLWithValues) QueryRowInTransaction ¶
func (s SQLWithValues) QueryRowInTransaction(txOpts *TxOptions, dest ...interface{}) error
QueryRowInTransaction is like QueryRow but executes the statement in a transaction, you can define IsolationLevel and statements Before and/or After it.
func (SQLWithValues) QueryTx ¶
func (s SQLWithValues) QueryTx(tx Tx, ctx context.Context, dest ...interface{}) (rows Rows, err error)
Query executes the SQL query and returns rows.
func (SQLWithValues) String ¶
func (s SQLWithValues) String() string
type Tx ¶
type Tx interface { ExecContext(ctx context.Context, query string, args ...interface{}) (Result, error) QueryContext(ctx context.Context, query string, args ...interface{}) (Rows, error) QueryRowContext(ctx context.Context, query string, args ...interface{}) Row Commit(ctx context.Context) error Rollback(ctx context.Context) error }