// Patial Tech. // Author, Ankit Patial package pgm import ( "context" "strconv" "strings" "github.com/jackc/pgx/v5" ) type ( Clause interface { Insert() InsertClause Select(fields ...Field) SelectClause Update() UpdateClause Delete() DeleteCluase } Execute interface { Exec(ctx context.Context) error ExecTx(ctx context.Context, tx pgx.Tx) error Stringer } Stringer interface { String() string } Conditioner interface { Condition(args *[]any, idx int) string } ) func And(cond ...Conditioner) Conditioner { return &CondGroup{op: " AND ", cond: cond} } func Or(cond ...Conditioner) Conditioner { return &CondGroup{op: " OR ", cond: cond} } func (cv *Cond) Condition(args *[]any, argIdx int) string { // 1. condition with subquery if cv.action == CondActionSubQuery { qStr, newArgs := cv.Val.(SelectClause).raw(*args) *args = newArgs return cv.Field + strings.Replace(cv.op, "$", qStr, 1) } // 2. normal condition var op string if cv.Val != nil { *args = append(*args, cv.Val) if strings.HasSuffix(cv.op, "$") { op = cv.op + strconv.Itoa(argIdx+1) } else { op = strings.Replace(cv.op, "$", "$"+strconv.Itoa(argIdx+1), 1) } } else { op = cv.op } if cv.action == CondActionNeedToClose { return cv.Field + op + ")" } return cv.Field + op } func (c *CondGroup) Condition(args *[]any, argIdx int) string { sb := getSB() defer putSB(sb) sb.WriteString("(") for i, cond := range c.cond { if i == 0 { sb.WriteString(cond.Condition(args, argIdx+i)) } else { sb.WriteString(c.op) sb.WriteString(cond.Condition(args, argIdx+i)) } } sb.WriteString(")") return sb.String() }