forked from ebhomengo/niki
ADD | general instant queries & debug sth
This commit is contained in:
parent
44bfde3c65
commit
9a219730a0
|
|
@ -32,7 +32,7 @@ func (db *DB) GetTransactionListByUserID(ctx context.Context, userID uint64, dbP
|
|||
scanTransaction, countParams, fetchParams,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, 0, richerror.New(op).WithErr(err)
|
||||
}
|
||||
|
||||
return transactionsList, totalItemsCount, nil
|
||||
|
|
@ -101,7 +101,7 @@ func (db *DB) GetTransactionListByUserID(ctx context.Context, userID uint64, dbP
|
|||
}
|
||||
|
||||
func scanTransaction(scanner postgres.Scanner) (transaction entity.Transaction, err error) {
|
||||
err = scanner.Scan(&transaction.UserID, &transaction.Currency, &transaction.Amount, &transaction.ActionType, &transaction.Timestamp, &transaction.CreatedAt)
|
||||
err = scanner.Scan(&transaction.ID, &transaction.UserID, &transaction.Amount, &transaction.Currency, &transaction.ActionType, &transaction.Timestamp, &transaction.CreatedAt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@ func (db *DB) InsertTransaction(ctx context.Context, transaction entity.Transact
|
|||
|
||||
}()
|
||||
|
||||
params := []any{transaction.UserID, transaction.Currency, transaction.Amount, transaction.ActionType, transaction.Timestamp}
|
||||
params := []any{transaction.UserID, transaction.Amount, transaction.Currency, transaction.ActionType, transaction.Timestamp}
|
||||
|
||||
_, execErr := tx.StmtExecContext(newCtx, stmt, params...)
|
||||
if execErr != nil {
|
||||
err = richerror.New(op).WithErr(execErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgCantInsertTransaction)
|
||||
err = richerror.New(op).WithErr(execErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.gocasts.ir/ebhomengo/niki/domain/wallet/entity"
|
||||
"git.gocasts.ir/ebhomengo/niki/pkg/database/postgres"
|
||||
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||
)
|
||||
|
||||
func (db *DB) GetWalletByUserID(ctx context.Context, UserID uint64) (entity.Wallet, error) {
|
||||
|
||||
const op = richerror.Op("Wallet.repo.GetWalletByUserID")
|
||||
|
||||
query := `SELECT * FROM wallets WHERE user_id = $1`
|
||||
|
||||
/////////////// use instant query
|
||||
|
||||
wallet, err := postgres.InstantQueryRowContext[entity.Wallet](ctx, postgres.StatementKeyWalletGetUserWallet, query, db.conn, scanWallet, UserID)
|
||||
if err != nil {
|
||||
return entity.Wallet{}, richerror.New(op).WithErr(err)
|
||||
}
|
||||
|
||||
return wallet, nil
|
||||
|
||||
//////////////////////normal
|
||||
|
||||
//stmt, stErr := db.conn.PrepareStatement(ctx, postgres.StatementKeyWalletGetUserWallet, query)
|
||||
//if stErr != nil {
|
||||
// return entity.Wallet{}, richerror.New(op).WithErr(stErr)
|
||||
//}
|
||||
//walletRow := db.conn.StmtQueryRowContext(ctx, stmt, UserID)
|
||||
//
|
||||
//wallet, sErr := scanWallet(walletRow)
|
||||
//
|
||||
//if sErr != nil {
|
||||
// return entity.Wallet{}, richerror.New(op).WithErr(sErr)
|
||||
//}
|
||||
//
|
||||
//return wallet, nil
|
||||
|
||||
}
|
||||
|
||||
func scanWallet(scanner postgres.Scanner) (entity.Wallet, error) {
|
||||
|
||||
var wallet entity.Wallet
|
||||
|
||||
err := scanner.Scan(&wallet.ID, &wallet.UserID, &wallet.Balance, &wallet.Currency, &wallet.Status, &wallet.UpdatedAt)
|
||||
if err != nil {
|
||||
return entity.Wallet{}, err
|
||||
}
|
||||
|
||||
return wallet, nil
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.gocasts.ir/ebhomengo/niki/domain/wallet/entity"
|
||||
"git.gocasts.ir/ebhomengo/niki/pkg/database/postgres"
|
||||
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||
)
|
||||
|
||||
func (db *DB) GetWalletByUserID(ctx context.Context, UserID uint64) (entity.Wallet, error) {
|
||||
const op = richerror.Op("Wallet.repo.GetWalletByUserID")
|
||||
query := `SELECT * FROM wallets WHERE user_id = $1`
|
||||
stmt, stErr := db.conn.PrepareStatement(ctx, postgres.StatementKeyWalletGetUserWallet, query)
|
||||
if stErr != nil {
|
||||
return entity.Wallet{}, richerror.New(op).WithErr(stErr)
|
||||
}
|
||||
walletRow := db.conn.StmtQueryRowContext(ctx, stmt, UserID)
|
||||
|
||||
wallet, sErr := scanWallet(walletRow)
|
||||
|
||||
if sErr != nil {
|
||||
return entity.Wallet{}, richerror.New(op).WithErr(sErr)
|
||||
}
|
||||
|
||||
return wallet, nil
|
||||
|
||||
}
|
||||
|
||||
func scanWallet(scanner postgres.Scanner) (entity.Wallet, error) {
|
||||
|
||||
var wallet entity.Wallet
|
||||
|
||||
err := scanner.Scan(&wallet.ID, &wallet.Balance, &wallet.Currency, &wallet.Status, &wallet.UpdatedAt)
|
||||
if err != nil {
|
||||
return entity.Wallet{}, err
|
||||
}
|
||||
|
||||
return wallet, nil
|
||||
}
|
||||
|
|
@ -22,11 +22,11 @@ func (s Service) CreateTransaction(ctx context.Context, request param.CreateTran
|
|||
Timestamp: request.Timestamp,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
err := s.repo.InsertTransaction(ctx, transaction)
|
||||
balance, err := s.repo.InsertTransaction(ctx, transaction)
|
||||
if err != nil {
|
||||
return param.InsertTransactionResponse{}, richerror.New(op).WithErr(err)
|
||||
}
|
||||
|
||||
return param.InsertTransactionResponse{}, nil
|
||||
return param.InsertTransactionResponse{Balance: balance}, nil
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
type Repository interface {
|
||||
GetTransactionListByUserID(ctx context.Context, UserID uint64, DBPagination postgres.DBPagination) ([]entity.Transaction, int64, error)
|
||||
GetWalletByUserID(ctx context.Context, UserID uint64) (entity.Wallet, error)
|
||||
InsertTransaction(ctx context.Context, transaction entity.Transaction) error
|
||||
InsertTransaction(ctx context.Context, transaction entity.Transaction) (float64, error)
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@ package postgres
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
|
||||
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||
_ "github.com/jackc/pgx/v5/stdlib"
|
||||
)
|
||||
|
||||
|
|
@ -111,3 +114,96 @@ func (db *DB) StmtExecContext(ctx context.Context, stmt *sql.Stmt, args ...any)
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
///////////////////////// generic query
|
||||
|
||||
type ScannerFunc[T any] func(scanner Scanner) (T, error)
|
||||
|
||||
func InstantQueryContext[T any](ctx context.Context, stmtKey statementKey, query string, conn *DB, scanner ScannerFunc[T], args ...any) ([]T, error) {
|
||||
const op = richerror.Op("postgres.InstantQueryContext")
|
||||
|
||||
readyStmt, err := conn.PrepareStatement(ctx, stmtKey, query)
|
||||
|
||||
if err != nil {
|
||||
return nil, richerror.New(op).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
}
|
||||
|
||||
rows, qErr := readyStmt.QueryContext(ctx, args...)
|
||||
|
||||
if qErr != nil {
|
||||
return nil, richerror.New(op).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var itemsList []T
|
||||
|
||||
for rows.Next() {
|
||||
|
||||
item, sErr := scanner(rows)
|
||||
if sErr != nil {
|
||||
return nil, richerror.New(op).WithErr(sErr).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
|
||||
}
|
||||
|
||||
itemsList = append(itemsList, item)
|
||||
|
||||
}
|
||||
|
||||
if rErr := rows.Err(); rErr != nil {
|
||||
return nil, richerror.New(op).WithErr(rErr).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
|
||||
}
|
||||
|
||||
return itemsList, nil
|
||||
|
||||
}
|
||||
|
||||
func InstantQueryRowContext[T any](ctx context.Context, stmtKey statementKey, query string, conn *DB, scanner ScannerFunc[T], args ...any) (item T, err error) {
|
||||
const op = richerror.Op("postgres.InstantQueryRowContext")
|
||||
readyStmt, sErr := conn.PrepareStatement(ctx, stmtKey, query)
|
||||
|
||||
if sErr != nil {
|
||||
err = richerror.New(op).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
return
|
||||
}
|
||||
|
||||
row := readyStmt.QueryRowContext(ctx, args...)
|
||||
|
||||
item, scErr := scanner(row)
|
||||
if scErr != nil {
|
||||
if errors.Is(scErr, sql.ErrNoRows) {
|
||||
err = richerror.New(op).WithErr(scErr).WithKind(richerror.KindNotFound).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
|
||||
return
|
||||
|
||||
}
|
||||
err = richerror.New(op).WithErr(scErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
if rErr := row.Err(); rErr != nil {
|
||||
err = richerror.New(op).WithErr(rErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func InstantExecContext(ctx context.Context, stmtKey statementKey, query string, conn *DB, args ...any) (sql.Result, error) {
|
||||
const op = richerror.Op("postgres.InstantExecContext")
|
||||
|
||||
readyStmt, err := conn.PrepareStatement(ctx, stmtKey, query)
|
||||
|
||||
if err != nil {
|
||||
return nil, richerror.New(op)
|
||||
}
|
||||
|
||||
result, err := readyStmt.ExecContext(ctx, args...)
|
||||
if err != nil {
|
||||
return nil, richerror.New(op)
|
||||
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ type DBPagination struct {
|
|||
PageSize int64
|
||||
}
|
||||
|
||||
type ScannerFunc[T any] func(scanner Scanner) (T, error)
|
||||
|
||||
func PageNumberPagination[T any](ctx context.Context, countQuery string, fetchQuery string, conn *DB, countQueryStmt statementKey, fetchQueryStmt statementKey, op richerror.Op, scanner ScannerFunc[T], countParams []any, fetchParams []any) ([]T, int64, error) {
|
||||
|
||||
var totalCount int64
|
||||
|
|
@ -78,7 +76,7 @@ func PageNumberPagination[T any](ctx context.Context, countQuery string, fetchQu
|
|||
|
||||
if qErr := queryRows.Err(); qErr != nil {
|
||||
|
||||
return nil, 0, richerror.New(op).WithErr(qErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
|
||||
return nil, 0, richerror.New(op).WithErr(qErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
}
|
||||
|
||||
return itemsList, totalCount, nil
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ package postgres
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
|
||||
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
|
|
@ -176,3 +179,99 @@ func (tx *TxConn) StmtExecContext(ctx context.Context, stmt *sql.Stmt, args ...a
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
///////////////////////// generic query
|
||||
|
||||
func TXInstantQueryContext[T any](ctx context.Context, txConn *sql.Tx, stmtKey statementKey, query string, conn *DB, scanner ScannerFunc[T], args ...any) ([]T, error) {
|
||||
const op = richerror.Op("postgres.TXInstantQueryContext")
|
||||
|
||||
stmt, err := conn.PrepareStatement(ctx, stmtKey, query)
|
||||
|
||||
if err != nil {
|
||||
return nil, richerror.New(op).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
}
|
||||
|
||||
txStmt := txConn.StmtContext(ctx, stmt)
|
||||
|
||||
rows, qErr := txStmt.QueryContext(ctx, args...)
|
||||
|
||||
if qErr != nil {
|
||||
return nil, richerror.New(op).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var itemsList []T
|
||||
|
||||
for rows.Next() {
|
||||
|
||||
item, sErr := scanner(rows)
|
||||
if sErr != nil {
|
||||
return nil, richerror.New(op).WithErr(sErr).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
|
||||
}
|
||||
|
||||
itemsList = append(itemsList, item)
|
||||
|
||||
}
|
||||
|
||||
if rErr := rows.Err(); rErr != nil {
|
||||
return nil, richerror.New(op).WithErr(rErr).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
|
||||
}
|
||||
|
||||
return itemsList, nil
|
||||
|
||||
}
|
||||
|
||||
func TXInstantQueryRowContext[T any](ctx context.Context, txConn *sql.Tx, stmtKey statementKey, query string, conn *DB, scanner ScannerFunc[T], args ...any) (item T, err error) {
|
||||
const op = richerror.Op("postgres.TXInstantQueryRowContext")
|
||||
|
||||
stmt, sErr := conn.PrepareStatement(ctx, stmtKey, query)
|
||||
|
||||
if sErr != nil {
|
||||
err = richerror.New(op).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
return
|
||||
}
|
||||
txStmt := txConn.StmtContext(ctx, stmt)
|
||||
|
||||
row := txStmt.QueryRowContext(ctx, args...)
|
||||
|
||||
item, scErr := scanner(row)
|
||||
if scErr != nil {
|
||||
if errors.Is(scErr, sql.ErrNoRows) {
|
||||
err = richerror.New(op).WithErr(scErr).WithKind(richerror.KindNotFound).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
|
||||
return
|
||||
|
||||
}
|
||||
err = richerror.New(op).WithErr(scErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgCantScanQueryResult)
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
if rErr := row.Err(); rErr != nil {
|
||||
err = richerror.New(op).WithErr(rErr).WithKind(richerror.KindUnexpected).WithMessage(errmsg.ErrorMsgFailedQuery)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func TXInstantExecContext(ctx context.Context, txConn *sql.Tx, stmtKey statementKey, query string, conn *DB, args ...any) (sql.Result, error) {
|
||||
const op = richerror.Op("postgres.TXInstantExecContext")
|
||||
|
||||
stmt, err := conn.PrepareStatement(ctx, stmtKey, query)
|
||||
|
||||
if err != nil {
|
||||
return nil, richerror.New(op)
|
||||
}
|
||||
txStmt := txConn.StmtContext(ctx, stmt)
|
||||
|
||||
result, err := txStmt.ExecContext(ctx, args...)
|
||||
if err != nil {
|
||||
return nil, richerror.New(op)
|
||||
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,9 +58,7 @@ const (
|
|||
ErrorMsgInvalidRefreshToken = "invalid refresh token"
|
||||
ErrorMsgInvalidBenefactorStatus = "invalid benefactor status"
|
||||
ErrorMsgInvalidAction = "action invalid"
|
||||
ErrorMsgCantUpsertBalance = "cant update balance" // wallet
|
||||
ErrorMsgCantGetBalance = "cant update balance" // wallet
|
||||
ErrorMsgCantInsertTransaction = "cant insert transaction" // wallet
|
||||
ErrorMsgFailedQuery = "query failed" // wallet
|
||||
ErrorMsgCantUpsertBalance = "cant update balance" // wallet
|
||||
ErrorMsgFailedQuery = "query failed" // wallet
|
||||
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue