-
Notifications
You must be signed in to change notification settings - Fork 345
/
sqlserver.go
74 lines (70 loc) · 2.16 KB
/
sqlserver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Package sqlserver defines and registers usql's Microsoft SQL Server driver.
//
// See: https://github.com/microsoft/go-mssqldb
// Group: base
package sqlserver
import (
"context"
"database/sql"
"fmt"
"io"
"strconv"
"strings"
sqlserver "github.com/microsoft/go-mssqldb" // DRIVER
"github.com/microsoft/go-mssqldb/azuread"
"github.com/xo/dburl"
"github.com/xo/usql/drivers"
"github.com/xo/usql/drivers/metadata"
)
func init() {
drivers.Register("sqlserver", drivers.Driver{
AllowMultilineComments: true,
RequirePreviousPassword: true,
LexerName: "tsql",
Open: func(u *dburl.URL, _, _ func() io.Writer) (func(string, string) (*sql.DB, error), error) {
return func(_ string, params string) (*sql.DB, error) {
driver := "sqlserver"
if u.Query().Has("fedauth") {
driver = azuread.DriverName
}
return sql.Open(driver, params)
}, nil
},
Version: func(ctx context.Context, db drivers.DB) (string, error) {
var ver, level, edition string
err := db.QueryRowContext(
ctx,
`SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')`,
).Scan(&ver, &level, &edition)
if err != nil {
return "", err
}
return "Microsoft SQL Server " + ver + ", " + level + ", " + edition, nil
},
ChangePassword: func(db drivers.DB, user, newpw, oldpw string) error {
_, err := db.Exec(`ALTER LOGIN ` + user + ` WITH password = '` + newpw + `' old_password = '` + oldpw + `'`)
return err
},
Err: func(err error) (string, string) {
if e, ok := err.(sqlserver.Error); ok {
return strconv.Itoa(int(e.Number)), e.Message
}
msg := err.Error()
if i := strings.LastIndex(msg, "sqlserver:"); i != -1 {
msg = msg[i:]
}
return "", msg
},
IsPasswordErr: func(err error) bool {
return strings.Contains(err.Error(), "Login failed for")
},
NewMetadataReader: NewReader,
NewMetadataWriter: func(db drivers.DB, w io.Writer, opts ...metadata.ReaderOption) metadata.Writer {
return metadata.NewDefaultWriter(NewReader(db, opts...))(db, w)
},
Copy: drivers.CopyWithInsert(placeholder),
})
}
func placeholder(n int) string {
return fmt.Sprintf("@p%d", n)
}