package pg

Import Path
	github.com/go-pg/pg/v10 (on go.dev)

Dependency Relation
	imports 24 packages, and imported by one package


Code Examples { src := []string{"one@example.com", "two@example.com"} var dst []string _, err := pgdb.QueryOne(pg.Scan(pg.Array(&dst)), `SELECT ?`, pg.Array(src)) panicIf(err) fmt.Println(dst) } { db := pg.Connect(&pg.Options{ User: "postgres", Password: "postgres", Database: "postgres", }) defer db.Close() var n int _, err := db.QueryOne(pg.Scan(&n), "SELECT 1") panicIf(err) fmt.Println(n) } { db := txExample() incrInTx := func(db *pg.DB) error { tx, err := db.Begin() if err != nil { return err } defer tx.Rollback() var counter int _, err = tx.QueryOne( pg.Scan(&counter), `SELECT counter FROM tx_test FOR UPDATE`) if err != nil { return err } counter++ _, err = tx.Exec(`UPDATE tx_test SET counter = ?`, counter) if err != nil { return err } return tx.Commit() } var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() err := incrInTx(db) panicIf(err) }() } wg.Wait() var counter int _, err := db.QueryOne(pg.Scan(&counter), `SELECT counter FROM tx_test`) panicIf(err) fmt.Println(counter) } { _, err := pgdb.Exec(`CREATE TEMP TABLE words(word text, len int)`) panicIf(err) r := strings.NewReader("hello,5\nfoo,3\n") _, err = pgdb.CopyFrom(r, `COPY words FROM STDIN WITH CSV`) panicIf(err) var buf bytes.Buffer _, err = pgdb.CopyTo(&buf, `COPY words TO STDOUT WITH CSV`) panicIf(err) fmt.Println(buf.String()) } { res, err := pgdb.Exec(`CREATE TEMP TABLE test()`) panicIf(err) fmt.Println(res.RowsAffected()) } package main import ( "fmt" "github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10/orm" ) type User struct { Id int64 Name string Emails []string } func (u User) String() string { return fmt.Sprintf("User<%d %s %v>", u.Id, u.Name, u.Emails) } type Story struct { Id int64 Title string AuthorId int64 Author *User `pg:"rel:has-one"` } func (s Story) String() string { return fmt.Sprintf("Story<%d %s %s>", s.Id, s.Title, s.Author) } func main() { db := pg.Connect(&pg.Options{ User: "postgres", Password: "postgres", }) defer db.Close() err := createSchema(db) if err != nil { panic(err) } user1 := &User{ Name: "admin", Emails: []string{"admin1@admin", "admin2@admin"}, } _, err = db.Model(user1).Insert() if err != nil { panic(err) } _, err = db.Model(&User{ Name: "root", Emails: []string{"root1@root", "root2@root"}, }).Insert() if err != nil { panic(err) } story1 := &Story{ Title: "Cool story", AuthorId: user1.Id, } _, err = db.Model(story1).Insert() if err != nil { panic(err) } // Select user by primary key. user := &User{Id: user1.Id} err = db.Model(user).WherePK().Select() if err != nil { panic(err) } // Select all users. var users []User err = db.Model(&users).Select() if err != nil { panic(err) } // Select story and associated author in one query. story := new(Story) err = db.Model(story). Relation("Author"). Where("story.id = ?", story1.Id). Select() if err != nil { panic(err) } fmt.Println(user) fmt.Println(users) fmt.Println(story) } // createSchema creates database schema for User and Story models. func createSchema(db *pg.DB) error { models := []interface{}{ (*User)(nil), (*Story)(nil), } for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ Temp: true, }) if err != nil { return err } } return nil } { // Profile belongs to User. type Profile struct { Id int Lang string UserId int } type User struct { Id int Name string Profile *Profile `pg:"rel:belongs-to"` } db := connect() defer db.Close() qs := []string{ "CREATE TEMP TABLE users (id int, name text)", "CREATE TEMP TABLE profiles (id int, lang text, user_id int)", "INSERT INTO users VALUES (1, 'user 1'), (2, 'user 2')", "INSERT INTO profiles VALUES (1, 'en', 1), (2, 'ru', 2)", } for _, q := range qs { _, err := db.Exec(q) if err != nil { panic(err) } } var users []User err := db.Model(&users). Column("user.*"). Relation("Profile"). Select() if err != nil { panic(err) } fmt.Println(len(users), "results") fmt.Println(users[0].Id, users[0].Name, users[0].Profile) fmt.Println(users[1].Id, users[1].Name, users[1].Profile) } { db := modelDB() var books []Book err := db.Model(&books).Select() if err != nil { panic(err) } res, err := db.Model(&books).Delete() if err != nil { panic(err) } fmt.Println("deleted", res.RowsAffected()) count, err := db.Model((*Book)(nil)).Count() if err != nil { panic(err) } fmt.Println("left", count) } { db := modelDB() book1 := &Book{ Title: "new book 1", } book2 := &Book{ Title: "new book 2", } _, err := db.Model(book1, book2).Insert() if err != nil { panic(err) } fmt.Println(book1, book2) for _, book := range []*Book{book1, book2} { _, err := db.Model(book).WherePK().Delete() if err != nil { panic(err) } } } { db := modelDB() books := []Book{{ Title: "new book 1", }, { Title: "new book 2", }} _, err := db.Model(&books).Insert() if err != nil { panic(err) } fmt.Println(books) for i := range books { _, err := db.Model(&books[i]).WherePK().Delete() if err != nil { panic(err) } } } { db := modelDB() book1 := &Book{ ID: 1, Title: "updated book 1", UpdatedAt: time.Now(), } book2 := &Book{ ID: 2, Title: "updated book 2", UpdatedAt: time.Now(), } _, err := db.Model(book1, book2).Column("title", "updated_at").Update() if err != nil { panic(err) } var books []Book err = db.Model(&books).Order("id").Select() if err != nil { panic(err) } fmt.Println(books) } { db := modelDB() books := []Book{{ ID: 1, Title: "updated book 1", UpdatedAt: time.Now(), }, { ID: 2, Title: "updated book 2", UpdatedAt: time.Now(), }} _, err := db.Model(&books).Column("title", "updated_at").Update() if err != nil { panic(err) } books = nil err = db.Model(&books).Order("id").Select() if err != nil { panic(err) } fmt.Println(books) } package main import ( "fmt" "github.com/go-pg/pg/v10/orm" ) type InventoryItem struct { Name string SupplierID int Price float64 } type OnHand struct { tableName struct{} `pg:"on_hand"` Item InventoryItem `pg:"composite:inventory_item"` Count int } func main() { db := connect() defer db.Close() err := db.Model((*OnHand)(nil)).DropTable(&orm.DropTableOptions{ IfExists: true, Cascade: true, }) panicIf(err) err = db.Model((*InventoryItem)(nil)).DropComposite(&orm.DropCompositeOptions{ IfExists: true, }) panicIf(err) err = db.Model((*InventoryItem)(nil)).CreateComposite(nil) panicIf(err) err = db.Model((*OnHand)(nil)).CreateTable(nil) panicIf(err) _, err = db.Model(&OnHand{ Item: InventoryItem{ Name: "fuzzy dice", SupplierID: 42, Price: 1.99, }, Count: 1000, }).Insert() panicIf(err) onHand := new(OnHand) err = db.Model(onHand).Select() panicIf(err) fmt.Println(onHand.Item.Name, onHand.Item.Price, onHand.Count) } { db := modelDB() count, err := db.Model(&Book{}).Count() if err != nil { panic(err) } fmt.Println(count) } { db := modelDB() count, err := db.Model(&Book{}).CountEstimate(0) if err != nil { panic(err) } fmt.Println(count) } { type Model1 struct { Id int } type Model2 struct { Id int Name string Model1Id int `pg:"on_delete:RESTRICT,on_update: CASCADE"` Model1 *Model1 `pg:"rel:has-one"` } for _, model := range []interface{}{&Model1{}, &Model2{}} { err := pgdb.Model(model).CreateTable(&orm.CreateTableOptions{ Temp: true, FKConstraints: true, }) panicIf(err) } var info []struct { ColumnName string DataType string } _, err := pgdb.Query(&info, ` SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'model2' `) panicIf(err) fmt.Println(info) } package main import ( "fmt" "time" "github.com/go-pg/pg/v10/orm" "github.com/go-pg/pg/v10/types" ) const pgTimeFormat = "15:04:05.999999999" type Time struct { time.Time } var _ types.ValueAppender = (*Time)(nil) func (tm Time) AppendValue(b []byte, flags int) ([]byte, error) { if flags == 1 { b = append(b, '\'') } b = tm.UTC().AppendFormat(b, pgTimeFormat) if flags == 1 { b = append(b, '\'') } return b, nil } var _ types.ValueScanner = (*Time)(nil) func (tm *Time) ScanValue(rd types.Reader, n int) error { if n <= 0 { tm.Time = time.Time{} return nil } tmp, err := rd.ReadFullTemp() if err != nil { return err } tm.Time, err = time.ParseInLocation(pgTimeFormat, string(tmp), time.UTC) if err != nil { return err } return nil } type Event struct { Id int Time Time `pg:"type:time"` } func main() { db := connect() defer db.Close() err := db.Model((*Event)(nil)).CreateTable(&orm.CreateTableOptions{ Temp: true, }) panicIf(err) _, err = db.Model(&Event{ Time: Time{time.Date(0, 0, 0, 12, 00, 00, 00, time.UTC)}, // noon }).Insert() panicIf(err) evt := new(Event) err = db.Model(evt).Select() panicIf(err) fmt.Println(evt.Time) } { db := modelDB() book := &Book{ Title: "title 1", AuthorID: 1, } _, err := db.Model(book).Insert() if err != nil { panic(err) } _, err = db.Model(book).WherePK().Delete() if err != nil { panic(err) } err = db.Model(book).WherePK().Select() fmt.Println(err) } { db := modelDB() ids := pg.In([]int{1, 2, 3}) res, err := db.Model((*Book)(nil)).Where("id IN (?)", ids).Delete() if err != nil { panic(err) } fmt.Println("deleted", res.RowsAffected()) count, err := db.Model((*Book)(nil)).Count() if err != nil { panic(err) } fmt.Println("left", count) } { type Model1 struct { } var model1 Model1 _, err := pgdb.QueryOne(&model1, "SELECT 1 AS id") fmt.Printf("Model1: %v\n", err) type Model2 struct { tableName struct{} `pg:",discard_unknown_columns"` } var model2 Model2 _, err = pgdb.QueryOne(&model2, "SELECT 1 AS id") fmt.Printf("Model2: %v\n", err) } { db := modelDB() var books []Book exists, err := db.Model(&books).Where("author_id = ?", 1).Exists() if err != nil { panic(err) } fmt.Println(exists) } { err := pgdb.Model((*Book)(nil)). OrderExpr("id ASC"). ForEach(func(b *Book) error { fmt.Println(b) return nil }) if err != nil { panic(err) } } { type Profile struct { Id int Lang string Active bool UserId int } // User has many profiles. type User struct { Id int Name string Profiles []*Profile `pg:"rel:has-many"` } db := connect() defer db.Close() qs := []string{ "CREATE TEMP TABLE users (id int, name text)", "CREATE TEMP TABLE profiles (id int, lang text, active bool, user_id int)", "INSERT INTO users VALUES (1, 'user 1')", "INSERT INTO profiles VALUES (1, 'en', TRUE, 1), (2, 'ru', TRUE, 1), (3, 'md', FALSE, 1)", } for _, q := range qs { _, err := db.Exec(q) if err != nil { panic(err) } } var user User err := db.Model(&user). Column("user.*"). Relation("Profiles", func(q *pg.Query) (*pg.Query, error) { return q.Where("active IS TRUE"), nil }). First() if err != nil { panic(err) } fmt.Println(user.Id, user.Name, user.Profiles[0], user.Profiles[1]) } { type Item struct { Id int Items []Item `pg:"rel:has-many,join_fk:parent_id"` ParentId int } db := connect() defer db.Close() qs := []string{ "CREATE TEMP TABLE items (id int, parent_id int)", "INSERT INTO items VALUES (1, NULL), (2, 1), (3, 1)", } for _, q := range qs { _, err := db.Exec(q) if err != nil { panic(err) } } var item Item err := db.Model(&item).Column("item.*").Relation("Items").First() if err != nil { panic(err) } fmt.Println("Item", item.Id) fmt.Println("Subitems", item.Items[0].Id, item.Items[1].Id) } { type Profile struct { Id int Lang string } // User has one profile. type User struct { Id int Name string ProfileId int Profile *Profile `pg:"rel:has-one"` } db := connect() defer db.Close() qs := []string{ "CREATE TEMP TABLE users (id int, name text, profile_id int)", "CREATE TEMP TABLE profiles (id int, lang text)", "INSERT INTO users VALUES (1, 'user 1', 1), (2, 'user 2', 2)", "INSERT INTO profiles VALUES (1, 'en'), (2, 'ru')", } for _, q := range qs { _, err := db.Exec(q) if err != nil { panic(err) } } var users []User err := db.Model(&users). Column("user.*"). Relation("Profile"). Select() if err != nil { panic(err) } fmt.Println(len(users), "results") fmt.Println(users[0].Id, users[0].Name, users[0].Profile) fmt.Println(users[1].Id, users[1].Name, users[1].Profile) } { type Item struct { Id int64 Attrs map[string]string `pg:",hstore"` // marshalled as PostgreSQL hstore } _, err := pgdb.Exec(`CREATE TEMP TABLE items (id serial, attrs hstore)`) if err != nil { panic(err) } defer pgdb.Exec("DROP TABLE items") item1 := Item{ Id: 1, Attrs: map[string]string{"hello": "world"}, } _, err = pgdb.Model(&item1).Insert() if err != nil { panic(err) } var item Item err = pgdb.Model(&item).Where("id = ?", 1).Select() if err != nil { panic(err) } fmt.Println(item) } { db := modelDB() book := &Book{ Title: "new book", AuthorID: 1, } _, err := db.Model(book).Insert() if err != nil { panic(err) } fmt.Println(book) _, err = db.Model(book).WherePK().Delete() if err != nil { panic(err) } } { type NamelessModel struct { tableName struct{} `pg:"_"` // "_" means no name Id int } db := modelDB() err := db.Model((*NamelessModel)(nil)).Table("dynamic_name").CreateTable(nil) panicIf(err) row123 := &NamelessModel{ Id: 123, } _, err = db.Model(row123).Table("dynamic_name").Insert() panicIf(err) row := new(NamelessModel) err = db.Model(row).Table("dynamic_name").First() panicIf(err) fmt.Println("id is", row.Id) err = db.Model((*NamelessModel)(nil)).Table("dynamic_name").DropTable(nil) panicIf(err) } { db := modelDB() book := &Book{ ID: 100, Title: "book 100", } for i := 0; i < 2; i++ { res, err := db.Model(book).OnConflict("DO NOTHING").Insert() if err != nil { panic(err) } if res.RowsAffected() > 0 { fmt.Println("created") } else { fmt.Println("did nothing") } } _, err := db.Model(book).WherePK().Delete() if err != nil { panic(err) } } { db := modelDB() var book *Book for i := 0; i < 2; i++ { book = &Book{ ID: 100, Title: fmt.Sprintf("title version #%d", i), } _, err := db.Model(book). OnConflict("(id) DO UPDATE"). Set("title = EXCLUDED.title"). Insert() if err != nil { panic(err) } err = db.Model(book).WherePK().Select() if err != nil { panic(err) } fmt.Println(book) } _, err := db.Model(book).WherePK().Delete() if err != nil { panic(err) } } package main import ( "fmt" "github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10/orm" ) func init() { // Register many to many model so ORM can better recognize m2m relation. // This should be done before dependant models are used. orm.RegisterTable((*OrderToItem)(nil)) } type Order struct { Id int Items []Item `pg:"many2many:order_to_items"` } type Item struct { Id int } type OrderToItem struct { OrderId int ItemId int } func main() { db := connect() defer db.Close() if err := createManyToManyTables(db); err != nil { panic(err) } values := []interface{}{ &Item{Id: 1}, &Item{Id: 2}, &Order{Id: 1}, &OrderToItem{OrderId: 1, ItemId: 1}, &OrderToItem{OrderId: 1, ItemId: 2}, } for _, v := range values { _, err := db.Model(v).Insert() if err != nil { panic(err) } } // Select order and all items with following queries: // // SELECT "order"."id" FROM "orders" AS "order" ORDER BY "order"."id" LIMIT 1 // // SELECT order_to_items.*, "item"."id" FROM "items" AS "item" // JOIN order_to_items AS order_to_items ON (order_to_items."order_id") IN (1) // WHERE ("item"."id" = order_to_items."item_id") order := new(Order) err := db.Model(order).Relation("Items").First() if err != nil { panic(err) } fmt.Println("Order", order.Id, "Items", order.Items[0].Id, order.Items[1].Id) // Select order and all items sorted by id with following queries: // // SELECT "order"."id" FROM "orders" AS "order" ORDER BY "order"."id" LIMIT 1 // // SELECT order_to_items.*, "item"."id" FROM "items" AS "item" // JOIN order_to_items AS order_to_items ON (order_to_items."order_id") IN (1) // WHERE ("item"."id" = order_to_items."item_id") // ORDER BY item.id DESC order = new(Order) err = db.Model(order). Relation("Items", func(q *pg.Query) (*pg.Query, error) { q = q.OrderExpr("item.id DESC") return q, nil }). First() if err != nil { panic(err) } fmt.Println("Order", order.Id, "Items", order.Items[0].Id, order.Items[1].Id) } func createManyToManyTables(db *pg.DB) error { models := []interface{}{ (*Order)(nil), (*Item)(nil), (*OrderToItem)(nil), } for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ Temp: true, }) if err != nil { return err } } return nil } package main import ( "fmt" "github.com/go-pg/pg/v10" "github.com/go-pg/pg/v10/orm" ) func init() { // Register many to many model so ORM can better recognize m2m relation. // This should be done before dependant models are used. orm.RegisterTable((*ElemToElem)(nil)) } type Elem struct { Id int Elems []Elem `pg:"many2many:elem_to_elems,join_fk:sub_id"` } type ElemToElem struct { ElemId int SubId int } func createManyToManySefTables(db *pg.DB) error { models := []interface{}{ (*Elem)(nil), (*ElemToElem)(nil), } for _, model := range models { err := db.Model(model).CreateTable(&orm.CreateTableOptions{ Temp: true, }) if err != nil { return err } } return nil } func main() { db := connect() defer db.Close() if err := createManyToManySefTables(db); err != nil { panic(err) } values := []interface{}{ &Elem{Id: 1}, &Elem{Id: 2}, &Elem{Id: 3}, &ElemToElem{ElemId: 1, SubId: 2}, &ElemToElem{ElemId: 1, SubId: 3}, } for _, v := range values { _, err := db.Model(v).Insert() if err != nil { panic(err) } } // Select elem and all subelems with following queries: // // SELECT "elem"."id" FROM "elems" AS "elem" ORDER BY "elem"."id" LIMIT 1 // // SELECT elem_to_elems.*, "elem"."id" FROM "elems" AS "elem" // JOIN elem_to_elems AS elem_to_elems ON (elem_to_elems."elem_id") IN (1) // WHERE ("elem"."id" = elem_to_elems."sub_id") elem := new(Elem) err := db.Model(elem).Relation("Elems").First() if err != nil { panic(err) } fmt.Println("Elem", elem.Id) fmt.Println("Subelems", elem.Elems[0].Id, elem.Elems[1].Id) } { type Example struct { Hello string } var str sql.NullString _, err := pgdb.QueryOne(pg.Scan(&str), "SELECT ?hello", &Example{Hello: ""}) if err != nil { panic(err) } fmt.Println(str.Valid) } { type Item struct { Id int64 Emails []string `pg:",array"` // marshalled as PostgreSQL array Numbers [][]int `pg:",array"` // marshalled as PostgreSQL array } _, err := pgdb.Exec(`CREATE TEMP TABLE items (id serial, emails text[], numbers int[][])`) panicIf(err) defer pgdb.Exec("DROP TABLE items") item1 := &Item{ Id: 1, Emails: []string{"one@example.com", "two@example.com"}, Numbers: [][]int{{1, 2}, {3, 4}}, } _, err = pgdb.Model(item1).Insert() panicIf(err) item := new(Item) err = pgdb.Model(item).Where("id = ?", 1).Select() panicIf(err) fmt.Println(item) } { db := modelDB() book := &Book{ ID: 1, } err := db.Model(book).WherePK().Select() if err != nil { panic(err) } fmt.Println(book) } { db := modelDB() var book Book err := db.Model(&book).Column("book.*").First() if err != nil { panic(err) } fmt.Println(book, book.AuthorID) } { db := modelDB() var books []Book count, err := db.Model(&books).OrderExpr("id ASC").Limit(2).SelectAndCount() if err != nil { panic(err) } fmt.Println(count) fmt.Println(books) } { db := modelDB() var authorId int var editorId int filter := func(q *pg.Query) (*pg.Query, error) { if authorId != 0 { q = q.Where("author_id = ?", authorId) } if editorId != 0 { q = q.Where("editor_id = ?", editorId) } return q, nil } var books []Book authorId = 1 err := db.Model(&books). Apply(filter). Select() if err != nil { panic(err) } fmt.Println(books) } { db := modelDB() var firstBook Book err := db.Model(&firstBook).First() if err != nil { panic(err) } fmt.Println(firstBook) } { db := modelDB() var res []struct { AuthorId int BookCount int } err := db.Model(&Book{}). Column("author_id"). ColumnExpr("count(*) AS book_count"). Group("author_id"). OrderExpr("book_count DESC"). Select(&res) if err != nil { panic(err) } fmt.Println("len", len(res)) fmt.Printf("author %d has %d books\n", res[0].AuthorId, res[0].BookCount) fmt.Printf("author %d has %d books\n", res[1].AuthorId, res[1].BookCount) } { db := modelDB() var lastBook Book err := db.Model(&lastBook).Last() if err != nil { panic(err) } fmt.Println(lastBook) } { db := modelDB() author := Author{ Name: "R. Scott Bakker", } created, err := db.Model(&author). Column("id"). Where("name = ?name"). OnConflict("DO NOTHING"). Returning("id"). SelectOrInsert() if err != nil { panic(err) } fmt.Println(created, author) } { db := modelDB() var ids []int err := db.Model(&Book{}). ColumnExpr("array_agg(book.id)"). Select(pg.Array(&ids)) if err != nil { panic(err) } fmt.Println(ids) } { db := modelDB() var book Book err := db.Model(&book). Column("book.id", "book.title"). OrderExpr("book.id ASC"). Limit(1). Select() if err != nil { panic(err) } fmt.Println(book) } { db := modelDB() var id int var title string err := db.Model(&Book{}). Column("book.id", "book.title"). OrderExpr("book.id ASC"). Limit(1). Select(&id, &title) if err != nil { panic(err) } fmt.Println(id, title) } { db := modelDB() var books []Book err := db.Model(&books). WhereGroup(func(q *pg.Query) (*pg.Query, error) { q = q.WhereOr("id = 1"). WhereOr("id = 2") return q, nil }). Where("title IS NOT NULL"). Select() if err != nil { panic(err) } fmt.Println(books) } { db := modelDB() var books []Book err := db.Model(&books).WhereIn("id IN (?)", []int{1, 2}).Select() if err != nil { panic(err) } fmt.Println(books) } { authorBooks := pgdb.Model(&Book{}).Where("author_id = ?", 1) var books []Book err := pgdb.Model(). With("author_books", authorBooks). Table("author_books"). Select(&books) if err != nil { panic(err) } fmt.Println(books) } { // WITH author_books AS ( // SELECT * books WHERE author_id = 1 // ) // SELECT * FROM author_books var books []Book err := pgdb.Model(&books). Where("author_id = ?", 1). WrapWith("author_books"). Table("author_books"). Select(&books) if err != nil { panic(err) } fmt.Println(books) } { type Flight struct { Id int Name string DeletedAt time.Time `pg:",soft_delete"` } err := pgdb.Model((*Flight)(nil)).CreateTable(&orm.CreateTableOptions{ Temp: true, }) panicIf(err) flight1 := &Flight{ Id: 1, } _, err = pgdb.Model(flight1).Insert() panicIf(err) _, err = pgdb.Model(flight1).WherePK().Delete() panicIf(err) count, err := pgdb.Model((*Flight)(nil)).Count() panicIf(err) fmt.Println("count", count) deletedCount, err := pgdb.Model((*Flight)(nil)).Deleted().Count() panicIf(err) fmt.Println("deleted count", deletedCount) _, err = pgdb.Model(flight1).WherePK().ForceDelete() panicIf(err) deletedCount, err = pgdb.Model((*Flight)(nil)).Deleted().Count() panicIf(err) fmt.Println("deleted count", deletedCount) } package main import ( "fmt" "time" "github.com/go-pg/pg/v10/types" ) type CustomTime struct { Time time.Time } var _ types.ValueScanner = (*CustomTime)(nil) func (tm *CustomTime) ScanValue(rd types.Reader, n int) error { var err error tm.Time, err = types.ScanTime(rd, n) return err } var _ types.ValueAppender = (*CustomTime)(nil) func (tm *CustomTime) AppendValue(b []byte, flags int) ([]byte, error) { return types.AppendTime(b, tm.Time, flags), nil } type Video struct { Id int Name string DeletedAt CustomTime `pg:",soft_delete"` } func main() { video1 := &Video{ Id: 1, } _, err := pgdb.Model(video1).Insert() panicIf(err) // Soft delete. _, err = pgdb.Model(video1).WherePK().Delete() panicIf(err) // Count visible videos. count, err := pgdb.Model((*Video)(nil)).Count() panicIf(err) fmt.Println("count", count) // Count soft deleted videos. deletedCount, err := pgdb.Model((*Video)(nil)).Deleted().Count() panicIf(err) fmt.Println("deleted count", deletedCount) // Actually delete the video. _, err = pgdb.Model(video1).WherePK().ForceDelete() panicIf(err) // Count soft deleted videos. deletedCount, err = pgdb.Model((*Video)(nil)).Deleted().Count() panicIf(err) fmt.Println("deleted count", deletedCount) } { db := modelDB() book := &Book{ID: 1} err := db.Model(book).WherePK().Select() if err != nil { panic(err) } book.Title = "updated book 1" _, err = db.Model(book).WherePK().Update() if err != nil { panic(err) } err = db.Model(book).WherePK().Select() if err != nil { panic(err) } fmt.Println(book) } { db := modelDB() book := &Book{ ID: 1, Title: "updated book 1", } _, err := db.Model(book).WherePK().UpdateNotZero() if err != nil { panic(err) } book = new(Book) err = db.Model(book).Where("id = ?", 1).Select() if err != nil { panic(err) } fmt.Println(book) } { db := modelDB() var book Book _, err := db.Model(&book). Set("title = concat(?, title, ?)", "prefix ", " suffix"). Where("id = ?", 1). Returning("*"). Update() if err != nil { panic(err) } fmt.Println(book) } { db := modelDB() book := Book{ ID: 1, Title: "updated book 1", AuthorID: 2, } _, err := db.Model(&book).Column("title").WherePK().Returning("*").Update() if err != nil { panic(err) } fmt.Println(book, book.AuthorID) } { db := modelDB() book := Book{ ID: 1, Title: "updated book 1", AuthorID: 2, } _, err := db.Model(&book).Set("title = ?title").WherePK().Returning("*").Update() if err != nil { panic(err) } fmt.Println(book, book.AuthorID) } { type Event struct { ID int Active bool `pg:",use_zero"` } db := pg.Connect(pgOptions()) defer db.Close() err := db.Model((*Event)(nil)).CreateTable(&orm.CreateTableOptions{ Temp: true, }) if err != nil { panic(err) } event := &Event{ ID: 1, Active: true, } _, err = db.Model(event).Insert() if err != nil { panic(err) } fmt.Println(event) event.Active = false _, err = db.Model(event).WherePK().UpdateNotZero() if err != nil { panic(err) } event2 := new(Event) err = db.Model(event2).Where("id = ?", 1).Select() if err != nil { panic(err) } fmt.Println(event2) } { stmt, err := pgdb.Prepare(`SELECT $1::text, $2::text`) panicIf(err) var s1, s2 string _, err = stmt.QueryOne(pg.Scan(&s1, &s2), "foo", "bar") panicIf(err) fmt.Println(s1, s2) } package main import ( "fmt" "github.com/go-pg/pg/v10" ) func CreateUser(db *pg.DB, user *User) error { _, err := db.QueryOne(user, ` INSERT INTO users (name, emails) VALUES (?name, ?emails) RETURNING id `, user) return err } func GetUser(db *pg.DB, id int64) (*User, error) { var user User _, err := db.QueryOne(&user, `SELECT * FROM users WHERE id = ?`, id) return &user, err } func GetUsers(db *pg.DB) ([]User, error) { var users []User _, err := db.Query(&users, `SELECT * FROM users`) return users, err } func GetUsersByIds(db *pg.DB, ids []int64) ([]User, error) { var users []User _, err := db.Query(&users, `SELECT * FROM users WHERE id IN (?)`, pg.In(ids)) return users, err } func CreateStory(db *pg.DB, story *Story) error { _, err := db.QueryOne(story, ` INSERT INTO stories (title, author_id) VALUES (?title, ?author_id) RETURNING id `, story) return err } // GetStory returns story with associated author. func GetStory(db *pg.DB, id int64) (*Story, error) { var story Story _, err := db.QueryOne(&story, ` SELECT s.*, u.id AS author__id, u.name AS author__name, u.emails AS author__emails FROM stories AS s, users AS u WHERE s.id = ? AND u.id = s.author_id `, id) return &story, err } func main() { db := pg.Connect(&pg.Options{ User: "postgres", Password: "postgres", }) err := createSchema(db) panicIf(err) user1 := &User{ Name: "admin", Emails: []string{"admin1@admin", "admin2@admin"}, } err = CreateUser(db, user1) panicIf(err) err = CreateUser(db, &User{ Name: "root", Emails: []string{"root1@root", "root2@root"}, }) panicIf(err) story1 := &Story{ Title: "Cool story", AuthorId: user1.Id, } err = CreateStory(db, story1) panicIf(err) user, err := GetUser(db, user1.Id) panicIf(err) users, err := GetUsers(db) panicIf(err) story, err := GetStory(db, story1.Id) panicIf(err) fmt.Println(user) fmt.Println(users) fmt.Println(story) } { var user struct { Name string } res, err := pgdb.QueryOne(&user, ` WITH users (name) AS (VALUES (?)) SELECT * FROM users `, "admin") panicIf(err) fmt.Println(res.RowsAffected()) fmt.Println(user) } { _, err := pgdb.Exec(`CREATE TEMP TABLE users(id serial, name varchar(500))`) panicIf(err) var user struct { Id int32 Name string } user.Name = "admin" _, err = pgdb.QueryOne(&user, ` INSERT INTO users (name) VALUES (?name) RETURNING id `, &user) panicIf(err) fmt.Println(user) } { db := txExample() incrInTx := func(db *pg.DB) error { return db.RunInTransaction(ctx, func(tx *pg.Tx) error { var counter int _, err := tx.QueryOne( pg.Scan(&counter), `SELECT counter FROM tx_test FOR UPDATE`) if err != nil { return err } counter++ _, err = tx.Exec(`UPDATE tx_test SET counter = ?`, counter) return err }) } var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() err := incrInTx(db) panicIf(err) }() } wg.Wait() var counter int _, err := db.QueryOne(pg.Scan(&counter), `SELECT counter FROM tx_test`) panicIf(err) fmt.Println(counter) } { var count int _, err := pgdb.WithTimeout(time.Minute).QueryOne(pg.Scan(&count), ` SELECT count(*) FROM big_table `) panicIf(err) } { var dst MyArrayValueScanner _, err := pgdb.QueryOne(pg.Scan(pg.Array(&dst)), `SELECT array_agg(id) from generate_series(0, 10) AS id`) panicIf(err) fmt.Println(dst.sum) } { type Event struct { Id int Data map[string]interface{} `pg:",json_use_number"` } db := pg.Connect(pgOptions()) defer db.Close() err := db.Model((*Event)(nil)).CreateTable(&orm.CreateTableOptions{ Temp: true, }) if err != nil { panic(err) } event := &Event{ Data: map[string]interface{}{ "price": 1.23, }, } _, err = db.Model(event).Insert() if err != nil { panic(err) } event2 := new(Event) err = db.Model(event2).Where("id = ?", event.Id).Select() if err != nil { panic(err) } fmt.Printf("%T", event2.Data["price"]) } { video := &Video{ Id: 123, } _, err := pgdb.Model(video).Insert() panicIf(err) _, err = pgdb.Model(video).Insert() if err != nil { pgErr, ok := err.(pg.Error) if ok && pgErr.IntegrityViolation() { fmt.Println("video already exists:", err) } else if pgErr.Field('S') == "PANIC" { panic(err) } } } { src := map[string]string{"hello": "world"} var dst map[string]string _, err := pgdb.QueryOne(pg.Scan(pg.Hstore(&dst)), `SELECT ?`, pg.Hstore(src)) if err != nil { panic(err) } fmt.Println(dst) } { db := modelDB() var book Book err := db.Model(&book).Where("? = 1", pg.Ident("id")).Select() if err != nil { panic(err) } fmt.Println(book) } { var nums pg.Ints _, err := pgdb.Query(&nums, `SELECT generate_series(0, 10)`) panicIf(err) fmt.Println(nums) } { ln := pgdb.Listen(ctx, "mychan") defer ln.Close() ch := ln.Channel() go func() { time.Sleep(time.Millisecond) _, err := pgdb.Exec("NOTIFY mychan, ?", "hello world") panicIf(err) }() notif := <-ch fmt.Println(notif) } { db := modelDB() cond := fmt.Sprintf("id = %d", 1) var book Book err := db.Model(&book).Where("?", pg.Safe(cond)).Select() if err != nil { panic(err) } fmt.Println(book) } { var s1, s2 string _, err := pgdb.QueryOne(pg.Scan(&s1, &s2), `SELECT ?, ?`, "foo", "bar") panicIf(err) fmt.Println(s1, s2) } { var strs pg.Strings _, err := pgdb.Query(&strs, ` WITH users AS (VALUES ('foo'), ('bar')) SELECT * FROM users `) panicIf(err) fmt.Println(strs) } package main import ( "fmt" "github.com/go-pg/pg/v10" ) type Params struct { X int Y int } func (p *Params) Sum() int { return p.X + p.Y } // go-pg recognizes `?` in queries as placeholders and replaces them // with parameters when queries are executed. `?` can be escaped with backslash. // Parameters are escaped before replacing according to PostgreSQL rules. // Specifically: // - all parameters are properly quoted against SQL injections; // - null byte is removed; // - JSON/JSONB gets `\u0000` escaped as `\\u0000`. func main() { var num int // Simple params. _, err := pgdb.Query(pg.Scan(&num), "SELECT ?", 42) if err != nil { panic(err) } fmt.Println("simple:", num) // Indexed params. _, err = pgdb.Query(pg.Scan(&num), "SELECT ?0 + ?0", 1) if err != nil { panic(err) } fmt.Println("indexed:", num) // Named params. params := &Params{ X: 1, Y: 1, } _, err = pgdb.Query(pg.Scan(&num), "SELECT ?x + ?y + ?Sum", params) if err != nil { panic(err) } fmt.Println("named:", num) // Global params. _, err = pgdb.WithParam("z", 1).Query(pg.Scan(&num), "SELECT ?x + ?y + ?z", params) if err != nil { panic(err) } fmt.Println("global:", num) // Model params. var tableName, tableAlias, tableColumns, columns string _, err = pgdb.Model(&Params{}).Query( pg.Scan(&tableName, &tableAlias, &tableColumns, &columns), "SELECT '?TableName', '?TableAlias', '?TableColumns', '?Columns'", ) if err != nil { panic(err) } fmt.Println("table name:", tableName) fmt.Println("table alias:", tableAlias) fmt.Println("table columns:", tableColumns) fmt.Println("columns:", columns) }
Package-Level Type Names (total 34, in which 29 are exported)
/* sort exporteds by: | */
Conn represents a single database connection rather than a pool of database connections. Prefer running queries from DB unless there is a specific need for a continuous single database connection. A Conn must call Close to return the connection to the database pool and may do so concurrently with a running query. After a call to Close, all operations on the connection fail. AddQueryHook adds a hook into query processing. Begin starts a transaction. Most callers should use RunInTransaction instead. ( Conn) BeginContext(ctx context.Context) (*Tx, error) Close closes the database client, releasing any open resources. It is rare to Close a DB, as the DB handle is meant to be long-lived and shared between many goroutines. Context returns DB context. CopyFrom copies data from reader to a table. CopyTo copies data from a table to writer. Exec executes a query ignoring returned rows. The params are for any placeholders in the query. ( Conn) ExecContext(c context.Context, query interface{}, params ...interface{}) (Result, error) ExecOne acts like Exec, but query must affect only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows. ( Conn) ExecOneContext(ctx context.Context, query interface{}, params ...interface{}) (Result, error) ( Conn) Formatter() orm.QueryFormatter Model returns new query for the model. ( Conn) ModelContext(c context.Context, model ...interface{}) *Query Param returns value for the param. Ping verifies a connection to the database is still alive, establishing a connection if necessary. PoolStats returns connection pool stats. Prepare creates a prepared statement for later queries or executions. Multiple queries or executions may be run concurrently from the returned statement. Query executes a query that returns rows, typically a SELECT. The params are for any placeholders in the query. ( Conn) QueryContext(c context.Context, model, query interface{}, params ...interface{}) (Result, error) QueryOne acts like Query, but query must return only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows. ( Conn) QueryOneContext(ctx context.Context, model, query interface{}, params ...interface{}) (Result, error) RunInTransaction runs a function in a transaction. If function returns an error transaction is rolled back, otherwise transaction is committed. WithContext returns a copy of the DB that uses the ctx. WithParam returns a copy of the DB that replaces the param with the value in queries. WithTimeout returns a copy of the DB that uses d as the read/write timeout. Conn : DBI *Conn : github.com/go-pg/pg/v10/orm.DB *Conn : github.com/go-pg/migrations/v8.DB Conn : database/sql/driver.Pinger Conn : io.Closer func (*Conn).WithContext(ctx context.Context) *Conn func (*Conn).WithParam(param string, value interface{}) *Conn func (*Conn).WithTimeout(d time.Duration) *Conn func (*DB).Conn() *Conn
DB is a database handle representing a pool of zero or more underlying connections. It's safe for concurrent use by multiple goroutines. AddQueryHook adds a hook into query processing. Begin starts a transaction. Most callers should use RunInTransaction instead. ( DB) BeginContext(ctx context.Context) (*Tx, error) Close closes the database client, releasing any open resources. It is rare to Close a DB, as the DB handle is meant to be long-lived and shared between many goroutines. Conn returns a single connection from the connection pool. Queries run on the same Conn will be run in the same database session. Every Conn must be returned to the database pool after use by calling Conn.Close. Context returns DB context. CopyFrom copies data from reader to a table. CopyTo copies data from a table to writer. Exec executes a query ignoring returned rows. The params are for any placeholders in the query. ( DB) ExecContext(c context.Context, query interface{}, params ...interface{}) (Result, error) ExecOne acts like Exec, but query must affect only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows. ( DB) ExecOneContext(ctx context.Context, query interface{}, params ...interface{}) (Result, error) ( DB) Formatter() orm.QueryFormatter Listen listens for notifications sent with NOTIFY command. Model returns new query for the model. ( DB) ModelContext(c context.Context, model ...interface{}) *Query Options returns read-only Options that were used to connect to the DB. Param returns value for the param. Ping verifies a connection to the database is still alive, establishing a connection if necessary. PoolStats returns connection pool stats. Prepare creates a prepared statement for later queries or executions. Multiple queries or executions may be run concurrently from the returned statement. Query executes a query that returns rows, typically a SELECT. The params are for any placeholders in the query. ( DB) QueryContext(c context.Context, model, query interface{}, params ...interface{}) (Result, error) QueryOne acts like Query, but query must return only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows. ( DB) QueryOneContext(ctx context.Context, model, query interface{}, params ...interface{}) (Result, error) RunInTransaction runs a function in a transaction. If function returns an error transaction is rolled back, otherwise transaction is committed. (*DB) String() string WithContext returns a copy of the DB that uses the ctx. WithParam returns a copy of the DB that replaces the param with the value in queries. WithTimeout returns a copy of the DB that uses d as the read/write timeout. DB : DBI *DB : github.com/go-pg/pg/v10/orm.DB *DB : github.com/go-pg/migrations/v8.DB DB : database/sql/driver.Pinger *DB : expvar.Var *DB : fmt.Stringer DB : io.Closer func Connect(opt *Options) *DB func (*DB).WithContext(ctx context.Context) *DB func (*DB).WithParam(param string, value interface{}) *DB func (*DB).WithTimeout(d time.Duration) *DB
DBI is a DB interface implemented by *DB and *Tx. ( DBI) Begin() (*Tx, error) ( DBI) CopyFrom(r io.Reader, query interface{}, params ...interface{}) (Result, error) ( DBI) CopyTo(w io.Writer, query interface{}, params ...interface{}) (Result, error) ( DBI) Exec(query interface{}, params ...interface{}) (Result, error) ( DBI) ExecContext(c context.Context, query interface{}, params ...interface{}) (Result, error) ( DBI) ExecOne(query interface{}, params ...interface{}) (Result, error) ( DBI) ExecOneContext(c context.Context, query interface{}, params ...interface{}) (Result, error) ( DBI) Model(model ...interface{}) *Query ( DBI) ModelContext(c context.Context, model ...interface{}) *Query ( DBI) Query(model, query interface{}, params ...interface{}) (Result, error) ( DBI) QueryContext(c context.Context, model, query interface{}, params ...interface{}) (Result, error) ( DBI) QueryOne(model, query interface{}, params ...interface{}) (Result, error) ( DBI) QueryOneContext(c context.Context, model, query interface{}, params ...interface{}) (Result, error) ( DBI) RunInTransaction(ctx context.Context, fn func(*Tx) error) error Conn DB *Tx
Error represents an error returned by PostgreSQL server using PostgreSQL ErrorResponse protocol. https://www.postgresql.org/docs/10/static/protocol-message-formats.html ( Error) Error() builtin.string Field returns a string value associated with an error field. https://www.postgresql.org/docs/10/static/protocol-error-fields.html IntegrityViolation reports whether an error is a part of Integrity Constraint Violation class of errors. https://www.postgresql.org/docs/10/static/errcodes-appendix.html github.com/go-pg/pg/v10/internal.PGError Error : error
Ident represents a SQL identifier, e.g. table or column name.
Ints is a type alias for a slice of int64 values. AddColumnScanner ... AppendValue appends the values from `ints` to the given byte slice. Init initializes the Int slice. NewColumnScanner ... ScanColumn scans the columns and appends them to `ints`. *Ints : github.com/go-pg/pg/v10/orm.ColumnScanner *Ints : github.com/go-pg/pg/v10/orm.HooklessModel Ints : github.com/go-pg/pg/v10/types.ValueAppender
IntSet is a set of int64 values. AddColumnScanner ... Init initializes the IntSet. NextColumnScanner ... ScanColumn scans the columns and appends them to `IntSet`. *IntSet : github.com/go-pg/pg/v10/orm.ColumnScanner *IntSet : github.com/go-pg/pg/v10/orm.HooklessModel
Listener listens for notifications sent with NOTIFY command. It's NOT safe for concurrent use by multiple goroutines except the Channel API. Channel returns a channel for concurrently receiving notifications. It periodically sends Ping notification to test connection health. The channel is closed with Listener. Receive* APIs can not be used after channel is created. ChannelSize is like Channel, but creates a Go channel with specified buffer size. Close closes the listener, releasing any open resources. Listen starts listening for notifications on channels. Receive indefinitely waits for a notification. This is low-level API and in most cases Channel should be used instead. ReceiveTimeout waits for a notification until timeout is reached. This is low-level API and in most cases Channel should be used instead. (*Listener) String() string Unlisten stops listening for notifications on channels. *Listener : expvar.Var *Listener : fmt.Stringer *Listener : io.Closer func (*DB).Listen(ctx context.Context, channels ...string) *Listener
Notification which is received with LISTEN command. Channel string Payload string func (*Listener).Channel() <-chan Notification func (*Listener).ChannelSize(size int) <-chan Notification
NullTime is a time.Time wrapper that marshals zero time as JSON null and PostgreSQL NULL.
Options contains database connection options. TCP host:port or Unix socket depending on Network. ApplicationName is the application name. Used in logs on Pg side. Only available from pg-9.0. Database string Dial timeout for establishing new connections. Default is 5 seconds. Dialer creates new network connection and has priority over Network and Addr options. Frequency of idle checks made by idle connections reaper. Default is 1 minute. -1 disables idle connections reaper, but idle connections are still discarded by the client if IdleTimeout is set. Amount of time after which client closes idle connections. Should be less than server's timeout. Default is 5 minutes. -1 disables idle timeout check. Connection age at which client retires (closes) the connection. It is useful with proxies like PgBouncer and HAProxy. Default is to not close aged connections. Maximum number of retries before giving up. Default is to not retry failed queries. Maximum backoff between each retry. Default is 4 seconds; -1 disables backoff. Minimum number of idle connections which is useful when establishing new connection is slow. Minimum backoff between each retry. Default is 250 milliseconds; -1 disables backoff. Network type, either tcp or unix. Default is tcp. Hook that is called after new connection is established and user is authenticated. Password string Maximum number of socket connections. Default is 10 connections per every CPU as reported by runtime.NumCPU. Time for which client waits for free connection if all connections are busy before returning an error. Default is 30 seconds if ReadTimeOut is not defined, otherwise, ReadTimeout + 1 second. Timeout for socket reads. If reached, commands will fail with a timeout instead of blocking. Whether to retry queries cancelled because of statement_timeout. TLS config for secure connections. User string Timeout for socket writes. If reached, commands will fail with a timeout instead of blocking. func ParseURL(sURL string) (*Options, error) func (*DB).Options() *Options func Connect(opt *Options) *DB
PoolStats contains the stats of a connection pool. // number of times free connection was found in the pool // number of idle connections in the pool // number of times free connection was NOT found in the pool // number of stale connections removed from the pool // number of times a wait timeout occurred // number of total connections in the pool
type Query = orm.Query (struct)
QueryEvent ... DB orm.DB Err error Model interface{} Params []interface{} Query interface{} Result Result StartTime time.Time Stash map[interface{}]interface{} FormattedQuery returns the formatted query of a query event. The query is only valid until the query Result is returned to the user. UnformattedQuery returns the unformatted query of a query event. The query is only valid until the query Result is returned to the user. func QueryHook.AfterQuery(context.Context, *QueryEvent) error func QueryHook.BeforeQuery(context.Context, *QueryEvent) (context.Context, error)
QueryHook ... ( QueryHook) AfterQuery(context.Context, *QueryEvent) error ( QueryHook) BeforeQuery(context.Context, *QueryEvent) (context.Context, error)
Result summarizes an executed SQL command.
Safe represents a safe SQL query.
Stmt is a prepared statement. Stmt is safe for concurrent use by multiple goroutines. Close closes the statement. Exec executes a prepared statement with the given parameters. ExecContext executes a prepared statement with the given parameters. ExecOne acts like Exec, but query must affect only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows. ExecOneContext acts like ExecOne but additionally receives a context. Query executes a prepared query statement with the given parameters. QueryContext acts like Query but additionally receives a context. QueryOne acts like Query, but query must return only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows. QueryOneContext acts like QueryOne but additionally receives a context. *Stmt : io.Closer func (*Tx).Prepare(q string) (*Stmt, error) func (*Tx).Stmt(stmt *Stmt) *Stmt func (*Tx).Stmt(stmt *Stmt) *Stmt
Strings is a type alias for a slice of strings. AddColumnScanner ... AppendValue appends the values from `strings` to the given byte slice. Init initializes the Strings slice. NextColumnScanner ... ScanColumn scans the columns and appends them to `strings`. *Strings : github.com/go-pg/pg/v10/orm.ColumnScanner *Strings : github.com/go-pg/pg/v10/orm.HooklessModel Strings : github.com/go-pg/pg/v10/types.ValueAppender
Tx is an in-progress database transaction. It is safe for concurrent use by multiple goroutines. A transaction must end with a call to Commit or Rollback. After a call to Commit or Rollback, all operations on the transaction fail with ErrTxDone. The statements prepared for a transaction by calling the transaction's Prepare or Stmt methods are closed by the call to Commit or Rollback. Begin returns current transaction. It does not start new transaction. (*Tx) Close() error Close calls Rollback if the tx has not already been committed or rolled back. (*Tx) Commit() error Commit commits the transaction. Context returns the context.Context of the transaction. CopyFrom is an alias for DB.CopyFrom. CopyTo is an alias for DB.CopyTo. Exec is an alias for DB.Exec. ExecContext acts like Exec but additionally receives a context. ExecOne is an alias for DB.ExecOne. ExecOneContext acts like ExecOne but additionally receives a context. Formatter is an alias for DB.Formatter. Model is an alias for DB.Model. ModelContext acts like Model but additionally receives a context. Prepare creates a prepared statement for use within a transaction. The returned statement operates within the transaction and can no longer be used once the transaction has been committed or rolled back. To use an existing prepared statement on this transaction, see Tx.Stmt. Query is an alias for DB.Query. QueryContext acts like Query but additionally receives a context. QueryOne is an alias for DB.QueryOne. QueryOneContext acts like QueryOne but additionally receives a context. (*Tx) Rollback() error Rollback aborts the transaction. RunInTransaction runs a function in the transaction. If function returns an error transaction is rolled back, otherwise transaction is committed. Stmt returns a transaction-specific prepared statement from an existing statement. *Tx : DBI *Tx : github.com/go-pg/pg/v10/orm.DB *Tx : github.com/go-pg/migrations/v8.DB *Tx : database/sql/driver.Tx *Tx : io.Closer func DBI.Begin() (*Tx, error) func (*Tx).Begin() (*Tx, error) func github.com/go-pg/migrations/v8.DB.Begin() (*Tx, error)
Package-Level Functions (total 60, in which 12 are exported)
Array accepts a slice and returns a wrapper for working with PostgreSQL array data type. For struct fields you can use array tag: Emails []string `pg:",array"`
Connect connects to a database using provided options. The returned DB is safe for concurrent use by multiple goroutines and maintains its own connection pool.
Hstore accepts a map and returns a wrapper for working with hstore data type. Supported map types are: - map[string]string For struct fields you can use hstore tag: Attrs map[string]string `pg:",hstore"`
In accepts a slice and returns a wrapper that can be used with PostgreSQL IN operator: Where("id IN (?)", pg.In([]int{1, 2, 3, 4})) produces WHERE id IN (1, 2, 3, 4)
InMulti accepts multiple values and returns a wrapper that can be used with PostgreSQL IN operator: Where("(id1, id2) IN (?)", pg.InMulti([]int{1, 2}, []int{3, 4})) produces WHERE (id1, id2) IN ((1, 2), (3, 4))
Model returns a new query for the optional model.
ModelContext returns a new query for the optional model with a context.
ParseURL parses an URL into options that can be used to connect to PostgreSQL.
SafeQuery replaces any placeholders found in the query.
Scan returns ColumnScanner that copies the columns in the row into the values.
SetLogger sets the logger to the given one.
Version is the current release version.
Package-Level Variables (total 9, in which 4 are exported)
Discard is used with Query and QueryOne to discard rows.
ErrMultiRows is returned by QueryOne and ExecOne when query returned multiple rows but exactly one row is expected.
ErrNoRows is returned by QueryOne and ExecOne when query returned zero rows but at least one row is expected.
ErrTxDone is returned by any operation that is performed on a transaction that has already been committed or rolled back.
Package-Level Constants (total 39, none are exported)