@@ -10,7 +10,61 @@ import (
1010
1111// QueryablePGX interface for pgx Query method
1212type 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