6
6
"errors"
7
7
"fmt"
8
8
"reflect"
9
+ "strings"
9
10
"time"
10
11
11
12
"github.com/domonda/go-sqldb"
@@ -58,11 +59,33 @@ func QueryValueOrDefault[T any](ctx context.Context, query string, args ...any)
58
59
return value , err
59
60
}
60
61
61
- // QueryStruct uses the passed pkValue+pkValues to query a table row
62
+ // QueryRowStruct queries a row and scans it as struct.
63
+ func QueryRowStruct [S ~ struct {}](ctx context.Context , query string , args ... any ) (row * S , err error ) {
64
+ err = Conn (ctx ).QueryRow (query , args ... ).ScanStruct (& row )
65
+ if err != nil {
66
+ return nil , err
67
+ }
68
+ return row , nil
69
+ }
70
+
71
+ // QueryRowStructOrNil queries a row and scans it as struct
72
+ // or returns nil in case of sql.ErrNoRows.
73
+ func QueryRowStructOrNil [S ~ struct {}](ctx context.Context , query string , args ... any ) (row * S , err error ) {
74
+ err = Conn (ctx ).QueryRow (query , args ... ).ScanStruct (& row )
75
+ if err != nil {
76
+ if errors .Is (err , sql .ErrNoRows ) {
77
+ return nil , nil
78
+ }
79
+ return nil , err
80
+ }
81
+ return row , nil
82
+ }
83
+
84
+ // GetRow uses the passed pkValue+pkValues to query a table row
62
85
// and scan it into a struct of type S that must have tagged fields
63
86
// with primary key flags to identify the primary key column names
64
87
// for the passed pkValue+pkValues and a table name.
65
- func QueryStruct [S any ](ctx context.Context , pkValue any , pkValues ... any ) (row * S , err error ) {
88
+ func GetRow [S ~ struct {} ](ctx context.Context , pkValue any , pkValues ... any ) (row * S , err error ) {
66
89
// Using explicit first pkValue value
67
90
// to not be able to compile without any value
68
91
pkValues = append ([]any {pkValue }, pkValues ... )
@@ -78,25 +101,26 @@ func QueryStruct[S any](ctx context.Context, pkValue any, pkValues ...any) (row
78
101
if len (pkColumns ) != len (pkValues ) {
79
102
return nil , fmt .Errorf ("got %d primary key values, but struct %s has %d primary key fields" , len (pkValues ), t , len (pkColumns ))
80
103
}
81
- query := fmt .Sprintf (`SELECT * FROM %s WHERE "%s" = $1` , table , pkColumns [0 ])
104
+ var query strings.Builder
105
+ fmt .Fprintf (& query , `SELECT * FROM %s WHERE "%s" = $1` , table , pkColumns [0 ]) //#nosec G104
82
106
for i := 1 ; i < len (pkColumns ); i ++ {
83
- query += fmt .Sprintf ( ` AND "%s" = $%d` , pkColumns [i ], i + 1 )
107
+ fmt .Fprintf ( & query , ` AND "%s" = $%d` , pkColumns [i ], i + 1 ) //#nosec G104
84
108
}
85
- err = conn .QueryRow (query , pkValues ... ).ScanStruct (& row )
109
+ err = conn .QueryRow (query . String () , pkValues ... ).ScanStruct (& row )
86
110
if err != nil {
87
111
return nil , err
88
112
}
89
113
return row , nil
90
114
}
91
115
92
- // QueryStructOrNil uses the passed pkValue+pkValues to query a table row
116
+ // GetRowOrNil uses the passed pkValue+pkValues to query a table row
93
117
// and scan it into a struct of type S that must have tagged fields
94
118
// with primary key flags to identify the primary key column names
95
119
// for the passed pkValue+pkValues and a table name.
96
120
// Returns nil as row and error if no row could be found with the
97
121
// passed pkValue+pkValues.
98
- func QueryStructOrNil [S any ](ctx context.Context , pkValue any , pkValues ... any ) (row * S , err error ) {
99
- row , err = QueryStruct [S ](ctx , pkValue , pkValues ... )
122
+ func GetRowOrNil [S ~ struct {} ](ctx context.Context , pkValue any , pkValues ... any ) (row * S , err error ) {
123
+ row , err = GetRow [S ](ctx , pkValue , pkValues ... )
100
124
if err != nil {
101
125
if errors .Is (err , sql .ErrNoRows ) {
102
126
return nil , nil
0 commit comments