Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Rainc1oud/pmx

 
 

Repository files navigation

pmx

Golang data mapping library for postgres and pgx.

Install

go get -u github.com/wcamarao/pmx

Features

  • Simple data mapping with struct tags
  • Explicit by design, no magic or conventions
  • Select database records into an annotated struct or slice
  • Insert and update database records from an annotated struct
  • Compatible with pgx Exec/Query interface i.e. pgxpool.Pool, pgx.Conn, pgx.Tx
  • Support transient fields and auto generated values

Data Mapping

Given the following table:

create table events (
    id uuid primary key,
    recorded_at timestamptz
);

Annotate a data model with struct tags:

type Event struct {
    ID         string    `db:"id" table:"events"`
    RecordedAt time.Time `db:"recorded_at"`
    Transient  string    // ignored by pmx
    transient  string    // ignored by pmx
}
  • The first struct field must be annotated with table for insert and update operations
  • Struct fields annotated with db must be exported
  • Transient fields can be optionally exported

Insert

Always provide a struct pointer.

type Event struct {
    ID         string    `db:"id" table:"events"`
    RecordedAt time.Time `db:"recorded_at"`
}

func main() {
    ctx := context.Background()

    conn, err := pgx.Connect(ctx, "postgresql://...")
    if err != nil {
        panic(err)
    }
    defer conn.Close(ctx)

    event := Event{
        ID:         "a1eff19b-4624-46c6-9e09-5910e7b2938d",
        RecordedAt: time.Now(),
    }

    // Generated query: insert into events (id, recorded_at) values ($1, $2)
    err = pmx.Insert(ctx, conn, &event)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%+v\n", event)
}

Select into struct

Always provide a struct pointer.

type Event struct {
    ID         string    `db:"id" table:"events"`
    RecordedAt time.Time `db:"recorded_at"`
}

func main() {
    ctx := context.Background()

    conn, err := pgx.Connect(ctx, "postgresql://...")
    if err != nil {
        panic(err)
    }
    defer conn.Close(ctx)

    var event Event
    ok, err := pmx.Select(ctx, conn, &event, "select * from events where id = $1", "a1eff19b-4624-46c6-9e09-5910e7b2938d")
    if err != nil {
        panic(err)
    }

    if !ok {
        panic("event not found")
    }

    fmt.Printf("%+v\n", event)
}

Select into slice

Always provide a slice pointer.

The underlying slice type must be a struct pointer.

type Event struct {
    ID         string    `db:"id" table:"events"`
    RecordedAt time.Time `db:"recorded_at"`
}

func main() {
    ctx := context.Background()

    conn, err := pgx.Connect(ctx, "postgresql://...")
    if err != nil {
        panic(err)
    }
    defer conn.Close(ctx)

    var events []*Event
    ok, err := pmx.Select(ctx, conn, &events, "select * from events limit 3")
    if err != nil {
        panic(err)
    }

    if !ok {
        panic("no events found")
    }

    fmt.Printf("%+v\n", events)
}

Update

Always provide a struct pointer.

The last argument UpdateOptions specifies:

  • Set: explicit struct fields to be updated
  • By: explicit struct fields to be matched by equality in the where clause
type Event struct {
    ID         string    `db:"id" table:"events"`
    RecordedAt time.Time `db:"recorded_at"`
}

func main() {
    ctx := context.Background()

    conn, err := pgx.Connect(ctx, "postgresql://...")
    if err != nil {
        panic(err)
    }
    defer conn.Close(ctx)

    event := Event{
        ID:         "a1eff19b-4624-46c6-9e09-5910e7b2938d",
        RecordedAt: time.Now(),
    }

    // Generated query: update events set recorded_at = $1 where id = $2
    err = pmx.Update(ctx, conn, &event, &pmx.UpdateOptions{
        Set: []string{"RecordedAt"},
        By:  []string{"ID"},
    })
    if err != nil {
        panic(err)
    }

    fmt.Printf("%+v\n", event)
}

Auto Generated Values

Given the following table with an auto generated value, e.g. serial/sequence:

create table events (
    id bigserial primary key,
    recorded_at timestamptz
);

Annotate the ID struct field with a generated:"auto" struct tag:

type Event struct {
    ID         string    `db:"id" generated:"auto" table:"events"`
    RecordedAt time.Time `db:"recorded_at"`
}

The id column will be excluded from insert values and update set statements.

ErrInvalidRef

The error pmx.ErrInvalidRef ("invalid ref") means you provided an invalid pointer reference.

About

Go data mapping library for postgres and pgx

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Go 96.6%
  • Makefile 3.4%