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
Array
{
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)
}
Connect
{
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_Begin
{
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)
}
DB_CopyFrom
{
_, 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())
}
DB_Exec
{
res, err := pgdb.Exec(`CREATE TEMP TABLE test()`)
panicIf(err)
fmt.Println(res.RowsAffected())
}
DB_Model
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
}
DB_Model_belongsTo
{
// 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_Model_bulkDelete
{
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_Model_bulkInsert
{
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_Model_bulkInsertSlice
{
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_Model_bulkUpdate
{
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_Model_bulkUpdateSlice
{
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)
}
DB_Model_compositeType
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_Model_count
{
db := modelDB()
count, err := db.Model(&Book{}).Count()
if err != nil {
panic(err)
}
fmt.Println(count)
}
DB_Model_countEstimate
{
db := modelDB()
count, err := db.Model(&Book{}).CountEstimate(0)
if err != nil {
panic(err)
}
fmt.Println(count)
}
DB_Model_createTable
{
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)
}
DB_Model_customType
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_Model_delete
{
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_Model_deleteMultipleRows
{
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)
}
DB_Model_discardUnknownColumns
{
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_Model_exists
{
db := modelDB()
var books []Book
exists, err := db.Model(&books).Where("author_id = ?", 1).Exists()
if err != nil {
panic(err)
}
fmt.Println(exists)
}
DB_Model_forEach
{
err := pgdb.Model((*Book)(nil)).
OrderExpr("id ASC").
ForEach(func(b *Book) error {
fmt.Println(b)
return nil
})
if err != nil {
panic(err)
}
}
DB_Model_hasMany
{
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])
}
DB_Model_hasManySelf
{
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)
}
DB_Model_hasOne
{
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)
}
DB_Model_hstoreStructTag
{
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_Model_insert
{
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)
}
}
DB_Model_insertDynamicTableName
{
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_Model_insertOnConflictDoNothing
{
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_Model_insertOnConflictDoUpdate
{
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)
}
}
DB_Model_manyToMany
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
}
DB_Model_manyToManySelf
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)
}
DB_Model_nullEmptyValue
{
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)
}
DB_Model_postgresArrayStructTag
{
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_Model_select
{
db := modelDB()
book := &Book{
ID: 1,
}
err := db.Model(book).WherePK().Select()
if err != nil {
panic(err)
}
fmt.Println(book)
}
DB_Model_selectAllColumns
{
db := modelDB()
var book Book
err := db.Model(&book).Column("book.*").First()
if err != nil {
panic(err)
}
fmt.Println(book, book.AuthorID)
}
DB_Model_selectAndCount
{
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_Model_selectApplyFunc
{
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_Model_selectFirstRow
{
db := modelDB()
var firstBook Book
err := db.Model(&firstBook).First()
if err != nil {
panic(err)
}
fmt.Println(firstBook)
}
DB_Model_selectGroupBy
{
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_Model_selectLastRow
{
db := modelDB()
var lastBook Book
err := db.Model(&lastBook).Last()
if err != nil {
panic(err)
}
fmt.Println(lastBook)
}
DB_Model_selectOrInsert
{
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_Model_selectSQLExpression
{
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_Model_selectSomeColumns
{
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_Model_selectSomeColumnsIntoVars
{
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_Model_selectWhereGroup
{
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_Model_selectWhereIn
{
db := modelDB()
var books []Book
err := db.Model(&books).WhereIn("id IN (?)", []int{1, 2}).Select()
if err != nil {
panic(err)
}
fmt.Println(books)
}
DB_Model_selectWith
{
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)
}
DB_Model_selectWrapWith
{
// 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)
}
DB_Model_softDelete
{
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)
}
DB_Model_softDeleteCustom
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_Model_update
{
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_Model_updateNotZero
{
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_Model_updateSetValues
{
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_Model_updateSomeColumns
{
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_Model_updateSomeColumns2
{
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)
}
DB_Model_updateUseZeroBool
{
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)
}
DB_Prepare
{
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)
}
DB_Query
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)
}
DB_QueryOne
{
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)
}
DB_QueryOne_returning_id
{
_, 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_RunInTransaction
{
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)
}
DB_WithTimeout
{
var count int
_, err := pgdb.WithTimeout(time.Minute).QueryOne(pg.Scan(&count), `
SELECT count(*) FROM big_table
`)
panicIf(err)
}
DB_arrayValueScanner
{
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)
}
DB_jsonUseNumber
{
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"])
}
Error
{
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)
}
}
}
Hstore
{
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)
}
Ident
{
db := modelDB()
var book Book
err := db.Model(&book).Where("? = 1", pg.Ident("id")).Select()
if err != nil {
panic(err)
}
fmt.Println(book)
}
Ints
{
var nums pg.Ints
_, err := pgdb.Query(&nums, `SELECT generate_series(0, 10)`)
panicIf(err)
fmt.Println(nums)
}
Listener
{
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)
}
Safe
{
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)
}
Scan
{
var s1, s2 string
_, err := pgdb.QueryOne(pg.Scan(&s1, &s2), `SELECT ?, ?`, "foo", "bar")
panicIf(err)
fmt.Println(s1, s2)
}
Strings
{
var strs pg.Strings
_, err := pgdb.Query(&strs, `
WITH users AS (VALUES ('foo'), ('bar')) SELECT * FROM users
`)
panicIf(err)
fmt.Println(strs)
}
_placeholders
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: alphabet | popularity */
type Conn (struct)
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.
Fields (total 7, none are exported )
/* 7 unexporteds ... */ /* 7 unexporteds: */
baseDB *baseDB
baseDB .db orm .DB
baseDB .fmter *orm .Formatter
baseDB .opt *Options
baseDB .pool pool .Pooler
baseDB .queryHooks []QueryHook
ctx context .Context
Methods (total 55, in which 26 are exported )
( Conn) AddQueryHook (hook QueryHook )
AddQueryHook adds a hook into query processing.
( Conn) Begin () (*Tx , error )
Begin starts a transaction. Most callers should use RunInTransaction instead.
( Conn) BeginContext (ctx context .Context ) (*Tx , error )
( Conn) Close () 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) Context () context .Context
Context returns DB context.
( Conn) CopyFrom (r io .Reader , query interface{}, params ...interface{}) (res Result , err error )
CopyFrom copies data from reader to a table.
( Conn) CopyTo (w io .Writer , query interface{}, params ...interface{}) (res Result , err error )
CopyTo copies data from a table to writer.
( Conn) Exec (query interface{}, params ...interface{}) (res Result , err error )
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 )
( Conn) ExecOne (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
( Conn) Model (model ...interface{}) *Query
Model returns new query for the model.
( Conn) ModelContext (c context .Context , model ...interface{}) *Query
( Conn) Param (param string ) interface{}
Param returns value for the param.
( Conn) Ping (ctx context .Context ) error
Ping verifies a connection to the database is still alive,
establishing a connection if necessary.
( Conn) PoolStats () *PoolStats
PoolStats returns connection pool stats.
( Conn) Prepare (q string ) (*Stmt , error )
Prepare creates a prepared statement for later queries or
executions. Multiple queries or executions may be run concurrently
from the returned statement.
( Conn) Query (model, query interface{}, params ...interface{}) (res Result , err error )
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 )
( Conn) QueryOne (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 )
( Conn) RunInTransaction (ctx context .Context , fn func(*Tx ) error ) error
RunInTransaction runs a function in a transaction. If function
returns an error transaction is rolled back, otherwise transaction
is committed.
(*Conn) WithContext (ctx context .Context ) *Conn
WithContext returns a copy of the DB that uses the ctx.
(*Conn) WithParam (param string , value interface{}) *Conn
WithParam returns a copy of the DB that replaces the param with the value
in queries.
(*Conn) WithTimeout (d time .Duration ) *Conn
WithTimeout returns a copy of the DB that uses d as the read/write timeout.
/* 29 unexporteds ... */ /* 29 unexporteds: */
( Conn) afterQuery (ctx context .Context , event *QueryEvent , res Result , err error ) error
( Conn) afterQueryFromIndex (ctx context .Context , event *QueryEvent , hookIndex int ) error
( Conn) auth (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
( Conn) authCleartext (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , password string ) error
( Conn) authMD5 (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
( Conn) authSASL (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
( Conn) beforeQuery (ctx context .Context , ormDB orm .DB , model, query interface{}, params []interface{}, fmtedQuery []byte ) (context .Context , *QueryEvent , error )
( Conn) cancelRequest (processID, secretKey int32 ) error
( Conn) clone () *baseDB
( Conn) closeStmt (c context .Context , cn *pool .Conn , name string ) error
( Conn) copyFrom (ctx context .Context , cn *pool .Conn , r io .Reader , query interface{}, params ...interface{}) (res Result , err error )
TODO: don't get/put conn in the pool.
( Conn) copyTo (ctx context .Context , cn *pool .Conn , w io .Writer , query interface{}, params ...interface{}) (res Result , err error )
( Conn) enableSSL (c context .Context , cn *pool .Conn , tlsConf *tls .Config ) error
( Conn) exec (ctx context .Context , query interface{}, params ...interface{}) (Result , error )
( Conn) execOne (c context .Context , query interface{}, params ...interface{}) (Result , error )
( Conn) getConn (ctx context .Context ) (*pool .Conn , error )
( Conn) initConn (ctx context .Context , cn *pool .Conn ) error
( Conn) logStartupNotice (rd *pool .ReaderContext ) error
logStartupNotice will handle notice messages during the startup process. It will parse them and log them for the
client. Notices are not common and only happen if there is something the client should be aware of. So logging should
not be a problem.
Notice messages can be seen in startup: https://www.postgresql.org/docs/13/protocol-flow.html
Information on the notice message format: https://www.postgresql.org/docs/13/protocol-message-formats.html
Note: This is true for earlier versions of PostgreSQL as well, I've just included the latest versions of the docs.
( Conn) prepare (c context .Context , cn *pool .Conn , q string ) (string , []types .ColumnInfo , error )
( Conn) query (ctx context .Context , model, query interface{}, params ...interface{}) (Result , error )
( Conn) queryOne (ctx context .Context , model, query interface{}, params ...interface{}) (Result , error )
( Conn) releaseConn (ctx context .Context , cn *pool .Conn , err error )
( Conn) retryBackoff (retry int ) time .Duration
( Conn) shouldRetry (err error ) bool
( Conn) simpleQuery (c context .Context , cn *pool .Conn , wb *pool .WriteBuffer ) (*result , error )
( Conn) simpleQueryData (c context .Context , cn *pool .Conn , model interface{}, wb *pool .WriteBuffer ) (*result , error )
( Conn) startup (c context .Context , cn *pool .Conn , user, password, database, appName string ) error
( Conn) withConn (ctx context .Context , fn func(context .Context , *pool .Conn ) error ) error
( Conn) withPool (p pool .Pooler ) *baseDB
Implements (at least 5, all are exported )
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
As Outputs Of (at least 5, in which 4 are exported )
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
/* at least one unexported ... */ /* at least one unexported: */
func newConn (ctx context .Context , baseDB *baseDB ) *Conn
type DB (struct)
DB is a database handle representing a pool of zero or more
underlying connections. It's safe for concurrent use by multiple
goroutines.
Fields (total 7, none are exported )
/* 7 unexporteds ... */ /* 7 unexporteds: */
baseDB *baseDB
baseDB .db orm .DB
baseDB .fmter *orm .Formatter
baseDB .opt *Options
baseDB .pool pool .Pooler
baseDB .queryHooks []QueryHook
ctx context .Context
Methods (total 59, in which 30 are exported )
( DB) AddQueryHook (hook QueryHook )
AddQueryHook adds a hook into query processing.
( DB) Begin () (*Tx , error )
Begin starts a transaction. Most callers should use RunInTransaction instead.
( DB) BeginContext (ctx context .Context ) (*Tx , error )
( DB) Close () 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.
(*DB) Conn () *Conn
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.
(*DB) Context () context .Context
Context returns DB context.
( DB) CopyFrom (r io .Reader , query interface{}, params ...interface{}) (res Result , err error )
CopyFrom copies data from reader to a table.
( DB) CopyTo (w io .Writer , query interface{}, params ...interface{}) (res Result , err error )
CopyTo copies data from a table to writer.
( DB) Exec (query interface{}, params ...interface{}) (res Result , err error )
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 )
( DB) ExecOne (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
(*DB) Listen (ctx context .Context , channels ...string ) *Listener
Listen listens for notifications sent with NOTIFY command.
( DB) Model (model ...interface{}) *Query
Model returns new query for the model.
( DB) ModelContext (c context .Context , model ...interface{}) *Query
(*DB) Options () *Options
Options returns read-only Options that were used to connect to the DB.
( DB) Param (param string ) interface{}
Param returns value for the param.
( DB) Ping (ctx context .Context ) error
Ping verifies a connection to the database is still alive,
establishing a connection if necessary.
( DB) PoolStats () *PoolStats
PoolStats returns connection pool stats.
( DB) Prepare (q string ) (*Stmt , error )
Prepare creates a prepared statement for later queries or
executions. Multiple queries or executions may be run concurrently
from the returned statement.
( DB) Query (model, query interface{}, params ...interface{}) (res Result , err error )
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 )
( DB) QueryOne (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 )
( DB) RunInTransaction (ctx context .Context , fn func(*Tx ) error ) error
RunInTransaction runs a function in a transaction. If function
returns an error transaction is rolled back, otherwise transaction
is committed.
(*DB) String () string
(*DB) WithContext (ctx context .Context ) *DB
WithContext returns a copy of the DB that uses the ctx.
(*DB) WithParam (param string , value interface{}) *DB
WithParam returns a copy of the DB that replaces the param with the value
in queries.
(*DB) WithTimeout (d time .Duration ) *DB
WithTimeout returns a copy of the DB that uses d as the read/write timeout.
/* 29 unexporteds ... */ /* 29 unexporteds: */
( DB) afterQuery (ctx context .Context , event *QueryEvent , res Result , err error ) error
( DB) afterQueryFromIndex (ctx context .Context , event *QueryEvent , hookIndex int ) error
( DB) auth (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
( DB) authCleartext (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , password string ) error
( DB) authMD5 (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
( DB) authSASL (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
( DB) beforeQuery (ctx context .Context , ormDB orm .DB , model, query interface{}, params []interface{}, fmtedQuery []byte ) (context .Context , *QueryEvent , error )
( DB) cancelRequest (processID, secretKey int32 ) error
( DB) clone () *baseDB
( DB) closeStmt (c context .Context , cn *pool .Conn , name string ) error
( DB) copyFrom (ctx context .Context , cn *pool .Conn , r io .Reader , query interface{}, params ...interface{}) (res Result , err error )
TODO: don't get/put conn in the pool.
( DB) copyTo (ctx context .Context , cn *pool .Conn , w io .Writer , query interface{}, params ...interface{}) (res Result , err error )
( DB) enableSSL (c context .Context , cn *pool .Conn , tlsConf *tls .Config ) error
( DB) exec (ctx context .Context , query interface{}, params ...interface{}) (Result , error )
( DB) execOne (c context .Context , query interface{}, params ...interface{}) (Result , error )
( DB) getConn (ctx context .Context ) (*pool .Conn , error )
( DB) initConn (ctx context .Context , cn *pool .Conn ) error
( DB) logStartupNotice (rd *pool .ReaderContext ) error
logStartupNotice will handle notice messages during the startup process. It will parse them and log them for the
client. Notices are not common and only happen if there is something the client should be aware of. So logging should
not be a problem.
Notice messages can be seen in startup: https://www.postgresql.org/docs/13/protocol-flow.html
Information on the notice message format: https://www.postgresql.org/docs/13/protocol-message-formats.html
Note: This is true for earlier versions of PostgreSQL as well, I've just included the latest versions of the docs.
( DB) prepare (c context .Context , cn *pool .Conn , q string ) (string , []types .ColumnInfo , error )
( DB) query (ctx context .Context , model, query interface{}, params ...interface{}) (Result , error )
( DB) queryOne (ctx context .Context , model, query interface{}, params ...interface{}) (Result , error )
( DB) releaseConn (ctx context .Context , cn *pool .Conn , err error )
( DB) retryBackoff (retry int ) time .Duration
( DB) shouldRetry (err error ) bool
( DB) simpleQuery (c context .Context , cn *pool .Conn , wb *pool .WriteBuffer ) (*result , error )
( DB) simpleQueryData (c context .Context , cn *pool .Conn , model interface{}, wb *pool .WriteBuffer ) (*result , error )
( DB) startup (c context .Context , cn *pool .Conn , user, password, database, appName string ) error
( DB) withConn (ctx context .Context , fn func(context .Context , *pool .Conn ) error ) error
( DB) withPool (p pool .Pooler ) *baseDB
Implements (at least 10, in which 7 are exported )
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
/* 3+ unexporteds ... */ /* 3+ unexporteds: */
*DB : github.com/aws/smithy-go/middleware.stringer
*DB : context.stringer
*DB : runtime.stringer
As Outputs Of (at least 5, in which 4 are exported )
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
/* at least one unexported ... */ /* at least one unexported: */
func newDB (ctx context .Context , baseDB *baseDB ) *DB
type DBI (interface)
DBI is a DB interface implemented by *DB and *Tx.
Methods (total 14, all are exported )
( 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
Implemented By (at least 4, in which 3 are exported )
Conn
DB
*Tx
/* at least one unexported ... */ /* at least one unexported: */
*baseDB
type Listener (struct)
Listener listens for notifications sent with NOTIFY command.
It's NOT safe for concurrent use by multiple goroutines
except the Channel API.
Fields (total 9, none are exported )
/* 9 unexporteds ... */ /* 9 unexporteds: */
ch chan Notification
chOnce sync .Once
channels []string
closed bool
cn *pool .Conn
db *DB
exit chan struct{}
mu sync .Mutex
pingCh chan struct{}
Methods (total 19, in which 8 are exported )
(*Listener) Channel () <-chan Notification
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.
(*Listener) ChannelSize (size int ) <-chan Notification
ChannelSize is like Channel, but creates a Go channel
with specified buffer size.
(*Listener) Close () error
Close closes the listener, releasing any open resources.
(*Listener) Listen (ctx context .Context , channels ...string ) error
Listen starts listening for notifications on channels.
(*Listener) Receive (ctx context .Context ) (channel string , payload string , err error )
Receive indefinitely waits for a notification. This is low-level API
and in most cases Channel should be used instead.
(*Listener) ReceiveTimeout (ctx context .Context , timeout time .Duration ) (channel, payload string , err error )
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
(*Listener) Unlisten (ctx context .Context , channels ...string ) error
Unlisten stops listening for notifications on channels.
/* 11 unexporteds ... */ /* 11 unexporteds: */
(*Listener) channel (size int ) <-chan Notification
(*Listener) closeTheCn (reason error ) error
(*Listener) conn (ctx context .Context ) (*pool .Conn , error )
(*Listener) connWithLock (ctx context .Context ) (*pool .Conn , error )
(*Listener) init ()
(*Listener) initChannel (size int )
(*Listener) listen (ctx context .Context , cn *pool .Conn , channels ...string ) error
(*Listener) ping () error
(*Listener) reconnect (ctx context .Context , reason error )
(*Listener) releaseConn (ctx context .Context , cn *pool .Conn , err error , allowTimeout bool )
(*Listener) unlisten (ctx context .Context , cn *pool .Conn , channels ...string ) error
Implements (at least 6, in which 3 are exported )
*Listener : expvar.Var
*Listener : fmt.Stringer
*Listener : io.Closer
/* 3+ unexporteds ... */ /* 3+ unexporteds: */
*Listener : github.com/aws/smithy-go/middleware.stringer
*Listener : context.stringer
*Listener : runtime.stringer
As Outputs Of (at least one exported )
func (*DB ).Listen (ctx context .Context , channels ...string ) *Listener
type Options (struct)
Options contains database connection options.
Fields (total 22, all are exported )
Addr string
TCP host:port or Unix socket depending on Network.
ApplicationName string
ApplicationName is the application name. Used in logs on Pg side.
Only available from pg-9.0.
Database string
DialTimeout time .Duration
Dial timeout for establishing new connections.
Default is 5 seconds.
Dialer func(ctx context .Context , network, addr string ) (net .Conn , error )
Dialer creates new network connection and has priority over
Network and Addr options.
IdleCheckFrequency time .Duration
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.
IdleTimeout time .Duration
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.
MaxConnAge time .Duration
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.
MaxRetries int
Maximum number of retries before giving up.
Default is to not retry failed queries.
MaxRetryBackoff time .Duration
Maximum backoff between each retry.
Default is 4 seconds; -1 disables backoff.
MinIdleConns int
Minimum number of idle connections which is useful when establishing
new connection is slow.
MinRetryBackoff time .Duration
Minimum backoff between each retry.
Default is 250 milliseconds; -1 disables backoff.
Network string
Network type, either tcp or unix.
Default is tcp.
OnConnect func(ctx context .Context , cn *Conn ) error
Hook that is called after new connection is established
and user is authenticated.
Password string
PoolSize int
Maximum number of socket connections.
Default is 10 connections per every CPU as reported by runtime.NumCPU.
PoolTimeout time .Duration
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.
ReadTimeout time .Duration
Timeout for socket reads. If reached, commands will fail
with a timeout instead of blocking.
RetryStatementTimeout bool
Whether to retry queries cancelled because of statement_timeout.
TLSConfig *tls .Config
TLS config for secure connections.
User string
WriteTimeout time .Duration
Timeout for socket writes. If reached, commands will fail
with a timeout instead of blocking.
Methods (total 2, neither is exported )
/* 2 unexporteds ... */ /* 2 unexporteds: */
(*Options) getDialer () func(context .Context ) (net .Conn , error )
(*Options) init ()
As Outputs Of (at least 2, both are exported )
func ParseURL (sURL string ) (*Options , error )
func (*DB ).Options () *Options
As Inputs Of (at least 2, in which 1 are exported )
func Connect (opt *Options ) *DB
/* at least one unexported ... */ /* at least one unexported: */
func newConnPool (opt *Options ) *pool .ConnPool
type Stmt (struct)
Stmt is a prepared statement. Stmt is safe for concurrent use by
multiple goroutines.
Fields (total 5, none are exported )
/* 5 unexporteds ... */ /* 5 unexporteds: */
columns []types .ColumnInfo
db *baseDB
name string
q string
stickyErr error
Methods (total 18, in which 9 are exported )
(*Stmt) Close () error
Close closes the statement.
(*Stmt) Exec (params ...interface{}) (Result , error )
Exec executes a prepared statement with the given parameters.
(*Stmt) ExecContext (c context .Context , params ...interface{}) (Result , error )
ExecContext executes a prepared statement with the given parameters.
(*Stmt) ExecOne (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.
(*Stmt) ExecOneContext (c context .Context , params ...interface{}) (Result , error )
ExecOneContext acts like ExecOne but additionally receives a context.
(*Stmt) Query (model interface{}, params ...interface{}) (Result , error )
Query executes a prepared query statement with the given parameters.
(*Stmt) QueryContext (c context .Context , model interface{}, params ...interface{}) (Result , error )
QueryContext acts like Query but additionally receives a context.
(*Stmt) QueryOne (model 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.
(*Stmt) QueryOneContext (c context .Context , model interface{}, params ...interface{}) (Result , error )
QueryOneContext acts like QueryOne but additionally receives a context.
/* 9 unexporteds ... */ /* 9 unexporteds: */
(*Stmt) closeStmt () error
(*Stmt) exec (ctx context .Context , params ...interface{}) (Result , error )
(*Stmt) execOne (c context .Context , params ...interface{}) (Result , error )
(*Stmt) extQuery (c context .Context , cn *pool .Conn , name string , params ...interface{}) (Result , error )
(*Stmt) extQueryData (c context .Context , cn *pool .Conn , name string , model interface{}, columns []types .ColumnInfo , params ...interface{}) (Result , error )
(*Stmt) prepare (ctx context .Context , q string ) error
(*Stmt) query (ctx context .Context , model interface{}, params ...interface{}) (Result , error )
(*Stmt) queryOne (c context .Context , model interface{}, params ...interface{}) (Result , error )
(*Stmt) withConn (c context .Context , fn func(context .Context , *pool .Conn ) error ) error
Implements (at least one exported )
*Stmt : io.Closer
As Outputs Of (at least 3, in which 2 are exported )
func (*Tx ).Prepare (q string ) (*Stmt , error )
func (*Tx ).Stmt (stmt *Stmt ) *Stmt
/* at least one unexported ... */ /* at least one unexported: */
func prepareStmt (db *baseDB , q string ) (*Stmt , error )
As Inputs Of (at least one exported )
func (*Tx ).Stmt (stmt *Stmt ) *Stmt
type Tx (struct)
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.
Fields (total 5, none are exported )
/* 5 unexporteds ... */ /* 5 unexporteds: */
_closed int32
ctx context .Context
db *baseDB
stmts []*Stmt
stmtsMu sync .Mutex
Methods (total 32, in which 24 are exported )
(*Tx) Begin () (*Tx , error )
Begin returns current transaction. It does not start new transaction.
(*Tx) Close () error
(*Tx) CloseContext (ctx context .Context ) error
Close calls Rollback if the tx has not already been committed or rolled back.
(*Tx) Commit () error
(*Tx) CommitContext (ctx context .Context ) error
Commit commits the transaction.
(*Tx) Context () context .Context
Context returns the context.Context of the transaction.
(*Tx) CopyFrom (r io .Reader , query interface{}, params ...interface{}) (res Result , err error )
CopyFrom is an alias for DB.CopyFrom.
(*Tx) CopyTo (w io .Writer , query interface{}, params ...interface{}) (res Result , err error )
CopyTo is an alias for DB.CopyTo.
(*Tx) Exec (query interface{}, params ...interface{}) (Result , error )
Exec is an alias for DB.Exec.
(*Tx) ExecContext (c context .Context , query interface{}, params ...interface{}) (Result , error )
ExecContext acts like Exec but additionally receives a context.
(*Tx) ExecOne (query interface{}, params ...interface{}) (Result , error )
ExecOne is an alias for DB.ExecOne.
(*Tx) ExecOneContext (c context .Context , query interface{}, params ...interface{}) (Result , error )
ExecOneContext acts like ExecOne but additionally receives a context.
(*Tx) Formatter () orm .QueryFormatter
Formatter is an alias for DB.Formatter.
(*Tx) Model (model ...interface{}) *Query
Model is an alias for DB.Model.
(*Tx) ModelContext (c context .Context , model ...interface{}) *Query
ModelContext acts like Model but additionally receives a context.
(*Tx) Prepare (q string ) (*Stmt , error )
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.
(*Tx) Query (model interface{}, query interface{}, params ...interface{}) (Result , error )
Query is an alias for DB.Query.
(*Tx) QueryContext (c context .Context , model interface{}, query interface{}, params ...interface{}) (Result , error )
QueryContext acts like Query but additionally receives a context.
(*Tx) QueryOne (model interface{}, query interface{}, params ...interface{}) (Result , error )
QueryOne is an alias for DB.QueryOne.
(*Tx) QueryOneContext (c context .Context , model interface{}, query interface{}, params ...interface{}) (Result , error )
QueryOneContext acts like QueryOne but additionally receives a context.
(*Tx) Rollback () error
(*Tx) RollbackContext (ctx context .Context ) error
Rollback aborts the transaction.
(*Tx) RunInTransaction (ctx context .Context , fn func(*Tx ) error ) error
RunInTransaction runs a function in the transaction. If function
returns an error transaction is rolled back, otherwise transaction
is committed.
(*Tx) Stmt (stmt *Stmt ) *Stmt
Stmt returns a transaction-specific prepared statement
from an existing statement.
/* 8 unexporteds ... */ /* 8 unexporteds: */
(*Tx) begin (ctx context .Context ) error
(*Tx) close ()
(*Tx) closed () bool
(*Tx) exec (ctx context .Context , query interface{}, params ...interface{}) (Result , error )
(*Tx) execOne (c context .Context , query interface{}, params ...interface{}) (Result , error )
(*Tx) query (ctx context .Context , model interface{}, query interface{}, params ...interface{}) (Result , error )
(*Tx) queryOne (c context .Context , model interface{}, query interface{}, params ...interface{}) (Result , error )
(*Tx) withConn (c context .Context , fn func(context .Context , *pool .Conn ) error ) error
Implements (at least 5, all are exported )
*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
As Outputs Of (at least 4, in which 3 are exported )
func DBI .Begin () (*Tx , error )
func (*Tx).Begin () (*Tx , error )
func github.com/go-pg/migrations/v8.DB .Begin () (*Tx , error )
/* at least one unexported ... */ /* at least one unexported: */
func github.com/go-pg/migrations/v8.(*Collection ).begin (db migrations .DB ) (*Tx , int64 , error )
As Inputs Of (at least 4, none are exported )
/* 4+ unexporteds ... */ /* 4+ unexporteds: */
func github.com/go-pg/migrations/v8.(*Collection ).down (db migrations .DB , tx *Tx , migrations []*migrations .Migration , oldVersion int64 ) (int64 , error )
func github.com/go-pg/migrations/v8.(*Collection ).run (tx *Tx , fn func() (int64 , error )) (newVersion int64 , err error )
func github.com/go-pg/migrations/v8.(*Collection ).runDown (db migrations .DB , tx *Tx , m *migrations .Migration ) (int64 , error )
func github.com/go-pg/migrations/v8.(*Collection ).runUp (db migrations .DB , tx *Tx , m *migrations .Migration ) (int64 , error )
/* 5 unexporteds ... */ /* 5 unexporteds: */ type baseDB (struct)
Fields (total 5, none are exported )
/* 5 unexporteds ... */ /* 5 unexporteds: */
db orm .DB
fmter *orm .Formatter
opt *Options
pool pool .Pooler
queryHooks []QueryHook
Methods (total 53, in which 24 are exported )
(*baseDB) AddQueryHook (hook QueryHook )
AddQueryHook adds a hook into query processing.
(*baseDB) Begin () (*Tx , error )
Begin starts a transaction. Most callers should use RunInTransaction instead.
(*baseDB) BeginContext (ctx context .Context ) (*Tx , error )
(*baseDB) Close () 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.
(*baseDB) CopyFrom (r io .Reader , query interface{}, params ...interface{}) (res Result , err error )
CopyFrom copies data from reader to a table.
(*baseDB) CopyTo (w io .Writer , query interface{}, params ...interface{}) (res Result , err error )
CopyTo copies data from a table to writer.
(*baseDB) Exec (query interface{}, params ...interface{}) (res Result , err error )
Exec executes a query ignoring returned rows. The params are for any
placeholders in the query.
(*baseDB) ExecContext (c context .Context , query interface{}, params ...interface{}) (Result , error )
(*baseDB) ExecOne (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.
(*baseDB) ExecOneContext (ctx context .Context , query interface{}, params ...interface{}) (Result , error )
(*baseDB) Formatter () orm .QueryFormatter
(*baseDB) Model (model ...interface{}) *Query
Model returns new query for the model.
(*baseDB) ModelContext (c context .Context , model ...interface{}) *Query
(*baseDB) Param (param string ) interface{}
Param returns value for the param.
(*baseDB) Ping (ctx context .Context ) error
Ping verifies a connection to the database is still alive,
establishing a connection if necessary.
(*baseDB) PoolStats () *PoolStats
PoolStats returns connection pool stats.
(*baseDB) Prepare (q string ) (*Stmt , error )
Prepare creates a prepared statement for later queries or
executions. Multiple queries or executions may be run concurrently
from the returned statement.
(*baseDB) Query (model, query interface{}, params ...interface{}) (res Result , err error )
Query executes a query that returns rows, typically a SELECT.
The params are for any placeholders in the query.
(*baseDB) QueryContext (c context .Context , model, query interface{}, params ...interface{}) (Result , error )
(*baseDB) QueryOne (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.
(*baseDB) QueryOneContext (ctx context .Context , model, query interface{}, params ...interface{}) (Result , error )
(*baseDB) RunInTransaction (ctx context .Context , fn func(*Tx ) error ) error
RunInTransaction runs a function in a transaction. If function
returns an error transaction is rolled back, otherwise transaction
is committed.
(*baseDB) WithParam (param string , value interface{}) *baseDB
(*baseDB) WithTimeout (d time .Duration ) *baseDB
/* 29 unexporteds ... */ /* 29 unexporteds: */
(*baseDB) afterQuery (ctx context .Context , event *QueryEvent , res Result , err error ) error
(*baseDB) afterQueryFromIndex (ctx context .Context , event *QueryEvent , hookIndex int ) error
(*baseDB) auth (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
(*baseDB) authCleartext (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , password string ) error
(*baseDB) authMD5 (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
(*baseDB) authSASL (c context .Context , cn *pool .Conn , rd *pool .ReaderContext , user, password string ) error
(*baseDB) beforeQuery (ctx context .Context , ormDB orm .DB , model, query interface{}, params []interface{}, fmtedQuery []byte ) (context .Context , *QueryEvent , error )
(*baseDB) cancelRequest (processID, secretKey int32 ) error
(*baseDB) clone () *baseDB
(*baseDB) closeStmt (c context .Context , cn *pool .Conn , name string ) error
(*baseDB) copyFrom (ctx context .Context , cn *pool .Conn , r io .Reader , query interface{}, params ...interface{}) (res Result , err error )
TODO: don't get/put conn in the pool.
(*baseDB) copyTo (ctx context .Context , cn *pool .Conn , w io .Writer , query interface{}, params ...interface{}) (res Result , err error )
(*baseDB) enableSSL (c context .Context , cn *pool .Conn , tlsConf *tls .Config ) error
(*baseDB) exec (ctx context .Context , query interface{}, params ...interface{}) (Result , error )
(*baseDB) execOne (c context .Context , query interface{}, params ...interface{}) (Result , error )
(*baseDB) getConn (ctx context .Context ) (*pool .Conn , error )
(*baseDB) initConn (ctx context .Context , cn *pool .Conn ) error
(*baseDB) logStartupNotice (rd *pool .ReaderContext ) error
logStartupNotice will handle notice messages during the startup process. It will parse them and log them for the
client. Notices are not common and only happen if there is something the client should be aware of. So logging should
not be a problem.
Notice messages can be seen in startup: https://www.postgresql.org/docs/13/protocol-flow.html
Information on the notice message format: https://www.postgresql.org/docs/13/protocol-message-formats.html
Note: This is true for earlier versions of PostgreSQL as well, I've just included the latest versions of the docs.
(*baseDB) prepare (c context .Context , cn *pool .Conn , q string ) (string , []types .ColumnInfo , error )
(*baseDB) query (ctx context .Context , model, query interface{}, params ...interface{}) (Result , error )
(*baseDB) queryOne (ctx context .Context , model, query interface{}, params ...interface{}) (Result , error )
(*baseDB) releaseConn (ctx context .Context , cn *pool .Conn , err error )
(*baseDB) retryBackoff (retry int ) time .Duration
(*baseDB) shouldRetry (err error ) bool
(*baseDB) simpleQuery (c context .Context , cn *pool .Conn , wb *pool .WriteBuffer ) (*result , error )
(*baseDB) simpleQueryData (c context .Context , cn *pool .Conn , model interface{}, wb *pool .WriteBuffer ) (*result , error )
(*baseDB) startup (c context .Context , cn *pool .Conn , user, password, database, appName string ) error
(*baseDB) withConn (ctx context .Context , fn func(context .Context , *pool .Conn ) error ) error
(*baseDB) withPool (p pool .Pooler ) *baseDB
Implements (at least 3, all are exported )
*baseDB : DBI
*baseDB : database/sql/driver.Pinger
*baseDB : io.Closer
As Inputs Of (at least 3, none are exported )
/* 3+ unexporteds ... */ /* 3+ unexporteds: */
func newConn (ctx context .Context , baseDB *baseDB ) *Conn
func newDB (ctx context .Context , baseDB *baseDB ) *DB
func prepareStmt (db *baseDB , q string ) (*Stmt , error )
type result (struct)
A result summarizes an executed SQL command.
Fields (total 3, none are exported )
/* 3 unexporteds ... */ /* 3 unexporteds: */
affected int
model orm .Model
returned int
Methods (total 4, in which 3 are exported )
(*result) Model () orm .Model
(*result) RowsAffected () int
(*result) RowsReturned () int
/* one unexported ... */ /* one unexported: */
(*result) parse (b []byte ) error
nolint
Implements (at least one exported )
*result : github.com/go-pg/pg/v10/orm.Result
As Outputs Of (at least 6, none are exported )
/* 6+ unexporteds ... */ /* 6+ unexporteds: */
func readCopyData (rd *pool .ReaderContext , w io .Writer ) (*result , error )
func readExtQuery (rd *pool .ReaderContext ) (*result , error )
func readExtQueryData (ctx context .Context , rd *pool .ReaderContext , mod interface{}, columns []types .ColumnInfo ) (*result , error )
func readReadyForQuery (rd *pool .ReaderContext ) (*result , error )
func readSimpleQuery (rd *pool .ReaderContext ) (*result , error )
func readSimpleQueryData (ctx context .Context , rd *pool .ReaderContext , mod interface{}) (*result , error )