Categorygithub.com/mattes/postgres
repositorypackage
0.0.0-20190930184550-893ea48b676a
Repository: https://github.com/mattes/postgres.git
Documentation: pkg.go.dev

# README

Postgres GoDoc

Postgres wraps github.com/lib/pq and implements a set of new features on top of it:

Postgres >= 11 required.

Status: under active development, exposed func signatures mostly stable

Usage

import pg "github.com/mattes/postgres"

type User struct {
  Id    string `db:"pk"`
  Name  string
  Email string
}

func init() {
  // Register struct &User{} with alias 'user.v1',
  // and have new ids prefixed with 'user'.
  pg.RegisterWithPrefix(&User{}, "user.v1", "user")
}

func main() {
  db, _ := pg.Open(os.Getenv("DB"))
  db.Migrate(context.Background())

  u := &User{
    Id:    pg.NewID(&User{}), // example: user_1R0D8rn6jP870lrtSpgb1y6M5tG
    Name:  "Karl",
    Email: "[email protected]",
  }
  db.Insert(context.Background(), u) // insert into table user_v1

  // ... for more examples, have a look at the docs.
}

Encoding & Decoding of Go types

This package converts between the following types. A postgres column can be null, if the related Go type can be nil. Otherwise Go's zero value is used as the postgres default value. Complex Go types are stored as JSON.

Go typePostgres column type
implements ColumnTyper"returned value"
implements sql.Scannertext null
time.Timetimestamp (6) without time zone
time.Durationbigint
[]stringtext[] null
stringtext not null default ''
boolboolean not null default false
intinteger not null default 0
struct{}jsonb null
[]Tjsonb null
map[T]Tjsonb null

Migrations for Go structs

Postgres tables should follow Go structs. This package is able to automatically run migrations to create new tables with primary keys, indexes and foreign keys.

Only backwards compatible, non-destructive migrations are applied to ensure that two or more Go processes with different Go struct schemas can run at the same time.

Use-caseautomatically migrated?
Create a new table for structYes
Add a new column for a new field in a structYes
Change field's nameNo
Change field's typeNo
Remove a fieldNo
Add a new field to primary keyNo
Remove a field from primary keyNo
Add a new indexYes
Remove an indexNo
Add a new field to indexNo
Remove a field from indexNo
Add a new unique indexYes, if existing data doesn't violate unique constraint.
Remove an unique indexNo
Add a new field to unique indexNo
Remove a field from unique indexNo
Add a new foreign keyYes, if existing data doesn't violate unique/ foreign key constraint.
Remove a foreign keyNo

Changes that are not backwards compatible usually require all deprecated Go processes to stop first. To enable zero-downtime deploys, it's recommended to either create a new table or field and write and read from the old and new table or field simultaneously until the deprecated versions are stopped and removed.

Struct tags

This package will pick up db struct tags to build queries and create migrations. The following struct tags are supported:

Primary Keys

// Column becomes primary key
Col string `db:"pk"` 

// Col1 and Col2 become composite primary key
Col1 string `db:"pk(name=mypk, method=hash, order=desc, composite=[Col2]"` 
Col2 string

Foreign Keys

// Column references A.Col
Col string `db:"references(struct=A, field=Col)"`

// Column references A.Col1 and A.Col2
Col string `db:"references(struct=A, fields=[Col1, Col2])"`

Indexes

// Column has index
Col string `db:"index"`

// Column has composite index
Col1 string `db:"index(name=myindex, method=hash, order=desc, composite=[Col2]"`
Col2 string

// Column has unique index
Col string `db:"unique"`

// Column has unique composite index
Col1 string `db:"unique(name=myindex, method=hash, order=desc, composite=[Col2]"`
Col2 string

Table Partitions

Partitions table by range, see docs.

CreatedAt time.Time `db:"pk,partitionByRange"`

Testing

Set env variable GOTEST_POSTGRES_URI (see helper_test.go for example) and run make test.