Implement support for pgx's CopyFrom#1352
Conversation
2fe607f to
720a65d
Compare
This allows type-safe bulk loading with great performance. I didn't implement it for Python and Kotlin. This change is fully backwards compatible, as it only changes the DBTX interface when someone adds their first :copyFrom query (at which point it's reasonable to require the CopyFrom method on the DBTX).
|
Any thoughts on this? |
kyleconroy
left a comment
There was a problem hiding this comment.
- Please rename
:copyFromto:copyfrom. - We need to return an error if you try to use
:copyfromusing stdlib PostgreSQL or MySQL - The newly generated code should live in a different file
Let me know if you have any questions.
| {{if eq .Cmd ":copyFrom"}} | ||
| // iteratorFor{{.MethodName}} implements pgx.CopyFromSource. | ||
| type iteratorFor{{.MethodName}} struct { | ||
| rows []{{.Arg.DefineType}} | ||
| skippedFirstNextCall bool | ||
| } | ||
|
|
||
| func (r *iteratorFor{{.MethodName}}) Next() bool { | ||
| if len(r.rows) == 0 { | ||
| return false | ||
| } | ||
| if !r.skippedFirstNextCall { | ||
| r.skippedFirstNextCall = true | ||
| return true | ||
| } | ||
| r.rows = r.rows[1:] | ||
| return len(r.rows) > 0 | ||
| } | ||
|
|
||
| func (r iteratorFor{{.MethodName}}) Values() ([]interface{}, error) { | ||
| return []interface{}{ | ||
| {{- if .Arg.Struct }} | ||
| {{- range .Arg.Struct.Fields }} | ||
| r.rows[0].{{.Name}}, | ||
| {{- end }} | ||
| {{- else }} | ||
| r.rows[0], | ||
| {{- end }} | ||
| }, nil | ||
| } | ||
|
|
||
| func (r iteratorFor{{.MethodName}}) Err() error { | ||
| return nil | ||
| } | ||
|
|
||
| {{range .Comments}}//{{.}} | ||
| {{end -}} | ||
| {{- if $.EmitMethodsWithDBArgument}} | ||
| func (q *Queries) {{.MethodName}}(ctx context.Context, db DBTX, {{.Arg.SlicePair}}) (int64, error) { | ||
| return db.CopyFrom(ctx, {{.TableIdentifier}}, {{.Arg.ColumnNames}}, &iteratorFor{{.MethodName}}{rows: {{.Arg.Name}}}) | ||
| {{- else}} | ||
| func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.SlicePair}}) (int64, error) { | ||
| return q.db.CopyFrom(ctx, {{.TableIdentifier}}, {{.Arg.ColumnNames}}, &iteratorFor{{.MethodName}}{rows: {{.Arg.Name}}}) | ||
| {{- end}} | ||
| } | ||
| {{end}} |
There was a problem hiding this comment.
Let's put this code into a different file, something called {query}_copyfrom.go
|
Thanks for the review :) Did you want a separate file for each query? What about settings to override the filename for those? And what about the MyQueryParams and MyQueryRow structs? Would they still be generated in querier.go, or should they be moved too? (If they'd have to be moved too, I'd template queryCode.tmpl twice, once for :copyfrom and once for the rest, but put their output in separate files.) |
Up to you! Probably easier to make it one file for each package.
That can come later in a follow-on PR.
We should keep those where they are today. Hope that help! |
|
Thanks! All done. Let me know when you want me to rebase+squash. |
I implemented my own feature request #1350.