Files
relspecgo/vendor/github.com/microsoft/go-mssqldb/bulkcopy_sql.go
T
Hein 337af294f3 chore(deps): update all dependencies
Fixes GO-2026-6629 (golang.org/x/text precis panic). Bumps bun and
bun/dialect/pgdialect together to v1.3.0; go directive now 1.26.0.
2026-10-12 09:31:55 +02:00

118 lines
3.1 KiB
Go

package mssql
import (
"context"
"database/sql/driver"
"encoding/json"
"errors"
)
type copyin struct {
cn *Conn
bulkcopy *Bulk
closed bool
}
type serializableBulkConfig struct {
TableName string
ColumnsName []string
Options BulkOptions
}
func (d *Driver) OpenConnection(dsn string) (*Conn, error) {
return d.open(context.Background(), dsn)
}
func (c *Conn) prepareCopyIn(ctx context.Context, query string) (_ driver.Stmt, err error) {
config_json := query[11:]
bulkconfig := serializableBulkConfig{}
err = json.Unmarshal([]byte(config_json), &bulkconfig)
if err != nil {
return
}
bulkcopy := c.CreateBulkContext(ctx, bulkconfig.TableName, bulkconfig.ColumnsName)
bulkcopy.Options = bulkconfig.Options
ci := &copyin{
cn: c,
bulkcopy: bulkcopy,
}
return ci, nil
}
// CopyIn creates a bulk import statement that can be passed to Prepare.
//
// table is the destination object name. It is treated as an object name and is
// quoted before it is sent to the server, so a name that is not a regular
// identifier does not need to be delimited by the caller. It may be qualified,
// as in "schema.table" or "database.schema.table", and individual parts may be
// delimited, as in "[my schema].[my table]".
//
// Because the destination is always an object name, a value that relied on
// being spliced into the statement as raw text no longer resolves. Pass
// "table" and options.Tablock rather than "table WITH (TABLOCK)". A name that
// cannot identify an object, because it is empty or has more than four parts,
// is reported before any statement is sent.
//
// columns are the destination column names, in the order their values are
// passed to Exec.
//
// Each options.Order entry names one or more columns to declare the data is
// already sorted by, as in "id" or "id ASC, name DESC". Column names are quoted
// the same way table is. A column name is separated from an optional trailing
// ASC or DESC sort direction by whitespace, and from the next column by a
// comma, so a column whose name ends in "asc" or "desc" or contains a comma has
// to be delimited by the caller to be told apart from a direction or a
// separator, as in "[sort desc]" or "[order, id]".
func CopyIn(table string, options BulkOptions, columns ...string) string {
bulkconfig := &serializableBulkConfig{TableName: table, Options: options, ColumnsName: columns}
config_json, err := json.Marshal(bulkconfig)
if err != nil {
panic(err)
}
stmt := "INSERTBULK " + string(config_json)
return stmt
}
func (ci *copyin) NumInput() int {
return -1
}
func (ci *copyin) Query(v []driver.Value) (r driver.Rows, err error) {
panic("should never be called")
}
func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
if ci.closed {
return nil, errors.New("copyin query is closed")
}
if len(v) == 0 {
rowCount, err := ci.bulkcopy.Done()
ci.closed = true
return driver.RowsAffected(rowCount), err
}
t := make([]interface{}, len(v))
for i, val := range v {
t[i] = val
}
err = ci.bulkcopy.AddRow(t)
if err != nil {
return
}
return driver.RowsAffected(0), nil
}
func (ci *copyin) Close() (err error) {
return nil
}