1
1
package main
2
2
3
3
import (
4
+ "bufio"
5
+ "bytes"
6
+ "errors"
7
+ "fmt"
8
+ "go/format"
9
+ "html/template"
4
10
"log"
11
+ "strings"
5
12
6
13
"github.com/stephen/sqlc-sql.js/internal/plugin"
14
+ "github.com/stephen/sqlc-sql.js/internal/sdk"
7
15
)
8
16
9
17
func main () {
10
18
req := & plugin.CodeGenRequest {}
11
19
// XXX: fail on req.Settings.Engine
12
20
// XXX: fail on type overrides
21
+ // XXX: fail on non-default schema
22
+ enums := buildEnums (req )
13
23
structs , err := buildStructs (req )
14
24
if err != nil {
15
25
panic (err )
@@ -20,5 +30,163 @@ func main() {
20
30
panic (err )
21
31
}
22
32
23
- log .Println (queries )
33
+ log .Println (queries , enums )
34
+ }
35
+
36
+ type tmplCtx struct {
37
+ Q string
38
+ Package string
39
+ Enums []Enum
40
+ Structs []Struct
41
+ GoQueries []Query
42
+
43
+ // TODO: Race conditions
44
+ SourceName string
45
+
46
+ EmitJSONTags bool
47
+ EmitDBTags bool
48
+ EmitPreparedQueries bool
49
+ EmitInterface bool
50
+ EmitEmptySlices bool
51
+ EmitMethodsWithDBArgument bool
52
+ UsesCopyFrom bool
53
+ UsesBatch bool
54
+ }
55
+
56
+ func generate (req * plugin.CodeGenRequest , enums []Enum , structs []Struct , queries []Query ) (* plugin.CodeGenResponse , error ) {
57
+ // i := &importer{
58
+ // Settings: req.Settings,
59
+ // Queries: queries,
60
+ // Enums: enums,
61
+ // Structs: structs,
62
+ // }
63
+
64
+ funcMap := template.FuncMap {
65
+ "lowerTitle" : sdk .LowerTitle ,
66
+ "comment" : sdk .DoubleSlashComment ,
67
+ "escape" : sdk .EscapeBacktick ,
68
+ // "imports": i.Imports,
69
+ "hasPrefix" : strings .HasPrefix ,
70
+ }
71
+
72
+ tmpl := template .Must (
73
+ template .New ("table" ).
74
+ Funcs (funcMap ).
75
+ ParseFS (
76
+ templates ,
77
+ "templates/*.tmpl" ,
78
+ "templates/*/*.tmpl" ,
79
+ ),
80
+ )
81
+
82
+ golang := req .Settings .Go
83
+ tctx := tmplCtx {
84
+ EmitInterface : golang .EmitInterface ,
85
+ EmitJSONTags : golang .EmitJsonTags ,
86
+ EmitDBTags : golang .EmitDbTags ,
87
+ EmitPreparedQueries : golang .EmitPreparedQueries ,
88
+ EmitEmptySlices : golang .EmitEmptySlices ,
89
+ EmitMethodsWithDBArgument : golang .EmitMethodsWithDbArgument ,
90
+ Q : "`" ,
91
+ Package : golang .Package ,
92
+ GoQueries : queries ,
93
+ Enums : enums ,
94
+ Structs : structs ,
95
+ }
96
+
97
+ if tctx .UsesCopyFrom {
98
+ return nil , errors .New (":copyfrom not supported" )
99
+ }
100
+
101
+ if tctx .UsesBatch {
102
+ return nil , errors .New (":batch* commands not supported" )
103
+ }
104
+
105
+ output := map [string ]string {}
106
+
107
+ execute := func (name , templateName string ) error {
108
+ var b bytes.Buffer
109
+ w := bufio .NewWriter (& b )
110
+ tctx .SourceName = name
111
+ err := tmpl .ExecuteTemplate (w , templateName , & tctx )
112
+ w .Flush ()
113
+ if err != nil {
114
+ return err
115
+ }
116
+ code , err := format .Source (b .Bytes ())
117
+ if err != nil {
118
+ fmt .Println (b .String ())
119
+ return fmt .Errorf ("source error: %w" , err )
120
+ }
121
+
122
+ if templateName == "queryFile" && golang .OutputFilesSuffix != "" {
123
+ name += golang .OutputFilesSuffix
124
+ }
125
+
126
+ if ! strings .HasSuffix (name , ".go" ) {
127
+ name += ".go"
128
+ }
129
+ output [name ] = string (code )
130
+ return nil
131
+ }
132
+
133
+ dbFileName := "db.go"
134
+ if golang .OutputDbFileName != "" {
135
+ dbFileName = golang .OutputDbFileName
136
+ }
137
+ modelsFileName := "models.go"
138
+ if golang .OutputModelsFileName != "" {
139
+ modelsFileName = golang .OutputModelsFileName
140
+ }
141
+ querierFileName := "querier.go"
142
+ if golang .OutputQuerierFileName != "" {
143
+ querierFileName = golang .OutputQuerierFileName
144
+ }
145
+ copyfromFileName := "copyfrom.go"
146
+ // TODO(Jille): Make this configurable.
147
+
148
+ batchFileName := "batch.go"
149
+
150
+ if err := execute (dbFileName , "dbFile" ); err != nil {
151
+ return nil , err
152
+ }
153
+ if err := execute (modelsFileName , "modelsFile" ); err != nil {
154
+ return nil , err
155
+ }
156
+ if golang .EmitInterface {
157
+ if err := execute (querierFileName , "interfaceFile" ); err != nil {
158
+ return nil , err
159
+ }
160
+ }
161
+ if tctx .UsesCopyFrom {
162
+ if err := execute (copyfromFileName , "copyfromFile" ); err != nil {
163
+ return nil , err
164
+ }
165
+ }
166
+ if tctx .UsesBatch {
167
+ if err := execute (batchFileName , "batchFile" ); err != nil {
168
+ return nil , err
169
+ }
170
+ }
171
+
172
+ files := map [string ]struct {}{}
173
+ for _ , gq := range queries {
174
+ files [gq .SourceName ] = struct {}{}
175
+ }
176
+
177
+ for source := range files {
178
+ if err := execute (source , "queryFile" ); err != nil {
179
+ return nil , err
180
+ }
181
+ }
182
+ resp := plugin.CodeGenResponse {}
183
+
184
+ for filename , code := range output {
185
+ resp .Files = append (resp .Files , & plugin.File {
186
+ Name : filename ,
187
+ Contents : []byte (code ),
188
+ })
189
+ }
190
+
191
+ return & resp , nil
24
192
}
0 commit comments