{{define "copyfromCodeGoSqlDriver"}} {{range .GoQueries}} {{if eq .Cmd ":copyfrom" }} var readerHandlerSequenceFor{{.MethodName}} uint32 = 1 func convertRowsFor{{.MethodName}}(w *io.PipeWriter, {{.Arg.SlicePair}}) { e := mysqltsv.NewEncoder(w, {{ len .Arg.CopyFromMySQLFields }}, nil) for _, row := range {{.Arg.Name}} { {{- with $arg := .Arg }} {{- range $arg.CopyFromMySQLFields}} {{- if eq .Type "string"}} e.AppendString({{if $arg.Struct}}row.{{.Name}}{{else}}row{{end}}) {{- else if or (eq .Type "[]byte") (eq .Type "json.RawMessage")}} e.AppendBytes({{if $arg.Struct}}row.{{.Name}}{{else}}row{{end}}) {{- else}} e.AppendValue({{if $arg.Struct}}row.{{.Name}}{{else}}row{{end}}) {{- end}} {{- end}} {{- end}} } w.CloseWithError(e.Close()) } {{range .Comments}}//{{.}} {{end -}} // {{.MethodName}} uses MySQL's LOAD DATA LOCAL INFILE and is not atomic. // // Errors and duplicate keys are treated as warnings and insertion will // continue, even without an error for some cases. Use this in a transaction // and use SHOW WARNINGS to check for any problems and roll back if you want to. // // Check the documentation for more information: // https://dev.mysql.com/doc/refman/8.0/en/load-data.html#load-data-error-handling func (q *Queries) {{.MethodName}}(ctx context.Context{{if $.EmitMethodsWithDBArgument}}, db DBTX{{end}}, {{.Arg.SlicePair}}) (int64, error) { pr, pw := io.Pipe() defer pr.Close() rh := fmt.Sprintf("{{.MethodName}}_%d", atomic.AddUint32(&readerHandlerSequenceFor{{.MethodName}}, 1)) mysql.RegisterReaderHandler(rh, func() io.Reader { return pr }) defer mysql.DeregisterReaderHandler(rh) go convertRowsFor{{.MethodName}}(pw, {{.Arg.Name}}) // The string interpolation is necessary because LOAD DATA INFILE requires // the file name to be given as a literal string. result, err := {{if (not $.EmitMethodsWithDBArgument)}}q.{{end}}db.ExecContext(ctx, fmt.Sprintf("LOAD DATA LOCAL INFILE '%s' INTO TABLE {{.TableIdentifierForMySQL}} %s ({{range $index, $name := .Arg.ColumnNames}}{{if gt $index 0}}, {{end}}{{$name}}{{end}})", "Reader::" + rh, mysqltsv.Escaping)) if err != nil { return 0, err } return result.RowsAffected() } {{end}} {{end}} {{end}}