-
Notifications
You must be signed in to change notification settings - Fork 777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Please rename
:copyFrom
to:copyfrom
. - We need to return an error if you try to use
:copyfrom
using 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.