README ¶
POP
A Tasty Treat For All Your Database Needs
So what does Pop do exactly? Well, it wraps the absolutely amazing https://github.com/jmoiron/sqlx library. It cleans up some of the common patterns and workflows usually associated with dealing with databases in Go.
Pop makes it easy to do CRUD operations, run migrations, and build/execute queries. Is Pop an ORM? I'll leave that up to you, the reader, to decide.
Pop, by default, follows conventions that were defined by the ActiveRecord Ruby gem, http://www.rubyonrails.org. What does this mean?
- Tables must have an "id" column and a corresponding "ID" field on the
struct
being used. - If there is a timestamp column named "created_at", "CreatedAt" on the
struct
, it will be set with the current time when the record is created. - If there is a timestamp column named "updated_at", "UpdatedAt" on the
struct
, it will be set with the current time when the record is updated. - Default database table names are lowercase, plural, and underscored versions of the
struct
name. Examples: User{} is "users", FooBar{} is "foo_bars", etc...
Supported Databases
- PostgreSQL (>= 9.3)
- MySQL (>= 5.7)
- SQLite (>= 3.x)
- CockroachDB (>= 1.1.1)
Connecting to Databases
Pop is easily configured using a YAML file. The configuration file should be stored in config/database.yml
or database.yml
.
Example Configuration File
development:
dialect: "postgres"
database: "your_db_development"
host: "localhost"
port: "5432"
user: "postgres"
password: "postgres"
test:
dialect: "mysql"
database: "your_db_test"
host: "localhost"
port: "3306"
user: "root"
password: "root"
staging:
dialect: "sqlite3"
database: "./staging.sqlite"
production:
dialect: "postgres"
url: {{ env "DATABASE_URL" }}
Note that the database.yml
file is also a Go template, so you can use Go template syntax. There are two special functions that are included, env
and envOr
.
env
- This function will look for the named environment variable and insert it into your file. This is useful for configuring production databases without having to store secret information in your repository.{{ env "DATABASE_URL" }}
envOr
- This function will look for the named environment variable and use it. If the variable can not be found a default value will be used.{{ envOr "MYSQL_HOST" "localhost" }}
You can generate a default configuration file using the init
command:
$ soda g config
The default will generate a database.yml
file in the current directory for a PostgreSQL database. You can override the type of database using the -t
flag and passing in any of the supported database types: postgres
, cockroach
, mysql
, or sqlite3
.
CockroachDB currently works best if you DO NOT use a url and instead define each key item. Because CockroachDB more or less uses the same driver as postgres you have the same configuration options for both. In production you will also want to make sure you are using a secure cluster and have set all the needed connection parameters for said secure connection. If you do not set the sslmode or set it to disable
this will put dump and load commands into --insecure
mode.
In your code
Once you have a configuration file defined you can easily connect to one of these connections in your application.
db, err := pop.Connect("development")
if err != nil {
log.Panic(err)
}
Now that you have your connection to the database you can start executing queries against it.
CLI Support
Pop features CLI support via the soda
command for the following operations:
- creating databases
- dropping databases
- migrating databases
Installing CLI Support
$ go get github.com/gobuffalo/pop/...
$ go install github.com/gobuffalo/pop/soda
Creating Databases
Assuming you defined a configuration file like that described in the above section you can automatically create those databases using the soda
command:
Create All Databases
$ soda create -a
Create a Specific Database
$ soda create -e development
Dropping Databases
Assuming you defined a configuration file like that described in the above section you can automatically drop those databases using the soda
command:
Drop All Databases
$ soda drop -a
Drop a Specific Database
$ soda drop -e development
Models
The soda
command supports the generation of models.
A full list of commands available for model generation can be found by asking for help:
$ soda generate help
Generate Models
The soda
command will generate Go models and, optionally, the associated migrations for you.
$ soda generate model user name:text email:text
Running this command with generate the following files:
models/user.go
models/user_test.go
migrations/20170115024143_create_users.up.fizz
migrations/20170115024143_create_users.down.fizz
The models/user.go
file contains a structure named User
with fields ID
, CreatedAt
, UpdatedAt
, Name
, and Email
. The first three correspond to the columns commonly found in ActiveRecord models as mentioned before, and the last two correspond to the additional fields specified on the command line. The known types are:
text
(string
in Go)time
ortimestamp
(time.Time
)nulls.Text
(nulls.String
) which corresponds to a nullifyable string, which can be distinguished from an empty stringuuid
(uuid.UUID
)- Other types are passed thru and are used as Fizz types.
The models/user_test.go
contains tests for the User model and they must be implemented by you.
The other two files correspond to the migrations as explained below.
Migrations
The soda
command supports the creation and running of migrations.
A full list of commands available for migration can be found by asking for help:
$ soda migrate --help
Create Migrations
The soda
command will generate SQL migrations (both the up and down) files for you.
$ soda generate fizz name_of_migration
Running this command with generate the following files:
./migrations/20160815134952_name_of_migration.up.fizz
./migrations/20160815134952_name_of_migration.down.fizz
The generated files are fizz
files. Fizz lets you use a common DSL for generating migrations. This means the same .fizz
file can be run against any of the supported dialects of Pop! Find out more about Fizz
If you want to generate old fashion .sql
files you can use the -t
flag for that:
$ soda generate sql name_of_migration
Running this command with generate the following files:
./migrations/20160815134952_name_of_migration.up.sql
./migrations/20160815134952_name_of_migration.down.sql
The soda migrate
command supports both .fizz
and .sql
files, so you can mix and match them to suit your needs.
Running Migrations
The soda
command will run the migrations using the following command:
$ soda migrate up
Migrations will be run in sequential order. The previously run migrations will be kept track of in a table named schema_migrations
in the database.
Migrations can also be run in reverse to rollback the schema.
$ soda migrate down
Find
user := models.User{}
err := tx.Find(&user, id)
Query
tx := models.DB
query := tx.Where("id = 1").Where("name = 'Mark'")
users := []models.User{}
err := query.All(&users)
err = tx.Where("id in (?)", 1, 2, 3).All(&users)
// page: page number
// perpage: limit
roles := []models.UserRole{}
query := models.DB.LeftJoin("roles", "roles.id=user_roles.role_id").
LeftJoin("users u", "u.id=user_roles.user_id").
Where(`roles.name like ?`, name).Paginate(page, perpage)
count, _ := query.Count(models.UserRole{})
count, _ := query.CountByField(models.UserRole{}, "*")
sql, args := query.ToSQL(&pop.Model{Value: models.UserRole{}}, "user_roles.*",
"roles.name as role_name", "u.first_name", "u.last_name")
//log.Printf("sql: %s, args: %v", sql, args)
err := models.DB.RawQuery(sql, args...).All(&roles)
Eager Loading
pop allows you to perform an eager loading for associations defined in a model. By using pop.Connection.Eager()
function plus some fields tags predefined in your model you can extract associated data from a model.
type User struct {
ID uuid.UUID
Email string
Password string
Books Books `has_many:"books" order_by:"title asc"`
FavoriteSong Song `has_one:"song" fk_id:"u_id"`
Houses Addresses `many_to_many:"users_addresses"`
}
type Book struct {
ID uuid.UUID
Title string
Isbn string
User User `belongs_to:"user"`
UserID uuid.UUID
}
type Song struct {
ID uuid.UUID
Title string
UserID uuid.UUID `db:"u_id"`
}
type Address struct {
ID uuid.UUID
Street string
HouseNumber int
}
type Addresses []Address
has_many: will load all records from the books
table that have a column named user_id
or the column specified with fk_id that matches the User.ID
value.
belongs_to: will load a record from users
table that have a column named id
that matches with Book.UserID
value.
has_one: will load a record from the songs
table that have a column named user_id
or the column specified with fk_id that matches the User.ID
value.
many_to_many: will load all records from the addresses
table through the table users_addresses
. Table users_addresses
MUST define address_id
and user_id
columns to match User.ID
and Address.ID
values. You can also define a fk_id tag that will be used in the target association i.e addresses
table.
fk_id: defines the column name in the target association that matches model ID
. In the example above Song
has a column named u_id
that represents id
of users
table. When loading FavoriteSong
, u_id
will be used instead of user_id
.
order_by: used in has_many
and many_to_many
to indicate the order for the association when loading. The format to use is order_by:"<column_name> <asc | desc>"
u := Users{}
err := tx.Eager().Where("name = 'Mark'").All(&u) // preload all associations for user with name 'Mark', i.e Books, Houses and FavoriteSong
err = tx.Eager("Books").Where("name = 'Mark'").All(&u) // preload only Books association for user with name 'Mark'.
Callbacks
Pop provides a means to execute code before and after database operations. This is done by defining specific methods on your models. For example, to hash a user password you may want to define the following method:
type User struct {
ID uuid.UUID
Email string
Password string
}
func (u *User) BeforeSave(tx *pop.Connection) error {
hash, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
if err != nil {
return errors.WithStack(err)
}
u.Password = string(hash)
return nil
}
The available callbacks include:
- BeforeSave
- BeforeCreate
- BeforeUpdate
- BeforeDestroy
- AfterSave
- AfterCreate
- AfterUpdate
- AfterDestroy
- AfterFind
Further reading
The Unofficial pop Book: a gentle introduction to new users.
Documentation ¶
Overview ¶
Package pop wraps the absolutely amazing https://github.com/jmoiron/sqlx library. It cleans up some of the common patterns and workflows usually associated with dealing with databases in Go.
Pop makes it easy to do CRUD operations, run migrations, and build/execute queries. Is Pop an ORM? I'll leave that up to you, the reader, to decide.
Pop, by default, follows conventions that were defined by the ActiveRecord Ruby gem, http://www.rubyonrails.org. What does this mean?
* Tables must have an "id" column and a corresponding "ID" field on the `struct` being used. * If there is a timestamp column named "created_at", "CreatedAt" on the `struct`, it will be set with the current time when the record is created. * If there is a timestamp column named "updated_at", "UpdatedAt" on the `struct`, it will be set with the current time when the record is updated. * Default databases are lowercase, underscored versions of the `struct` name. Examples: User{} is "users", FooBar{} is "foo_bars", etc...
Index ¶
- Variables
- func AddLookupPaths(paths ...string) error
- func CreateDB(c *Connection) error
- func DropDB(c *Connection) error
- func LoadConfigFile() error
- func LoadFrom(r io.Reader) error
- func LookupPaths() []string
- func MigrationCreate(path, name, ext string, up, down []byte) error
- type Connection
- func (c *Connection) All(models interface{}) error
- func (c *Connection) BelongsTo(model interface{}) *Query
- func (c *Connection) BelongsToAs(model interface{}, as string) *Query
- func (c *Connection) BelongsToThrough(bt, thru interface{}) *Query
- func (c *Connection) Close() error
- func (c *Connection) Count(model interface{}) (int, error)
- func (c *Connection) Create(model interface{}, excludeColumns ...string) error
- func (c *Connection) Destroy(model interface{}) error
- func (c *Connection) Eager(fields ...string) *Query
- func (c *Connection) Find(model interface{}, id interface{}) error
- func (c *Connection) First(model interface{}) error
- func (c *Connection) Last(model interface{}) error
- func (c *Connection) Limit(limit int) *Query
- func (c *Connection) Load(model interface{}, fields ...string) error
- func (c *Connection) MigrateDown(path string, step int) error
- func (c *Connection) MigrateReset(path string) error
- func (c *Connection) MigrateStatus(path string) error
- func (c *Connection) MigrateUp(path string) error
- func (c *Connection) MigrationURL() string
- func (c *Connection) NewTransaction() (*Connection, error)
- func (c *Connection) Open() error
- func (c *Connection) Order(stmt string) *Query
- func (c *Connection) Paginate(page int, perPage int) *Query
- func (c *Connection) PaginateFromParams(params PaginationParams) *Query
- func (c *Connection) Q() *Query
- func (c *Connection) RawQuery(stmt string, args ...interface{}) *Query
- func (c *Connection) Reload(model interface{}) error
- func (c *Connection) Rollback(fn func(tx *Connection)) error
- func (c *Connection) Save(model interface{}, excludeColumns ...string) error
- func (c *Connection) Scope(sf ScopeFunc) *Query
- func (c *Connection) String() string
- func (c *Connection) Transaction(fn func(tx *Connection) error) error
- func (c *Connection) TruncateAll() error
- func (c *Connection) URL() string
- func (c *Connection) Update(model interface{}, excludeColumns ...string) error
- func (c *Connection) ValidateAndCreate(model interface{}, excludeColumns ...string) (*validate.Errors, error)
- func (c *Connection) ValidateAndSave(model interface{}, excludeColumns ...string) (*validate.Errors, error)
- func (c *Connection) ValidateAndUpdate(model interface{}, excludeColumns ...string) (*validate.Errors, error)
- func (c *Connection) Where(stmt string, args ...interface{}) *Query
- type ConnectionDetails
- type FileMigrator
- type GroupClause
- type HavingClause
- type Migration
- type MigrationBox
- type Migrations
- type Migrator
- type Model
- type PaginationParams
- type Paginator
- type Query
- func (q *Query) All(models interface{}) error
- func (q *Query) BelongsTo(model interface{}) *Query
- func (q *Query) BelongsToAs(model interface{}, as string) *Query
- func (q *Query) BelongsToThrough(bt, thru interface{}) *Query
- func (q *Query) Clone(targetQ *Query)
- func (q Query) Count(model interface{}) (int, error)
- func (q Query) CountByField(model interface{}, field string) (int, error)
- func (q *Query) Eager(fields ...string) *Query
- func (q *Query) Exec() error
- func (q *Query) ExecWithCount() (int, error)
- func (q *Query) Exists(model interface{}) (bool, error)
- func (q *Query) Find(model interface{}, id interface{}) error
- func (q *Query) First(model interface{}) error
- func (q *Query) GroupBy(field string, fields ...string) *Query
- func (q *Query) Having(condition string, args ...interface{}) *Query
- func (q *Query) Join(table string, on string, args ...interface{}) *Query
- func (q *Query) Last(model interface{}) error
- func (q *Query) LeftInnerJoin(table string, on string, args ...interface{}) *Query
- func (q *Query) LeftJoin(table string, on string, args ...interface{}) *Query
- func (q *Query) LeftOuterJoin(table string, on string, args ...interface{}) *Query
- func (q *Query) Limit(limit int) *Query
- func (q *Query) Order(stmt string) *Query
- func (q *Query) Paginate(page int, perPage int) *Query
- func (q *Query) PaginateFromParams(params PaginationParams) *Query
- func (q *Query) RawQuery(stmt string, args ...interface{}) *Query
- func (q *Query) RightInnerJoin(table string, on string, args ...interface{}) *Query
- func (q *Query) RightJoin(table string, on string, args ...interface{}) *Query
- func (q *Query) RightOuterJoin(table string, on string, args ...interface{}) *Query
- func (q *Query) Scope(sf ScopeFunc) *Query
- func (q Query) ToSQL(model *Model, addColumns ...string) (string, []interface{})
- func (q *Query) Where(stmt string, args ...interface{}) *Query
- type ScopeFunc
- type TableNameAble
- type Tx
- type Value
Constants ¶
This section is empty.
Variables ¶
var Color = true
Color mode, to toggle colored logs
var ConfigName = "database.yml"
ConfigName is the name of the YAML databases config file
var Connections = map[string]*Connection{}
Connections contains all of the available connections
var Debug = false
Debug mode, to toggle verbose log traces
var Log = func(s string, args ...interface{}) { if Debug { if len(args) > 0 { xargs := make([]string, len(args)) for i, a := range args { switch a.(type) { case string: xargs[i] = fmt.Sprintf("%q", a) default: xargs[i] = fmt.Sprintf("%v", a) } } s = fmt.Sprintf("%s | %s", s, xargs) } if Color { s = color.YellowString(s) } logger.Println(s) } }
Log a formatted string to the logger
var PaginatorPageKey = "page"
PaginatorPageKey is the query parameter holding the current page index
var PaginatorPerPageDefault = 20
PaginatorPerPageDefault is the amount of results per page
var PaginatorPerPageKey = "per_page"
PaginatorPerPageKey is the query parameter holding the amount of results per page to override the default one
Functions ¶
func AddLookupPaths ¶
AddLookupPaths add paths to the current lookup paths list
func CreateDB ¶
func CreateDB(c *Connection) error
CreateDB creates a database, given a connection definition
func DropDB ¶
func DropDB(c *Connection) error
DropDB drops an existing database, given a connection definition
func LoadConfigFile ¶
func LoadConfigFile() error
LoadConfigFile loads a POP config file from the configured lookup paths
func LookupPaths ¶
func LookupPaths() []string
LookupPaths returns the current configuration lookup paths
func MigrationCreate ¶
MigrationCreate writes contents for a given migration in normalized files
Types ¶
type Connection ¶
Connection represents all of the necessary details for talking with a datastore
func Connect ¶
func Connect(e string) (*Connection, error)
Connect takes the name of a connection, default is "development", and will return that connection from the available `Connections`. If a connection with that name can not be found an error will be returned. If a connection is found, and it has yet to open a connection with its underlying datastore, a connection to that store will be opened.
func NewConnection ¶
func NewConnection(deets *ConnectionDetails) (*Connection, error)
NewConnection creates a new connection, and sets it's `Dialect` appropriately based on the `ConnectionDetails` passed into it.
func (*Connection) All ¶
func (c *Connection) All(models interface{}) error
All retrieves all of the records in the database that match the query.
c.All(&[]User{})
func (*Connection) BelongsTo ¶
func (c *Connection) BelongsTo(model interface{}) *Query
BelongsTo adds a "where" clause based on the "ID" of the "model" passed into it.
func (*Connection) BelongsToAs ¶
func (c *Connection) BelongsToAs(model interface{}, as string) *Query
BelongsToAs adds a "where" clause based on the "ID" of the "model" passed into it using an alias.
func (*Connection) BelongsToThrough ¶
func (c *Connection) BelongsToThrough(bt, thru interface{}) *Query
BelongsToThrough adds a "where" clause that connects the "bt" model through the associated "thru" model.
func (*Connection) Close ¶
func (c *Connection) Close() error
Close destroys an active datasource connection
func (*Connection) Count ¶
func (c *Connection) Count(model interface{}) (int, error)
Count the number of records in the database.
c.Count(&User{})
func (*Connection) Create ¶
func (c *Connection) Create(model interface{}, excludeColumns ...string) error
Create add a new given entry to the database, excluding the given columns. It updates `created_at` and `updated_at` columns automatically.
func (*Connection) Destroy ¶
func (c *Connection) Destroy(model interface{}) error
Destroy deletes a given entry from the database
func (*Connection) Eager ¶
func (c *Connection) Eager(fields ...string) *Query
Eager will enable load associations of the model. by defaults loads all the associations on the model, but can take a variadic list of associations to load.
c.Eager().Find(model, 1) // will load all associations for model. c.Eager("Books").Find(model, 1) // will load only Book association for model.
func (*Connection) Find ¶
func (c *Connection) Find(model interface{}, id interface{}) error
Find the first record of the model in the database with a particular id.
c.Find(&User{}, 1)
func (*Connection) First ¶
func (c *Connection) First(model interface{}) error
First record of the model in the database that matches the query.
c.First(&User{})
func (*Connection) Last ¶
func (c *Connection) Last(model interface{}) error
Last record of the model in the database that matches the query.
c.Last(&User{})
func (*Connection) Limit ¶
func (c *Connection) Limit(limit int) *Query
Limit will add a limit clause to the query.
func (*Connection) Load ¶
func (c *Connection) Load(model interface{}, fields ...string) error
Load loads all association or the fields specified in params for an already loaded model.
tx.First(&u) tx.Load(&u)
func (*Connection) MigrateDown ¶
func (c *Connection) MigrateDown(path string, step int) error
MigrateDown is deprecated, and will be removed in a future version. Use FileMigrator#Down instead.
func (*Connection) MigrateReset ¶
func (c *Connection) MigrateReset(path string) error
MigrateReset is deprecated, and will be removed in a future version. Use FileMigrator#Reset instead.
func (*Connection) MigrateStatus ¶
func (c *Connection) MigrateStatus(path string) error
MigrateStatus is deprecated, and will be removed in a future version. Use FileMigrator#Status instead.
func (*Connection) MigrateUp ¶
func (c *Connection) MigrateUp(path string) error
MigrateUp is deprecated, and will be removed in a future version. Use FileMigrator#Up instead.
func (*Connection) MigrationURL ¶
func (c *Connection) MigrationURL() string
MigrationURL returns the datasource connection string used for running the migrations
func (*Connection) NewTransaction ¶
func (c *Connection) NewTransaction() (*Connection, error)
NewTransaction starts a new transaction on the connection
func (*Connection) Open ¶
func (c *Connection) Open() error
Open creates a new datasource connection
func (*Connection) Order ¶
func (c *Connection) Order(stmt string) *Query
Order will append an order clause to the query.
c.Order("name desc")
func (*Connection) Paginate ¶
func (c *Connection) Paginate(page int, perPage int) *Query
Paginate records returned from the database.
q := c.Paginate(2, 15) q.All(&[]User{}) q.Paginator
func (*Connection) PaginateFromParams ¶
func (c *Connection) PaginateFromParams(params PaginationParams) *Query
PaginateFromParams paginates records returned from the database.
q := c.PaginateFromParams(req.URL.Query()) q.All(&[]User{}) q.Paginator
func (*Connection) Q ¶
func (c *Connection) Q() *Query
Q creates a new "empty" query for the current connection.
func (*Connection) RawQuery ¶
func (c *Connection) RawQuery(stmt string, args ...interface{}) *Query
RawQuery will override the query building feature of Pop and will use whatever query you want to execute against the `Connection`. You can continue to use the `?` argument syntax.
c.RawQuery("select * from foo where id = ?", 1)
func (*Connection) Reload ¶
func (c *Connection) Reload(model interface{}) error
Reload fetch fresh data for a given model, using its ID
func (*Connection) Rollback ¶
func (c *Connection) Rollback(fn func(tx *Connection)) error
Rollback will open a new transaction and automatically rollback that transaction when the inner function returns, regardless. This can be useful for tests, etc...
func (*Connection) Save ¶
func (c *Connection) Save(model interface{}, excludeColumns ...string) error
Save wraps the Create and Update methods. It executes a Create if no ID is provided with the entry; or issues an Update otherwise.
func (*Connection) Scope ¶
func (c *Connection) Scope(sf ScopeFunc) *Query
Scope the query by using a `ScopeFunc`
func ByName(name string) ScopeFunc { return func(q *Query) *Query { return q.Where("name = ?", name) } } c.Scope(ByName("mark")).First(&User{})
func (*Connection) String ¶
func (c *Connection) String() string
func (*Connection) Transaction ¶
func (c *Connection) Transaction(fn func(tx *Connection) error) error
Transaction will start a new transaction on the connection. If the inner function returns an error then the transaction will be rolled back, otherwise the transaction will automatically commit at the end.
func (*Connection) TruncateAll ¶
func (c *Connection) TruncateAll() error
TruncateAll truncates all data from the datasource
func (*Connection) URL ¶
func (c *Connection) URL() string
URL returns the datasource connection string
func (*Connection) Update ¶
func (c *Connection) Update(model interface{}, excludeColumns ...string) error
Update writes changes from an entry to the database, excluding the given columns. It updates the `updated_at` column automatically.
func (*Connection) ValidateAndCreate ¶
func (c *Connection) ValidateAndCreate(model interface{}, excludeColumns ...string) (*validate.Errors, error)
ValidateAndCreate applies validation rules on the given entry, then creates it if the validation succeed, excluding the given columns.
func (*Connection) ValidateAndSave ¶
func (c *Connection) ValidateAndSave(model interface{}, excludeColumns ...string) (*validate.Errors, error)
ValidateAndSave applies validation rules on the given entry, then save it if the validation succeed, excluding the given columns.
func (*Connection) ValidateAndUpdate ¶
func (c *Connection) ValidateAndUpdate(model interface{}, excludeColumns ...string) (*validate.Errors, error)
ValidateAndUpdate applies validation rules on the given entry, then update it if the validation succeed, excluding the given columns.
func (*Connection) Where ¶
func (c *Connection) Where(stmt string, args ...interface{}) *Query
Where will append a where clause to the query. You may use `?` in place of arguments.
c.Where("id = ?", 1) q.Where("id in (?)", 1, 2, 3)
type ConnectionDetails ¶
type ConnectionDetails struct { // Example: "postgres" or "sqlite3" or "mysql" Dialect string // The name of your database. Example: "foo_development" Database string // The host of your database. Example: "127.0.0.1" Host string // The port of your database. Example: 1234 // Will default to the "default" port for each dialect. Port string // The username of the database user. Example: "root" User string // The password of the database user. Example: "password" Password string // Instead of specifying each individual piece of the // connection you can instead just specify the URL of the // database. Example: "postgres://postgres:postgres@localhost:5432/pop_test?sslmode=disable" URL string // Defaults to 0 "unlimited". See https://golang.org/pkg/database/sql/#DB.SetMaxOpenConns Pool int Options map[string]string }
ConnectionDetails stores the data needed to connect to a datasource
func (*ConnectionDetails) Finalize ¶
func (cd *ConnectionDetails) Finalize() error
Finalize cleans up the connection details by normalizing names, filling in default values, etc...
func (*ConnectionDetails) Parse ¶
func (cd *ConnectionDetails) Parse(port string) error
Parse is deprecated! Please use `ConnectionDetails.Finalize()` instead!
func (*ConnectionDetails) RetryLimit ¶
func (cd *ConnectionDetails) RetryLimit() int
RetryLimit returns the maximum number of accepted connection retries
func (*ConnectionDetails) RetrySleep ¶
func (cd *ConnectionDetails) RetrySleep() time.Duration
RetrySleep returns the amount of time to wait between two connection retries
type FileMigrator ¶
FileMigrator is a migrator for SQL and Fizz files on disk at a specified path.
func NewFileMigrator ¶
func NewFileMigrator(path string, c *Connection) (FileMigrator, error)
NewFileMigrator for a path and a Connection
type GroupClause ¶
type GroupClause struct {
Field string
}
GroupClause holds the field to apply the GROUP clause on
func (GroupClause) String ¶
func (c GroupClause) String() string
type HavingClause ¶
type HavingClause struct { Condition string Arguments []interface{} }
HavingClause defines a condition and its arguments for a HAVING clause
func (HavingClause) String ¶
func (c HavingClause) String() string
type Migration ¶
type Migration struct { // Path to the migration (./migrations/123_create_widgets.up.sql) Path string // Version of the migration (123) Version string // Name of the migration (create_widgets) Name string // Direction of the migration (up) Direction string // Type of migration (sql) Type string // Runner function to run/execute the migration Runner func(Migration, *Connection) error }
Migration handles the data for a given database migration
func (Migration) Run ¶
func (mf Migration) Run(c *Connection) error
Run the migration. Returns an error if there is no mf.Runner defined.
type MigrationBox ¶
MigrationBox is a wrapper around packr.Box and Migrator. This will allow you to run migrations from a packed box inside of a compiled binary.
func NewMigrationBox ¶
func NewMigrationBox(box packr.Box, c *Connection) (MigrationBox, error)
NewMigrationBox from a packr.Box and a Connection.
type Migrations ¶
type Migrations []Migration
Migrations is a collection of Migration
func (Migrations) Len ¶
func (mfs Migrations) Len() int
func (Migrations) Less ¶
func (mfs Migrations) Less(i, j int) bool
func (Migrations) Swap ¶
func (mfs Migrations) Swap(i, j int)
type Migrator ¶
type Migrator struct { Connection *Connection SchemaPath string Migrations map[string]Migrations }
Migrator forms the basis of all migrations systems. It does the actual heavy lifting of running migrations. When building a new migration system, you should embed this type into your migrator.
func NewMigrator ¶
func NewMigrator(c *Connection) Migrator
NewMigrator returns a new "blank" migrator. It is recommended to use something like MigrationBox or FileMigrator. A "blank" Migrator should only be used as the basis for a new type of migration system.
func (Migrator) CreateSchemaMigrations ¶
CreateSchemaMigrations sets up a table to track migrations. This is an idempotent operation.
func (Migrator) Down ¶
Down runs pending "down" migrations and rolls back the database by the specified number of steps.
func (Migrator) DumpMigrationSchema ¶
DumpMigrationSchema will generate a file of the current database schema based on the value of Migrator.SchemaPath
func (Migrator) Reset ¶
Reset the database by runing the down migrations followed by the up migrations.
type Model ¶
Model is used throughout Pop to wrap the end user interface that is passed in to many functions.
func (*Model) ID ¶
func (m *Model) ID() interface{}
ID returns the ID of the Model. All models must have an `ID` field this is of type `int`,`int64` or of type `uuid.UUID`.
func (*Model) PrimaryKeyType ¶
PrimaryKeyType gives the primary key type of the `Model`.
type PaginationParams ¶
PaginationParams is a parameters provider interface to get the pagination params from
type Paginator ¶
type Paginator struct { // Current page you're on Page int `json:"page"` // Number of results you want per page PerPage int `json:"per_page"` // Page * PerPage (ex: 2 * 20, Offset == 40) Offset int `json:"offset"` // Total potential records matching the query TotalEntriesSize int `json:"total_entries_size"` // Total records returns, will be <= PerPage CurrentEntriesSize int `json:"current_entries_size"` // Total pages TotalPages int `json:"total_pages"` }
Paginator is a type used to represent the pagination of records from the database.
func NewPaginator ¶
NewPaginator returns a new `Paginator` value with the appropriate defaults set.
func NewPaginatorFromParams ¶
func NewPaginatorFromParams(params PaginationParams) *Paginator
NewPaginatorFromParams takes an interface of type `PaginationParams`, the `url.Values` type works great with this interface, and returns a new `Paginator` based on the params or `PaginatorPageKey` and `PaginatorPerPageKey`. Defaults are `1` for the page and PaginatorPerPageDefault for the per page value.
type Query ¶
type Query struct { RawSQL *clause Paginator *Paginator Connection *Connection // contains filtered or unexported fields }
Query is the main value that is used to build up a query to be executed against the `Connection`.
func Q ¶
func Q(c *Connection) *Query
Q will create a new "empty" query from the current connection.
func (*Query) All ¶
All retrieves all of the records in the database that match the query.
q.Where("name = ?", "mark").All(&[]User{})
func (*Query) BelongsTo ¶
BelongsTo adds a "where" clause based on the "ID" of the "model" passed into it.
func (*Query) BelongsToAs ¶
BelongsToAs adds a "where" clause based on the "ID" of the "model" passed into it, using an alias.
func (*Query) BelongsToThrough ¶
BelongsToThrough adds a "where" clause that connects the "bt" model through the associated "thru" model.
func (Query) Count ¶
Count the number of records in the database.
q.Where("name = ?", "mark").Count(&User{})
func (Query) CountByField ¶
CountByField counts the number of records in the database, for a given field.
q.Where("sex = ?", "f").Count(&User{}, "name")
func (*Query) Eager ¶
Eager will enable load associations of the model. by defaults loads all the associations on the model, but can take a variadic list of associations to load.
q.Eager().Find(model, 1) // will load all associations for model. q.Eager("Books").Find(model, 1) // will load only Book association for model.
func (*Query) ExecWithCount ¶
func (*Query) Exists ¶
Exists returns true/false if a record exists in the database that matches the query.
q.Where("name = ?", "mark").Exists(&User{})
func (*Query) Find ¶
Find the first record of the model in the database with a particular id.
q.Find(&User{}, 1)
func (*Query) First ¶
First record of the model in the database that matches the query.
q.Where("name = ?", "mark").First(&User{})
func (*Query) Last ¶
Last record of the model in the database that matches the query.
q.Where("name = ?", "mark").Last(&User{})
func (*Query) LeftInnerJoin ¶
LeftInnerJoin will append a LEFT INNER JOIN clause to the query
func (*Query) LeftOuterJoin ¶
LeftOuterJoin will append a LEFT OUTER JOIN clause to the query
func (*Query) Paginate ¶
Paginate records returned from the database.
q = q.Paginate(2, 15) q.All(&[]User{}) q.Paginator
func (*Query) PaginateFromParams ¶
func (q *Query) PaginateFromParams(params PaginationParams) *Query
PaginateFromParams paginates records returned from the database.
q = q.PaginateFromParams(req.URL.Query()) q.All(&[]User{}) q.Paginator
func (*Query) RawQuery ¶
RawQuery will override the query building feature of Pop and will use whatever query you want to execute against the `Connection`. You can continue to use the `?` argument syntax.
q.RawQuery("select * from foo where id = ?", 1)
func (*Query) RightInnerJoin ¶
RightInnerJoin will append a RIGHT INNER JOIN clause to the query
func (*Query) RightOuterJoin ¶
RightOuterJoin will append a RIGHT OUTER JOIN clause to the query
func (*Query) Scope ¶
Scope the query by using a `ScopeFunc`
func ByName(name string) ScopeFunc { return func(q *Query) *Query { return q.Where("name = ?", name) } } q.Scope(ByName("mark").Where("id = ?", 1).First(&User{})
type TableNameAble ¶
type TableNameAble interface {
TableName() string
}
TableNameAble interface allows for the customize table mapping between a name and the database. For example the value `User{}` will automatically map to "users". Implementing `TableNameAble` would allow this to change to be changed to whatever you would like.
type Tx ¶
func (*Tx) Transaction ¶
Transaction simply returns the current transaction, this is defined so it implements the `Store` interface.
Source Files ¶
- belongs_to.go
- callbacks.go
- clause.go
- cockroach.go
- commands.go
- config.go
- connection.go
- connection_details.go
- db.go
- dialect.go
- doc.go
- executors.go
- file_migrator.go
- finders.go
- group.go
- having.go
- join.go
- migration.go
- migration_box.go
- migration_info.go
- migrator.go
- model.go
- mysql.go
- paginator.go
- pop.go
- postgresql.go
- query.go
- query_groups.go
- query_having.go
- query_joins.go
- schema_migrations.go
- scopes.go
- sql_builder.go
- sqlite.go
- store.go
- tx.go
- validations.go