-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* added pgx v5 * added pgx v4 --------- Co-authored-by: maranqz <[email protected]>
- Loading branch information
Showing
23 changed files
with
1,668 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//go:build go1.16 | ||
// +build go1.16 | ||
|
||
//nolint:ireturn,nolintlint // return Tr for external usage. | ||
//revive:disable:package-comments | ||
package pgxv4 | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/avito-tech/go-transaction-manager/trm" | ||
trmcontext "github.com/avito-tech/go-transaction-manager/trm/context" | ||
) | ||
|
||
// DefaultCtxGetter is the CtxGetter with settings.DefaultCtxKey. | ||
// | ||
//nolint:gochecknoglobals | ||
var DefaultCtxGetter = NewCtxGetter(trmcontext.DefaultManager) | ||
|
||
// CtxGetter gets Tr from trm.СtxManager by casting trm.Transaction to Tr. | ||
type CtxGetter struct { | ||
ctxManager trm.СtxManager | ||
} | ||
|
||
//revive:disable:exported | ||
func NewCtxGetter(c trm.СtxManager) *CtxGetter { | ||
return &CtxGetter{ctxManager: c} | ||
} | ||
|
||
func (c *CtxGetter) DefaultTrOrDB(ctx context.Context, db Tr) Tr { | ||
if tr := c.ctxManager.Default(ctx); tr != nil { | ||
return c.convert(tr) | ||
} | ||
|
||
return db | ||
} | ||
|
||
func (c *CtxGetter) TrOrDB(ctx context.Context, key trm.CtxKey, db Tr) Tr { | ||
if tr := c.ctxManager.ByKey(ctx, key); tr != nil { | ||
return c.convert(tr) | ||
} | ||
|
||
return db | ||
} | ||
|
||
func (c *CtxGetter) convert(tr trm.Transaction) Tr { | ||
if tx, ok := tr.Transaction().(Tr); ok { | ||
return tx | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
//go:build go1.16 | ||
// +build go1.16 | ||
|
||
// Package pgxv4 is an implementation of trm.Transaction interface by Transaction for pgx.Tx. | ||
package pgxv4 | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/jackc/pgconn" | ||
"github.com/jackc/pgx/v4" | ||
) | ||
|
||
// Tr is an interface to work with pgx.Conn, pgxpool.Conn or pgxpool.Pool | ||
// StmtContext and Stmt are not implemented! | ||
type Tr interface { | ||
Begin(ctx context.Context) (pgx.Tx, error) | ||
BeginFunc(ctx context.Context, f func(pgx.Tx) error) (err error) | ||
|
||
CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error) | ||
SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults | ||
|
||
Exec(ctx context.Context, sql string, arguments ...interface{}) (commandTag pgconn.CommandTag, err error) | ||
Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error) | ||
QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row | ||
QueryFunc(ctx context.Context, sql string, args []interface{}, scans []interface{}, f func(pgx.QueryFuncRow) error) (pgconn.CommandTag, error) | ||
} | ||
|
||
// Transactional is an interface to work with pgx.Conn, pgxpool.Conn or pgxpool.Pool. | ||
type Transactional interface { | ||
BeginTx(ctx context.Context, txOptions pgx.TxOptions) (pgx.Tx, error) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
//go:build with_real_db | ||
// +build with_real_db | ||
|
||
package pgxv4_test | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/jackc/pgx/v4/pgxpool" | ||
|
||
trmpgx "github.com/avito-tech/go-transaction-manager/pgxv4" | ||
"github.com/avito-tech/go-transaction-manager/trm/manager" | ||
) | ||
|
||
// Example demonstrates the implementation of the Repository pattern by trm.Manager. | ||
func Example() { | ||
ctx := context.Background() | ||
|
||
uri := fmt.Sprintf("postgres://%s:%s@%s:%d/%s", | ||
"user", "pass", "localhost", 5432, "db", | ||
) | ||
|
||
pool, err := pgxpool.Connect(ctx, uri) | ||
checkErr(err) | ||
|
||
defer pool.Close() | ||
|
||
sqlStmt := `CREATE TABLE IF NOT EXISTS users_v4 (user_id serial, username TEXT)` | ||
_, err = pool.Exec(ctx, sqlStmt) | ||
checkErr(err, sqlStmt) | ||
|
||
r := newRepo(pool, trmpgx.DefaultCtxGetter) | ||
trManager := manager.Must(trmpgx.NewDefaultFactory(pool)) | ||
|
||
u := &user{ | ||
Username: "username", | ||
} | ||
|
||
err = trManager.Do(ctx, func(ctx context.Context) error { | ||
if err := r.Save(ctx, u); err != nil { | ||
return err | ||
} | ||
|
||
return trManager.Do(ctx, func(ctx context.Context) error { | ||
u.Username = "new_username" | ||
|
||
return r.Save(ctx, u) | ||
}) | ||
}) | ||
checkErr(err) | ||
|
||
userFromDB, err := r.GetByID(ctx, u.ID) | ||
checkErr(err) | ||
|
||
fmt.Println(userFromDB) | ||
|
||
// Output: &{1 new_username} | ||
} | ||
|
||
type repo struct { | ||
db *pgxpool.Pool | ||
getter *trmpgx.CtxGetter | ||
} | ||
|
||
func newRepo(db *pgxpool.Pool, c *trmpgx.CtxGetter) *repo { | ||
repo := &repo{ | ||
db: db, | ||
getter: c, | ||
} | ||
|
||
return repo | ||
} | ||
|
||
type user struct { | ||
ID int64 | ||
Username string | ||
} | ||
|
||
func (r *repo) GetByID(ctx context.Context, id int64) (*user, error) { | ||
query := `SELECT * FROM users_v4 WHERE user_id=$1` | ||
|
||
conn := r.getter.DefaultTrOrDB(ctx, r.db) | ||
row := conn.QueryRow(ctx, query, id) | ||
|
||
user := &user{} | ||
|
||
err := row.Scan(&user.ID, &user.Username) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return user, nil | ||
} | ||
|
||
func (r *repo) Save(ctx context.Context, u *user) error { | ||
isNew := u.ID == 0 | ||
conn := r.getter.DefaultTrOrDB(ctx, r.db) | ||
|
||
if !isNew { | ||
query := `UPDATE users_v4 SET username = $1 WHERE user_id = $2` | ||
|
||
if _, err := conn.Exec(ctx, query, u.Username, u.ID); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
query := `INSERT INTO users_v4 (username) VALUES ($1) RETURNING user_id` | ||
|
||
err := conn.QueryRow(ctx, query, u.Username).Scan(&u.ID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func checkErr(err error, args ...interface{}) { | ||
if err != nil { | ||
panic(fmt.Sprint(append([]interface{}{err}, args...)...)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//go:build go1.16 | ||
// +build go1.16 | ||
|
||
package pgxv4 | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/avito-tech/go-transaction-manager/trm" | ||
) | ||
|
||
// NewDefaultFactory creates default trm.Transaction(pgx.Tx). | ||
func NewDefaultFactory(db Transactional) trm.TrFactory { | ||
return NewFactory(db) | ||
} | ||
|
||
// NewFactory creates trm.Transaction(pgx.Tx). | ||
func NewFactory(db Transactional) trm.TrFactory { | ||
return func(ctx context.Context, trms trm.Settings) (context.Context, trm.Transaction, error) { | ||
s, _ := trms.(Settings) | ||
|
||
return NewTransaction(ctx, s.TxOpts(), db) | ||
} | ||
} |
Oops, something went wrong.