Skip to content

Add tsql/batch support for sqlserver #1270

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions database/sqlserver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
| URL Query | WithInstance Config | Description |
|------------|---------------------|-------------|
| `x-migrations-table` | `MigrationsTable` | Name of the migrations table |
| `x-batch` | `BatchEnabled` | Enable drivers batch parsing |
| `username` | | enter the SQL Server Authentication user id or the Windows Authentication user id in the DOMAIN\User format. On Windows, if user id is empty or missing Single-Sign-On is used. |
| `password` | | The user's password. |
| `password` | | The user's password. |
| `host` | | The host to connect to. |
| `port` | | The port to connect to. |
| `instance` | | SQL Server instance name. |
Expand All @@ -24,7 +25,7 @@ See https://github.com/microsoft/go-mssqldb for full parameter list.

### Which go-mssqldb driver to us?

Please note that the deprecated `mssql` driver is not supported. Please use the newer `sqlserver` driver.
Please note that the deprecated `mssql` driver is not supported. Please use the newer `sqlserver` driver.
See https://github.com/microsoft/go-mssqldb#deprecated for more information.

### Official Support by migrate
Expand Down
39 changes: 30 additions & 9 deletions database/sqlserver/sqlserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/golang-migrate/migrate/v4/database"
"github.com/hashicorp/go-multierror"
mssql "github.com/microsoft/go-mssqldb" // mssql support
"github.com/microsoft/go-mssqldb/batch"
)

func init() {
Expand All @@ -27,6 +28,7 @@ var DefaultMigrationsTable = "schema_migrations"

var (
ErrNilConfig = fmt.Errorf("no config")
ErrInvalidBatchValue = fmt.Errorf("invalid x-batch value")
ErrNoDatabaseName = fmt.Errorf("no database name")
ErrNoSchema = fmt.Errorf("no schema")
ErrDatabaseDirty = fmt.Errorf("database is dirty")
Expand All @@ -45,6 +47,7 @@ type Config struct {
MigrationsTable string
DatabaseName string
SchemaName string
BatchEnabled bool
}

// SQL Server connection
Expand Down Expand Up @@ -168,9 +171,18 @@ func (ss *SQLServer) Open(url string) (database.Driver, error) {

migrationsTable := purl.Query().Get("x-migrations-table")

var batchEnabled bool
if q := purl.Query().Get("x-batch"); q != "" {
batchEnabled, err = strconv.ParseBool(q)
if err != nil {
return nil, fmt.Errorf("%w: '%s': %w", ErrInvalidBatchValue, q, err)
}
}

px, err := WithInstance(db, &Config{
DatabaseName: purl.Path,
MigrationsTable: migrationsTable,
BatchEnabled: batchEnabled,
})

if err != nil {
Expand Down Expand Up @@ -246,18 +258,27 @@ func (ss *SQLServer) Run(migration io.Reader) error {
}

// run migration
query := string(migr[:])
if _, err := ss.conn.ExecContext(context.Background(), query); err != nil {
if msErr, ok := err.(mssql.Error); ok {
message := fmt.Sprintf("migration failed: %s", msErr.Message)
if msErr.ProcName != "" {
message = fmt.Sprintf("%s (proc name %s)", msErr.Message, msErr.ProcName)
var queries []string
if ss.config.BatchEnabled {
queries = batch.Split(string(migr), "go")
} else {
queries = []string{string(migr)}
}

for _, query := range queries {
if _, err := ss.conn.ExecContext(context.Background(), query); err != nil {
fmt.Println("ASD")
fmt.Println(query)
if msErr, ok := err.(mssql.Error); ok {
message := fmt.Sprintf("migration failed: %s", msErr.Message)
if msErr.ProcName != "" {
message = fmt.Sprintf("%s (proc name %s)", msErr.Message, msErr.ProcName)
}
return database.Error{OrigErr: err, Err: message, Query: migr, Line: uint(msErr.LineNo)}
}
return database.Error{OrigErr: err, Err: message, Query: migr, Line: uint(msErr.LineNo)}
return database.Error{OrigErr: err, Err: "migration failed", Query: migr}
}
return database.Error{OrigErr: err, Err: "migration failed", Query: migr}
}

return nil
}

Expand Down
12 changes: 7 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ require (
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
Expand All @@ -74,8 +73,8 @@ require (
cloud.google.com/go/longrunning v0.5.5 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
Expand Down Expand Up @@ -118,7 +117,7 @@ require (
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
Expand Down Expand Up @@ -160,7 +159,7 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/pierrec/lz4/v4 v4.1.16 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
Expand Down Expand Up @@ -211,3 +210,6 @@ require (
modernc.org/token v1.0.0 // indirect
modernc.org/zappy v1.0.0 // indirect
)

// Remove once https://github.com/microsoft/go-mssqldb/pull/257 is merged.
replace github.com/microsoft/go-mssqldb => github.com/heppu/go-mssqldb v0.0.0-20250501201929-760489e7f2c2
Loading