@@ -14,6 +14,7 @@ import (
1414 "fmt"
1515 "io"
1616 "os"
17+ "text/template"
1718)
1819
1920// Preparer is an interface used by Prepare.
@@ -58,21 +59,34 @@ type ExecerContext interface {
5859
5960// DotSql represents a dotSQL queries holder.
6061type DotSql struct {
61- queries map [string ]string
62+ queries map [string ]* template.Template
63+ data any
6264}
6365
64- func (d DotSql ) lookupQuery (name string ) (query string , err error ) {
65- query , ok := d .queries [name ]
66+ func (d DotSql ) WithData (data any ) DotSql {
67+ return DotSql {queries : d .queries , data : data }
68+ }
69+
70+ func (d DotSql ) lookupQuery (name string , data any ) (string , error ) {
71+ template , ok := d .queries [name ]
6672 if ! ok {
67- err = fmt .Errorf ("dotsql: '%s' could not be found" , name )
73+ return "" , fmt .Errorf ("dotsql: '%s' could not be found" , name )
74+ }
75+ if template == nil {
76+ return "" , nil
77+ }
78+ buffer := bytes .NewBufferString ("" )
79+ err := template .Execute (buffer , data )
80+ if err != nil {
81+ return "" , fmt .Errorf ("error parsing template: %w" , err )
6882 }
6983
70- return
84+ return buffer . String (), nil
7185}
7286
7387// Prepare is a wrapper for database/sql's Prepare(), using dotsql named query.
7488func (d DotSql ) Prepare (db Preparer , name string ) (* sql.Stmt , error ) {
75- query , err := d .lookupQuery (name )
89+ query , err := d .lookupQuery (name , d . data )
7690 if err != nil {
7791 return nil , err
7892 }
@@ -82,7 +96,7 @@ func (d DotSql) Prepare(db Preparer, name string) (*sql.Stmt, error) {
8296
8397// PrepareContext is a wrapper for database/sql's PrepareContext(), using dotsql named query.
8498func (d DotSql ) PrepareContext (ctx context.Context , db PreparerContext , name string ) (* sql.Stmt , error ) {
85- query , err := d .lookupQuery (name )
99+ query , err := d .lookupQuery (name , d . data )
86100 if err != nil {
87101 return nil , err
88102 }
@@ -92,7 +106,7 @@ func (d DotSql) PrepareContext(ctx context.Context, db PreparerContext, name str
92106
93107// Query is a wrapper for database/sql's Query(), using dotsql named query.
94108func (d DotSql ) Query (db Queryer , name string , args ... interface {}) (* sql.Rows , error ) {
95- query , err := d .lookupQuery (name )
109+ query , err := d .lookupQuery (name , d . data )
96110 if err != nil {
97111 return nil , err
98112 }
@@ -102,7 +116,7 @@ func (d DotSql) Query(db Queryer, name string, args ...interface{}) (*sql.Rows,
102116
103117// QueryContext is a wrapper for database/sql's QueryContext(), using dotsql named query.
104118func (d DotSql ) QueryContext (ctx context.Context , db QueryerContext , name string , args ... interface {}) (* sql.Rows , error ) {
105- query , err := d .lookupQuery (name )
119+ query , err := d .lookupQuery (name , d . data )
106120 if err != nil {
107121 return nil , err
108122 }
@@ -112,7 +126,7 @@ func (d DotSql) QueryContext(ctx context.Context, db QueryerContext, name string
112126
113127// QueryRow is a wrapper for database/sql's QueryRow(), using dotsql named query.
114128func (d DotSql ) QueryRow (db QueryRower , name string , args ... interface {}) (* sql.Row , error ) {
115- query , err := d .lookupQuery (name )
129+ query , err := d .lookupQuery (name , d . data )
116130 if err != nil {
117131 return nil , err
118132 }
@@ -122,7 +136,7 @@ func (d DotSql) QueryRow(db QueryRower, name string, args ...interface{}) (*sql.
122136
123137// QueryRowContext is a wrapper for database/sql's QueryRowContext(), using dotsql named query.
124138func (d DotSql ) QueryRowContext (ctx context.Context , db QueryRowerContext , name string , args ... interface {}) (* sql.Row , error ) {
125- query , err := d .lookupQuery (name )
139+ query , err := d .lookupQuery (name , d . data )
126140 if err != nil {
127141 return nil , err
128142 }
@@ -132,7 +146,7 @@ func (d DotSql) QueryRowContext(ctx context.Context, db QueryRowerContext, name
132146
133147// Exec is a wrapper for database/sql's Exec(), using dotsql named query.
134148func (d DotSql ) Exec (db Execer , name string , args ... interface {}) (sql.Result , error ) {
135- query , err := d .lookupQuery (name )
149+ query , err := d .lookupQuery (name , d . data )
136150 if err != nil {
137151 return nil , err
138152 }
@@ -142,7 +156,7 @@ func (d DotSql) Exec(db Execer, name string, args ...interface{}) (sql.Result, e
142156
143157// ExecContext is a wrapper for database/sql's ExecContext(), using dotsql named query.
144158func (d DotSql ) ExecContext (ctx context.Context , db ExecerContext , name string , args ... interface {}) (sql.Result , error ) {
145- query , err := d .lookupQuery (name )
159+ query , err := d .lookupQuery (name , d . data )
146160 if err != nil {
147161 return nil , err
148162 }
@@ -152,11 +166,11 @@ func (d DotSql) ExecContext(ctx context.Context, db ExecerContext, name string,
152166
153167// Raw returns the query, everything after the --name tag
154168func (d DotSql ) Raw (name string ) (string , error ) {
155- return d .lookupQuery (name )
169+ return d .lookupQuery (name , d . data )
156170}
157171
158172// QueryMap returns a map[string]string of loaded queries
159- func (d DotSql ) QueryMap () map [string ]string {
173+ func (d DotSql ) QueryMap () map [string ]* template. Template {
160174 return d .queries
161175}
162176
@@ -165,11 +179,18 @@ func Load(r io.Reader) (*DotSql, error) {
165179 scanner := & Scanner {}
166180 queries := scanner .Run (bufio .NewScanner (r ))
167181
168- dotsql := & DotSql {
169- queries : queries ,
182+ templates := make (map [string ]* template.Template )
183+ for k , v := range queries {
184+ tmpl , err := template .New (k ).Parse (v )
185+ if err != nil {
186+ return nil , err
187+ }
188+ templates [k ] = tmpl
170189 }
171190
172- return dotsql , nil
191+ return & DotSql {
192+ queries : templates ,
193+ }, nil
173194}
174195
175196// LoadFromFile imports SQL queries from the file.
@@ -193,7 +214,7 @@ func LoadFromString(sql string) (*DotSql, error) {
193214// It's in-order, so the last source will override queries with the same name
194215// in the previous arguments if any.
195216func Merge (dots ... * DotSql ) * DotSql {
196- queries := make (map [string ]string )
217+ queries := make (map [string ]* template. Template )
197218
198219 for _ , dot := range dots {
199220 for k , v := range dot .QueryMap () {
0 commit comments