Skip to content

Commit d590f72

Browse files
authored
Merge pull request #495 from DevX86/pgx
feat: add preliminary json support for qrm_pgx.
2 parents 0a336d6 + 837bd92 commit d590f72

File tree

1 file changed

+101
-1
lines changed

1 file changed

+101
-1
lines changed

qrm/qrm_pgx.go

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,61 @@ import (
1010

1111
// QueryablePGX interface for pgx Query method
1212
type QueryablePGX interface {
13-
Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)
13+
Query(ctx context.Context, query string, args ...any) (pgx.Rows, error)
14+
}
15+
16+
// QueryPGXJsonObj executes a SQL query that returns a JSON object, unmarshals the result into the provided destination,
17+
// and returns the number of rows processed.
18+
//
19+
// The query must return exactly one row with a single column; otherwise, an error is returned.
20+
//
21+
// Parameters:
22+
//
23+
// ctx - The context for managing query execution (timeouts, cancellations).
24+
// db - The database connection or transaction that implements the QueryablePGX interface.
25+
// query - The SQL query string to be executed.
26+
// args - A slice of arguments to be used with the query.
27+
// destPtr - A pointer to the variable where the unmarshaled JSON result will be stored.
28+
// The destination should be a pointer to a struct or map[string]any.
29+
//
30+
// Returns:
31+
//
32+
// rowsProcessed - The number of rows processed by the query execution.
33+
// err - An error if query execution or unmarshaling fails.
34+
func QueryPGXJsonObj(ctx context.Context, db QueryablePGX, query string, args []interface{}, destPtr interface{}) (rowsProcessed int64, err error) {
35+
must.BeInitializedPtr(destPtr, "jet: destination is nil")
36+
must.BeTypeKind(destPtr, reflect.Ptr, jsonDestObjErr)
37+
destType := reflect.TypeOf(destPtr).Elem()
38+
must.BeTrue(destType.Kind() == reflect.Struct || destType.Kind() == reflect.Map, jsonDestObjErr)
39+
40+
return queryPGXJson(ctx, db, query, args, destPtr)
41+
}
42+
43+
// QueryPGXJsonArr executes a SQL query that returns a JSON array, unmarshals the result into the provided destination,
44+
// and returns the number of rows processed.
45+
//
46+
// The query must return exactly one row with a single column; otherwise, an error is returned.
47+
//
48+
// Parameters:
49+
//
50+
// ctx - The context for managing query execution (timeouts, cancellations).
51+
// db - The database connection or transaction that implements the QueryablePGX interface.
52+
// query - The SQL query string to be executed.
53+
// args - A slice of arguments to be used with the query.
54+
// destPtr - A pointer to the variable where the unmarshaled JSON array will be stored.
55+
// The destination should be a pointer to a slice of structs or []map[string]any.
56+
//
57+
// Returns:
58+
//
59+
// rowsProcessed - The number of rows processed by the query execution.
60+
// err - An error if query execution or unmarshaling fails.
61+
func QueryPGXJsonArr(ctx context.Context, db QueryablePGX, query string, args []interface{}, destPtr interface{}) (rowsProcessed int64, err error) {
62+
must.BeInitializedPtr(destPtr, "jet: destination is nil")
63+
must.BeTypeKind(destPtr, reflect.Ptr, jsonDestArrErr)
64+
destType := reflect.TypeOf(destPtr).Elem()
65+
must.BeTrue(destType.Kind() == reflect.Slice, jsonDestArrErr)
66+
67+
return queryPGXJson(ctx, db, query, args, destPtr)
1468
}
1569

1670
// QueryPGX executes Query Result Mapping (QRM) of `query` with list of parametrized arguments `arg` over database connection `db`
@@ -106,3 +160,49 @@ func queryToSlicePGX(ctx context.Context, db QueryablePGX, query string, args []
106160

107161
return scanContext.rowNum, rows.Err()
108162
}
163+
164+
func queryPGXJson(ctx context.Context, db QueryablePGX, query string, args []interface{}, destPtr interface{}) (rowsProcessed int64, err error) {
165+
must.BeInitializedPtr(db, "jet: db is nil")
166+
167+
var rows pgx.Rows
168+
rows, err = db.Query(ctx, query, args...)
169+
170+
if err != nil {
171+
return 0, err
172+
}
173+
174+
defer rows.Close()
175+
176+
if !rows.Next() {
177+
err = rows.Err()
178+
if err != nil {
179+
return 0, err
180+
}
181+
return 0, ErrNoRows
182+
}
183+
184+
var jsonData []byte
185+
err = rows.Scan(&jsonData)
186+
187+
if err != nil {
188+
return 1, err
189+
}
190+
191+
if jsonData == nil {
192+
return 1, nil
193+
}
194+
195+
err = GlobalConfig.JsonUnmarshalFunc(jsonData, &destPtr)
196+
197+
if err != nil {
198+
return 1, fmt.Errorf("jet: invalid json, %w", err)
199+
}
200+
201+
if rows.Next() {
202+
return 1, fmt.Errorf("jet: query returned more then one row")
203+
}
204+
205+
rows.Close()
206+
207+
return 1, nil
208+
}

0 commit comments

Comments
 (0)