Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ jobs:
run: go build -v ./...

- name: Test
run: go test -v -coverprofile=coverage.txt -covermode=atomic ./...
run: go test -v -coverprofile=coverage.txt.tmp -covermode=atomic ./...
- name: Exclude adapters
run: cat coverage.txt.tmp | grep -v "/adapters/" > coverage.txt && rm coverage.txt.tmp
- uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This project under active development.
## Features
Essentially, **GERPO** is a helper for building SQL queries and mapping results to Go structs.
- **Data Sources (executor adapters)**:
- pgx pool v4
- pgx pool v4/v5
- any database/sql driver
- any other: you can add dbWrapper for any other database library, by implementing simple wrapper - executor.DBWrapper.
- **Repository configuration**:
Expand Down Expand Up @@ -63,19 +63,28 @@ import (
"github.com/insei/gerpo"
"github.com/insei/gerpo/executor/adapters/databasesql"
"github.com/insei/gerpo/executor/adapters/pgx4"
"github.com/insei/gerpo/executor/adapters/pgx5"
"github.com/insei/gerpo/executor/adapters/placeholder"
"github.com/jackc/pgx/v4/pgxpool"
)

func main() {
// for database/sql
// for database/sql postgres variant
// "github.com/insei/gerpo/executor/adapters/databasesql"
var db *sql.DB
dbWrap := databasesql.NewAdapter(db)
// for postgres change placeholder to dollar, by default placeholder is Question
phOption := databasesql.WithPlaceholder(placeholder.Dollar)
dbWrap := databasesql.NewAdapter(db, phOption)

// for pgx4 pool
// "github.com/insei/gerpo/executor/adapters/pgx4"
var pool *pgxpool.Pool
dbWrap := pgx4.NewPoolAdapter(pool)
var poolv4 *pgxpool.Pool
dbWrap = pgx4.NewPoolAdapter(poolv4)

// for pgx5 pool
// "github.com/insei/gerpo/executor/adapters/pgx5"
var poolv5 *pgxpool.Pool
dbWrap = pgx5.NewPoolAdapter(poolv5)

repo, err := gerpo.NewBuilder[ModelType]().DB(dbWrap)
// ...
Expand Down
54 changes: 54 additions & 0 deletions executor/adapters/pgx5/pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package pgx4

import (
"context"
"fmt"

"github.com/insei/gerpo/executor/adapters/placeholder"
"github.com/insei/gerpo/executor/types"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
)

type poolWrap struct {
pool *pgxpool.Pool
}

func (p *poolWrap) ExecContext(ctx context.Context, query string, args ...any) (types.Result, error) {
sql, err := placeholder.Dollar.ReplacePlaceholders(query)
if err != nil {
return nil, fmt.Errorf("failed to replace placeholders: %w", err)
}
res, err := p.pool.Exec(ctx, sql, args...)
if err != nil {
return nil, err
}
return &resultWrap{res: res}, nil
}

func (p *poolWrap) QueryContext(ctx context.Context, query string, args ...any) (types.Rows, error) {
sql, err := placeholder.Dollar.ReplacePlaceholders(query)
if err != nil {
return nil, fmt.Errorf("failed to replace placeholders: %w", err)
}
rows, err := p.pool.Query(ctx, sql, args...)
if err != nil {
return nil, err
}
return &rowsWrap{rows: rows}, nil
}

func (p *poolWrap) BeginTx(ctx context.Context) (types.Tx, error) {
tx, err := p.pool.BeginTx(ctx, pgx.TxOptions{})
if err != nil {
return nil, err
}
return &txWrap{
rollbackUnlessCommittedNeeded: true,
tx: tx,
}, err
}

func NewPoolAdapter(pool *pgxpool.Pool) types.DBAdapter {
return &poolWrap{pool}
}
11 changes: 11 additions & 0 deletions executor/adapters/pgx5/result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package pgx4

import "github.com/jackc/pgx/v5/pgconn"

type resultWrap struct {
res pgconn.CommandTag
}

func (e *resultWrap) RowsAffected() (int64, error) {
return e.res.RowsAffected(), nil
}
22 changes: 22 additions & 0 deletions executor/adapters/pgx5/rows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package pgx4

import (
"github.com/jackc/pgx/v5"
)

type rowsWrap struct {
rows pgx.Rows
}

func (r *rowsWrap) Next() bool {
return r.rows.Next()
}

func (r *rowsWrap) Scan(dest ...interface{}) error {
return r.rows.Scan(dest...)
}

func (r *rowsWrap) Close() error {
r.rows.Close()
return nil
}
58 changes: 58 additions & 0 deletions executor/adapters/pgx5/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package pgx4

import (
"context"
"fmt"

"github.com/insei/gerpo/executor/adapters/placeholder"
extypes "github.com/insei/gerpo/executor/types"
"github.com/jackc/pgx/v5"
)

type txWrap struct {
commited bool
rollbackUnlessCommittedNeeded bool
tx pgx.Tx
}

func (t txWrap) Rollback() error {
return t.tx.Rollback(context.Background())
}

func (t txWrap) Commit() error {
return t.tx.Commit(context.Background())
}

func (t txWrap) RollbackUnlessCommitted() error {
if !t.commited && t.rollbackUnlessCommittedNeeded {
err := t.Rollback()
if err != nil {
return err
}
}
return nil
}

func (t txWrap) ExecContext(ctx context.Context, query string, args ...any) (extypes.Result, error) {
sql, err := placeholder.Dollar.ReplacePlaceholders(query)
if err != nil {
return nil, fmt.Errorf("failed to replace placeholders: %w", err)
}
res, err := t.tx.Exec(ctx, sql, args...)
if err != nil {
return nil, err
}
return &resultWrap{res: res}, nil
}

func (t txWrap) QueryContext(ctx context.Context, query string, args ...any) (extypes.Rows, error) {
sql, err := placeholder.Dollar.ReplacePlaceholders(query)
if err != nil {
return nil, fmt.Errorf("failed to replace placeholders: %w", err)
}
rows, err := t.tx.Query(ctx, sql, args...)
if err != nil {
return nil, err
}
return &rowsWrap{rows: rows}, nil
}
9 changes: 6 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/insei/fmap/v3 v3.1.2
github.com/jackc/pgconn v1.14.3
github.com/jackc/pgx/v4 v4.18.3
github.com/jackc/pgx/v5 v5.7.4
github.com/stretchr/testify v1.10.0
)

Expand All @@ -17,14 +18,16 @@ require (
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jackc/puddle v1.3.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.6.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/text v0.22.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
11 changes: 8 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwX
github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
Expand All @@ -65,17 +65,20 @@ github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQ
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA=
github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand Down Expand Up @@ -153,6 +156,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down