summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--go.mod4
-rw-r--r--go.sum59
-rw-r--r--integrations/migration-test/migration_test.go10
-rw-r--r--vendor/cloud.google.com/go/AUTHORS15
-rw-r--r--vendor/cloud.google.com/go/CONTRIBUTORS40
-rw-r--r--vendor/cloud.google.com/go/LICENSE202
-rw-r--r--vendor/cloud.google.com/go/civil/civil.go277
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/README.md125
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/appveyor.yml5
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/buf.go19
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/bulkcopy.go164
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/bulkcopy_sql.go8
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/convert.go306
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/doc.go8
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/go.mod10
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/go.sum168
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/internal/querytext/parser.go (renamed from vendor/github.com/denisenkom/go-mssqldb/parser.go)12
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/mssql.go385
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/mssql_go110.go47
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/mssql_go18.go91
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/mssql_go19.go182
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/mssql_go19pre.go8
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/net.go20
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/ntlm.go82
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/rpc.go47
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/tds.go201
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/token.go32
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/tran.go13
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/tvp_go19.go231
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/types.go190
-rw-r--r--vendor/modules.txt5
31 files changed, 2372 insertions, 594 deletions
diff --git a/go.mod b/go.mod
index e1e26f1842..97e881986b 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,6 @@ module code.gitea.io/gitea
go 1.12
require (
- github.com/BurntSushi/toml v0.3.1 // indirect
github.com/PuerkitoBio/goquery v0.0.0-20170324135448-ed7d758e9a34
github.com/RoaringBitmap/roaring v0.4.7 // indirect
github.com/Unknwon/cae v0.0.0-20160715032808-c6aac99ea2ca
@@ -127,11 +126,8 @@ require (
gopkg.in/src-d/go-git.v4 v4.12.0
gopkg.in/stretchr/testify.v1 v1.2.2 // indirect
gopkg.in/testfixtures.v2 v2.5.0
- gopkg.in/yaml.v2 v2.2.2 // indirect
mvdan.cc/xurls/v2 v2.0.0
strk.kbt.io/projects/go/libravatar v0.0.0-20160628055650-5eed7bff870a
xorm.io/builder v0.3.5
xorm.io/core v0.6.3
)
-
-replace github.com/denisenkom/go-mssqldb => github.com/denisenkom/go-mssqldb v0.0.0-20180315180555-6a30f4e59a44
diff --git a/go.sum b/go.sum
index 9930b64d29..49a25faf30 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,8 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
+cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -7,6 +10,8 @@ github.com/PuerkitoBio/goquery v0.0.0-20170324135448-ed7d758e9a34 h1:UsHpWO0Elp6
github.com/PuerkitoBio/goquery v0.0.0-20170324135448-ed7d758e9a34/go.mod h1:T9ezsOHcCrDCgA8aF1Cqr3sSYbO/xgdy8/R/XiIMAhA=
github.com/RoaringBitmap/roaring v0.4.7 h1:eGUudvFzvF7Kxh7JjYvXfI1f7l22/2duFby7r5+d4oc=
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/Unknwon/cae v0.0.0-20160715032808-c6aac99ea2ca h1:xU8R31tsvj6TesCBog973+UgI3TXjh/LqN5clki6hcc=
github.com/Unknwon/cae v0.0.0-20160715032808-c6aac99ea2ca/go.mod h1:IRSre9/SEhVuy972TVuJLyaPTS73+8Owhe0Y0l9NXHc=
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg=
@@ -23,6 +28,7 @@ github.com/andybalholm/cascadia v0.0.0-20161224141413-349dd0209470 h1:4jHLmof+Hb
github.com/andybalholm/cascadia v0.0.0-20161224141413-349dd0209470/go.mod h1:3I+3V7B6gTBYfdpYgIG2ymALS9H+5VDKUl3lHH7ToM4=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -45,6 +51,7 @@ github.com/bradfitz/gomemcache v0.0.0-20160117192205-fb1f79c6b65a/go.mod h1:PmM6
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f h1:REH9VH5ubNR0skLaOxK7TRJeRbE2dDfvaouQo8FsRcA=
github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f/go.mod h1:6QaC0vFoKWYDth94dHFNgRT2YkT5FHdQp/Yx15aAAi0=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c h1:K4FIibkr4//ziZKOKmt4RL0YImuTjLLBtwElf+F2lSQ=
@@ -64,11 +71,15 @@ github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/denisenkom/go-mssqldb v0.0.0-20180315180555-6a30f4e59a44 h1:DWxZh2sImfCFn/79OUBhzFkPTKnsdDzXH/JTxpw5n6w=
-github.com/denisenkom/go-mssqldb v0.0.0-20180315180555-6a30f4e59a44/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
+github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
+github.com/denisenkom/go-mssqldb v0.0.0-20190724012636-11b2859924c1 h1:vHTzcl17WBhVXW/KIk2wAoWva7w5WhdNsZtw4caVZZI=
+github.com/denisenkom/go-mssqldb v0.0.0-20190724012636-11b2859924c1/go.mod h1:uU0N10vx1abI4qeVe79CxepBP6PPREVTgMS5Gx6/mOk=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 h1:aaQcKT9WumO6JEJcRyTqFVq4XUZiUcKR2/GI31TOcz8=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
@@ -137,13 +148,18 @@ github.com/go-xorm/xorm v0.7.4/go.mod h1:vpza5fydeRgt+stvo9qgMhSNohYqmNt0I1/D6hk
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561 h1:deE7ritpK04PgtpyVOS2TYcQEld9qLCD5b5EbVNOuLA=
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:YgYOrVn3Nj9Tq0EvjmFbphRytDj7JNRoWSStJZWDJTQ=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQdcMdzjbqqXMEnHfq0Or6p8=
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -153,6 +169,9 @@ github.com/google/go-github/v24 v24.0.1 h1:KCt1LjMJEey1qvPXxa9SjaWxwTsCWSq6p2Ju5
github.com/google/go-github/v24 v24.0.1/go.mod h1:CRqaW1Uns1TCkP0wqTpxYyRxRjxwvKU/XSS44u6X74M=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -167,6 +186,7 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+
github.com/gorilla/sessions v0.0.0-20160922145804-ca9ada445741/go.mod h1:+WVp8kdw6VhyKExm03PAMRn2ZxnPtm58pV0dBVPdhHE=
github.com/gorilla/sessions v1.1.1 h1:YMDmfaK68mUixINzY/XjscuJ47uXFWSSHzFbBQM0PrE=
github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=
@@ -187,6 +207,7 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
@@ -197,6 +218,7 @@ github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/keybase/go-crypto v0.0.0-20170605145657-00ac4db533f6 h1:9mszGwKDxHEY2cy+9XxCQKWIfkGPSAEFrcN8ghzyAKg=
github.com/keybase/go-crypto v0.0.0-20170605145657-00ac4db533f6/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v0.0.0-20161025140425-8df558b6cb6f h1:tCnZKEmDovgV4jmsclh6CuKk9AMzTzyVWfejgkgccVg=
github.com/klauspost/compress v0.0.0-20161025140425-8df558b6cb6f/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc h1:WW8B7p7QBnFlqRVv/k6ro/S8Z7tCnYjJHcQNScx9YVs=
@@ -257,10 +279,12 @@ github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -269,18 +293,23 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/pquerna/otp v0.0.0-20160912161815-54653902c20e h1:ApqncJ84HYN8x8x5WV1T1YWDuPRF/0aXZhr91LnRMCQ=
github.com/pquerna/otp v0.0.0-20160912161815-54653902c20e/go.mod h1:Zad1CMQfSQZI5KLpahDiSUX4tMMREnXw98IvL1nhgMk=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 h1:YDeskXpkNDhPdWN3REluVa46HQOVuVkjkd2sWnrABNQ=
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff h1:g9ZlAHmkc/h5So+OjNCkZWh+FjuKEOOOoyRkqlGA8+c=
@@ -338,19 +367,27 @@ github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443 h1:IcSOAf4PyMp3U3XbIEj1/xJ2BjNN2jWv7JoyOsMxXUU=
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -363,13 +400,16 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -379,15 +419,27 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190620070143-6f217b454f45 h1:Dl2hc890lrizvUppGbRWhnIh2f8jOTCQpY5IKWRS0oM=
golang.org/x/sys v0.0.0-20190620070143-6f217b454f45/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190620154339-431033348dd0 h1:qUGDNmGEM+ZBtwF9vuzEv+9nQQPL+l/oNBZ+DCDTAyo=
golang.org/x/tools v0.0.0-20190620154339-431033348dd0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
@@ -430,6 +482,9 @@ gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
mvdan.cc/xurls/v2 v2.0.0 h1:r1zSOSNS/kqtpmATyMMMvaZ4/djsesbYz5kr0+qMRWc=
mvdan.cc/xurls/v2 v2.0.0/go.mod h1:2/webFPYOXN9jp/lzuj0zuAVlF+9g4KPFJANH1oJhRU=
strk.kbt.io/projects/go/libravatar v0.0.0-20160628055650-5eed7bff870a h1:8q33ShxKXRwQ7JVd1ZnhIU3hZhwwn0Le+4fTeAackuM=
diff --git a/integrations/migration-test/migration_test.go b/integrations/migration-test/migration_test.go
index 15b086c6e6..fd0d0b7c72 100644
--- a/integrations/migration-test/migration_test.go
+++ b/integrations/migration-test/migration_test.go
@@ -181,11 +181,19 @@ func restoreOldDB(t *testing.T, version string) bool {
assert.NoError(t, err)
defer db.Close()
- _, err = db.Exec("DROP DATABASE IF EXISTS gitea")
+ _, err = db.Exec("DROP DATABASE IF EXISTS [gitea]")
assert.NoError(t, err)
statements := strings.Split(data, "\nGO\n")
for _, statement := range statements {
+ if len(statement) > 5 && statement[:5] == "USE [" {
+ dbname := statement[5 : len(statement)-1]
+ db.Close()
+ db, err = sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;",
+ host, port, dbname, models.DbCfg.User, models.DbCfg.Passwd))
+ assert.NoError(t, err)
+ defer db.Close()
+ }
_, err = db.Exec(statement)
assert.NoError(t, err, "Failure whilst running: %s\nError: %v", statement, err)
}
diff --git a/vendor/cloud.google.com/go/AUTHORS b/vendor/cloud.google.com/go/AUTHORS
new file mode 100644
index 0000000000..c364af1da0
--- /dev/null
+++ b/vendor/cloud.google.com/go/AUTHORS
@@ -0,0 +1,15 @@
+# This is the official list of cloud authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+
+# Names should be added to this file as:
+# Name or Organization <email address>
+# The email address is not required for organizations.
+
+Filippo Valsorda <hi@filippo.io>
+Google Inc.
+Ingo Oeser <nightlyone@googlemail.com>
+Palm Stone Games, Inc.
+Paweł Knap <pawelknap88@gmail.com>
+Péter Szilágyi <peterke@gmail.com>
+Tyler Treat <ttreat31@gmail.com>
diff --git a/vendor/cloud.google.com/go/CONTRIBUTORS b/vendor/cloud.google.com/go/CONTRIBUTORS
new file mode 100644
index 0000000000..3b3cbed98e
--- /dev/null
+++ b/vendor/cloud.google.com/go/CONTRIBUTORS
@@ -0,0 +1,40 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people. For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# Names should be added to this file as:
+# Name <email address>
+
+# Keep the list alphabetically sorted.
+
+Alexis Hunt <lexer@google.com>
+Andreas Litt <andreas.litt@gmail.com>
+Andrew Gerrand <adg@golang.org>
+Brad Fitzpatrick <bradfitz@golang.org>
+Burcu Dogan <jbd@google.com>
+Dave Day <djd@golang.org>
+David Sansome <me@davidsansome.com>
+David Symonds <dsymonds@golang.org>
+Filippo Valsorda <hi@filippo.io>
+Glenn Lewis <gmlewis@google.com>
+Ingo Oeser <nightlyone@googlemail.com>
+James Hall <james.hall@shopify.com>
+Johan Euphrosine <proppy@google.com>
+Jonathan Amsterdam <jba@google.com>
+Kunpei Sakai <namusyaka@gmail.com>
+Luna Duclos <luna.duclos@palmstonegames.com>
+Magnus Hiie <magnus.hiie@gmail.com>
+Mario Castro <mariocaster@gmail.com>
+Michael McGreevy <mcgreevy@golang.org>
+Omar Jarjur <ojarjur@google.com>
+Paweł Knap <pawelknap88@gmail.com>
+Péter Szilágyi <peterke@gmail.com>
+Sarah Adams <shadams@google.com>
+Thanatat Tamtan <acoshift@gmail.com>
+Toby Burress <kurin@google.com>
+Tuo Shan <shantuo@google.com>
+Tyler Treat <ttreat31@gmail.com>
diff --git a/vendor/cloud.google.com/go/LICENSE b/vendor/cloud.google.com/go/LICENSE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/vendor/cloud.google.com/go/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/cloud.google.com/go/civil/civil.go b/vendor/cloud.google.com/go/civil/civil.go
new file mode 100644
index 0000000000..29272ef26a
--- /dev/null
+++ b/vendor/cloud.google.com/go/civil/civil.go
@@ -0,0 +1,277 @@
+// Copyright 2016 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package civil implements types for civil time, a time-zone-independent
+// representation of time that follows the rules of the proleptic
+// Gregorian calendar with exactly 24-hour days, 60-minute hours, and 60-second
+// minutes.
+//
+// Because they lack location information, these types do not represent unique
+// moments or intervals of time. Use time.Time for that purpose.
+package civil
+
+import (
+ "fmt"
+ "time"
+)
+
+// A Date represents a date (year, month, day).
+//
+// This type does not include location information, and therefore does not
+// describe a unique 24-hour timespan.
+type Date struct {
+ Year int // Year (e.g., 2014).
+ Month time.Month // Month of the year (January = 1, ...).
+ Day int // Day of the month, starting at 1.
+}
+
+// DateOf returns the Date in which a time occurs in that time's location.
+func DateOf(t time.Time) Date {
+ var d Date
+ d.Year, d.Month, d.Day = t.Date()
+ return d
+}
+
+// ParseDate parses a string in RFC3339 full-date format and returns the date value it represents.
+func ParseDate(s string) (Date, error) {
+ t, err := time.Parse("2006-01-02", s)
+ if err != nil {
+ return Date{}, err
+ }
+ return DateOf(t), nil
+}
+
+// String returns the date in RFC3339 full-date format.
+func (d Date) String() string {
+ return fmt.Sprintf("%04d-%02d-%02d", d.Year, d.Month, d.Day)
+}
+
+// IsValid reports whether the date is valid.
+func (d Date) IsValid() bool {
+ return DateOf(d.In(time.UTC)) == d
+}
+
+// In returns the time corresponding to time 00:00:00 of the date in the location.
+//
+// In is always consistent with time.Date, even when time.Date returns a time
+// on a different day. For example, if loc is America/Indiana/Vincennes, then both
+// time.Date(1955, time.May, 1, 0, 0, 0, 0, loc)
+// and
+// civil.Date{Year: 1955, Month: time.May, Day: 1}.In(loc)
+// return 23:00:00 on April 30, 1955.
+//
+// In panics if loc is nil.
+func (d Date) In(loc *time.Location) time.Time {
+ return time.Date(d.Year, d.Month, d.Day, 0, 0, 0, 0, loc)
+}
+
+// AddDays returns the date that is n days in the future.
+// n can also be negative to go into the past.
+func (d Date) AddDays(n int) Date {
+ return DateOf(d.In(time.UTC).AddDate(0, 0, n))
+}
+
+// DaysSince returns the signed number of days between the date and s, not including the end day.
+// This is the inverse operation to AddDays.
+func (d Date) DaysSince(s Date) (days int) {
+ // We convert to Unix time so we do not have to worry about leap seconds:
+ // Unix time increases by exactly 86400 seconds per day.
+ deltaUnix := d.In(time.UTC).Unix() - s.In(time.UTC).Unix()
+ return int(deltaUnix / 86400)
+}
+
+// Before reports whether d1 occurs before d2.
+func (d1 Date) Before(d2 Date) bool {
+ if d1.Year != d2.Year {
+ return d1.Year < d2.Year
+ }
+ if d1.Month != d2.Month {
+ return d1.Month < d2.Month
+ }
+ return d1.Day < d2.Day
+}
+
+// After reports whether d1 occurs after d2.
+func (d1 Date) After(d2 Date) bool {
+ return d2.Before(d1)
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+// The output is the result of d.String().
+func (d Date) MarshalText() ([]byte, error) {
+ return []byte(d.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The date is expected to be a string in a format accepted by ParseDate.
+func (d *Date) UnmarshalText(data []byte) error {
+ var err error
+ *d, err = ParseDate(string(data))
+ return err
+}
+
+// A Time represents a time with nanosecond precision.
+//
+// This type does not include location information, and therefore does not
+// describe a unique moment in time.
+//
+// This type exists to represent the TIME type in storage-based APIs like BigQuery.
+// Most operations on Times are unlikely to be meaningful. Prefer the DateTime type.
+type Time struct {
+ Hour int // The hour of the day in 24-hour format; range [0-23]
+ Minute int // The minute of the hour; range [0-59]
+ Second int // The second of the minute; range [0-59]
+ Nanosecond int // The nanosecond of the second; range [0-999999999]
+}
+
+// TimeOf returns the Time representing the time of day in which a time occurs
+// in that time's location. It ignores the date.
+func TimeOf(t time.Time) Time {
+ var tm Time
+ tm.Hour, tm.Minute, tm.Second = t.Clock()
+ tm.Nanosecond = t.Nanosecond()
+ return tm
+}
+
+// ParseTime parses a string and returns the time value it represents.
+// ParseTime accepts an extended form of the RFC3339 partial-time format. After
+// the HH:MM:SS part of the string, an optional fractional part may appear,
+// consisting of a decimal point followed by one to nine decimal digits.
+// (RFC3339 admits only one digit after the decimal point).
+func ParseTime(s string) (Time, error) {
+ t, err := time.Parse("15:04:05.999999999", s)
+ if err != nil {
+ return Time{}, err
+ }
+ return TimeOf(t), nil
+}
+
+// String returns the date in the format described in ParseTime. If Nanoseconds
+// is zero, no fractional part will be generated. Otherwise, the result will
+// end with a fractional part consisting of a decimal point and nine digits.
+func (t Time) String() string {
+ s := fmt.Sprintf("%02d:%02d:%02d", t.Hour, t.Minute, t.Second)
+ if t.Nanosecond == 0 {
+ return s
+ }
+ return s + fmt.Sprintf(".%09d", t.Nanosecond)
+}
+
+// IsValid reports whether the time is valid.
+func (t Time) IsValid() bool {
+ // Construct a non-zero time.
+ tm := time.Date(2, 2, 2, t.Hour, t.Minute, t.Second, t.Nanosecond, time.UTC)
+ return TimeOf(tm) == t
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+// The output is the result of t.String().
+func (t Time) MarshalText() ([]byte, error) {
+ return []byte(t.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The time is expected to be a string in a format accepted by ParseTime.
+func (t *Time) UnmarshalText(data []byte) error {
+ var err error
+ *t, err = ParseTime(string(data))
+ return err
+}
+
+// A DateTime represents a date and time.
+//
+// This type does not include location information, and therefore does not
+// describe a unique moment in time.
+type DateTime struct {
+ Date Date
+ Time Time
+}
+
+// Note: We deliberately do not embed Date into DateTime, to avoid promoting AddDays and Sub.
+
+// DateTimeOf returns the DateTime in which a time occurs in that time's location.
+func DateTimeOf(t time.Time) DateTime {
+ return DateTime{
+ Date: DateOf(t),
+ Time: TimeOf(t),
+ }
+}
+
+// ParseDateTime parses a string and returns the DateTime it represents.
+// ParseDateTime accepts a variant of the RFC3339 date-time format that omits
+// the time offset but includes an optional fractional time, as described in
+// ParseTime. Informally, the accepted format is
+// YYYY-MM-DDTHH:MM:SS[.FFFFFFFFF]
+// where the 'T' may be a lower-case 't'.
+func ParseDateTime(s string) (DateTime, error) {
+ t, err := time.Parse("2006-01-02T15:04:05.999999999", s)
+ if err != nil {
+ t, err = time.Parse("2006-01-02t15:04:05.999999999", s)
+ if err != nil {
+ return DateTime{}, err
+ }
+ }
+ return DateTimeOf(t), nil
+}
+
+// String returns the date in the format described in ParseDate.
+func (dt DateTime) String() string {
+ return dt.Date.String() + "T" + dt.Time.String()
+}
+
+// IsValid reports whether the datetime is valid.
+func (dt DateTime) IsValid() bool {
+ return dt.Date.IsValid() && dt.Time.IsValid()
+}
+
+// In returns the time corresponding to the DateTime in the given location.
+//
+// If the time is missing or ambigous at the location, In returns the same
+// result as time.Date. For example, if loc is America/Indiana/Vincennes, then
+// both
+// time.Date(1955, time.May, 1, 0, 30, 0, 0, loc)
+// and
+// civil.DateTime{
+// civil.Date{Year: 1955, Month: time.May, Day: 1}},
+// civil.Time{Minute: 30}}.In(loc)
+// return 23:30:00 on April 30, 1955.
+//
+// In panics if loc is nil.
+func (dt DateTime) In(loc *time.Location) time.Time {
+ return time.Date(dt.Date.Year, dt.Date.Month, dt.Date.Day, dt.Time.Hour, dt.Time.Minute, dt.Time.Second, dt.Time.Nanosecond, loc)
+}
+
+// Before reports whether dt1 occurs before dt2.
+func (dt1 DateTime) Before(dt2 DateTime) bool {
+ return dt1.In(time.UTC).Before(dt2.In(time.UTC))
+}
+
+// After reports whether dt1 occurs after dt2.
+func (dt1 DateTime) After(dt2 DateTime) bool {
+ return dt2.Before(dt1)
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+// The output is the result of dt.String().
+func (dt DateTime) MarshalText() ([]byte, error) {
+ return []byte(dt.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The datetime is expected to be a string in a format accepted by ParseDateTime
+func (dt *DateTime) UnmarshalText(data []byte) error {
+ var err error
+ *dt, err = ParseDateTime(string(data))
+ return err
+}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/README.md b/vendor/github.com/denisenkom/go-mssqldb/README.md
index cd19ded516..8d530ab49a 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/README.md
+++ b/vendor/github.com/denisenkom/go-mssqldb/README.md
@@ -21,13 +21,12 @@ Other supported formats are listed below.
* `user id` - 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`
* `database`
-* `connection timeout` - in seconds (default is 30)
-* `dial timeout` - in seconds (default is 5)
+* `connection timeout` - in seconds (default is 0 for no timeout), set to 0 for no timeout. Recommended to set to 0 and use context to manage query and connection timeouts.
+* `dial timeout` - in seconds (default is 15), set to 0 for no timeout
* `encrypt`
* `disable` - Data send between client and server is not encrypted.
* `false` - Data sent between client and server is not encrypted beyond the login packet. (Default)
* `true` - Data sent between client and server is encrypted.
-* `keepAlive` - in seconds; 0 to disable (default is 30)
* `app name` - The application name (default is go-mssqldb)
### Connection parameters for ODBC and ADO style connection strings:
@@ -37,6 +36,7 @@ Other supported formats are listed below.
### Less common parameters:
+* `keepAlive` - in seconds; 0 to disable (default is 30)
* `failoverpartner` - host or host\instance (default is no partner).
* `failoverport` - used only when there is no instance in failoverpartner (default 1433)
* `packet size` - in bytes; 512 to 32767 (default is 4096)
@@ -68,14 +68,14 @@ Other supported formats are listed below.
* `sqlserver://username:password@host:port?param1=value&param2=value`
* `sqlserver://sa@localhost/SQLExpress?database=master&connection+timeout=30` // `SQLExpress instance.
* `sqlserver://sa:mypass@localhost?database=master&connection+timeout=30` // username=sa, password=mypass.
- * `sqlserver://sa:mypass@localhost:1234?database=master&connection+timeout=30"` // port 1234 on localhost.
+ * `sqlserver://sa:mypass@localhost:1234?database=master&connection+timeout=30` // port 1234 on localhost.
* `sqlserver://sa:my%7Bpass@somehost?connection+timeout=30` // password is "my{pass"
A string of this format can be constructed using the `URL` type in the `net/url` package.
```go
query := url.Values{}
- query.Add("connection timeout", "30")
+ query.Add("app name", "MyAppName")
u := &url.URL{
Scheme: "sqlserver",
@@ -90,14 +90,14 @@ Other supported formats are listed below.
2. ADO: `key=value` pairs separated by `;`. Values may not contain `;`, leading and trailing whitespace is ignored.
Examples:
- * `server=localhost\\SQLExpress;user id=sa;database=master;connection timeout=30`
- * `server=localhost;user id=sa;database=master;connection timeout=30`
+ * `server=localhost\\SQLExpress;user id=sa;database=master;app name=MyAppName`
+ * `server=localhost;user id=sa;database=master;app name=MyAppName`
3. ODBC: Prefix with `odbc`, `key=value` pairs separated by `;`. Allow `;` by wrapping
values in `{}`. Examples:
- * `odbc:server=localhost\\SQLExpress;user id=sa;database=master;connection timeout=30`
- * `odbc:server=localhost;user id=sa;database=master;connection timeout=30`
+ * `odbc:server=localhost\\SQLExpress;user id=sa;database=master;app name=MyAppName`
+ * `odbc:server=localhost;user id=sa;database=master;app name=MyAppName`
* `odbc:server=localhost;user id=sa;password={foo;bar}` // Value marked with `{}`, password is "foo;bar"
* `odbc:server=localhost;user id=sa;password={foo{bar}` // Value marked with `{}`, password is "foo{bar"
* `odbc:server=localhost;user id=sa;password={foobar }` // Value marked with `{}`, password is "foobar "
@@ -113,11 +113,81 @@ To run a stored procedure, set the query text to the procedure name:
var account = "abc"
_, err := db.ExecContext(ctx, "sp_RunMe",
sql.Named("ID", 123),
- sql.Out{Dest{sql.Named("Account", &account)}
+ sql.Named("Account", sql.Out{Dest: &account}),
)
```
-## Statement Parameters
+## Reading Output Parameters from a Stored Procedure with Resultset
+
+To read output parameters from a stored procedure with resultset, make sure you read all the rows before reading the output parameters:
+```go
+sqltextcreate := `
+CREATE PROCEDURE spwithoutputandrows
+ @bitparam BIT OUTPUT
+AS BEGIN
+ SET @bitparam = 1
+ SELECT 'Row 1'
+END
+`
+var bitout int64
+rows, err := db.QueryContext(ctx, "spwithoutputandrows", sql.Named("bitparam", sql.Out{Dest: &bitout}))
+var strrow string
+for rows.Next() {
+ err = rows.Scan(&strrow)
+}
+fmt.Printf("bitparam is %d", bitout)
+```
+
+## Caveat for local temporary tables
+
+Due to protocol limitations, temporary tables will only be allocated on the connection
+as a result of executing a query with zero parameters. The following query
+will, due to the use of a parameter, execute in its own session,
+and `#mytemp` will be de-allocated right away:
+
+```go
+conn, err := pool.Conn(ctx)
+defer conn.Close()
+_, err := conn.ExecContext(ctx, "select @p1 as x into #mytemp", 1)
+// at this point #mytemp is already dropped again as the session of the ExecContext is over
+```
+
+To work around this, always explicitly create the local temporary
+table in a query without any parameters. As a special case, the driver
+will then be able to execute the query directly on the
+connection-scoped session. The following example works:
+
+```go
+conn, err := pool.Conn(ctx)
+
+// Set us up so that temp table is always cleaned up, since conn.Close()
+// merely returns conn to pool, rather than actually closing the connection.
+defer func() {
+ _, _ = conn.ExecContext(ctx, "drop table #mytemp") // always clean up
+ conn.Close() // merely returns conn to pool
+}()
+
+
+// Since we not pass any parameters below, the query will execute on the scope of
+// the connection and succeed in creating the table.
+_, err := conn.ExecContext(ctx, "create table #mytemp ( x int )")
+
+// #mytemp is now available even if you pass parameters
+_, err := conn.ExecContext(ctx, "insert into #mytemp (x) values (@p1)", 1)
+
+```
+
+## Return Status
+
+To get the procedure return status, pass into the parameters a
+`*mssql.ReturnStatus`. For example:
+```
+var rs mssql.ReturnStatus
+_, err := db.ExecContext(ctx, "theproc", &rs)
+log.Printf("status=%d", rs)
+```
+
+## Parameters
The `sqlserver` driver uses normal MS SQL Server syntax and expects parameters in
the sql query to be in the form of either `@Name` or `@p1` to `@pN` (ordinal position).
@@ -126,6 +196,37 @@ the sql query to be in the form of either `@Name` or `@p1` to `@pN` (ordinal pos
db.QueryContext(ctx, `select * from t where ID = @ID and Name = @p2;`, sql.Named("ID", 6), "Bob")
```
+### Parameter Types
+
+To pass specific types to the query parameters, say `varchar` or `date` types,
+you must convert the types to the type before passing in. The following types
+are supported:
+
+ * string -> nvarchar
+ * mssql.VarChar -> varchar
+ * time.Time -> datetimeoffset or datetime (TDS version dependent)
+ * mssql.DateTime1 -> datetime
+ * mssql.DateTimeOffset -> datetimeoffset
+ * "cloud.google.com/go/civil".Date -> date
+ * "cloud.google.com/go/civil".DateTime -> datetime2
+ * "cloud.google.com/go/civil".Time -> time
+ * mssql.TVP -> Table Value Parameter (TDS version dependent)
+
+## Important Notes
+
+ * [LastInsertId](https://golang.org/pkg/database/sql/#Result.LastInsertId) should
+ not be used with this driver (or SQL Server) due to how the TDS protocol
+ works. Please use the [OUTPUT Clause](https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql)
+ or add a `select ID = convert(bigint, SCOPE_IDENTITY());` to the end of your
+ query (ref [SCOPE_IDENTITY](https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql)).
+ This will ensure you are getting the correct ID and will prevent a network round trip.
+ * [NewConnector](https://godoc.org/github.com/denisenkom/go-mssqldb#NewConnector)
+ may be used with [OpenDB](https://golang.org/pkg/database/sql/#OpenDB).
+ * [Connector.SessionInitSQL](https://godoc.org/github.com/denisenkom/go-mssqldb#Connector.SessionInitSQL)
+ may be set to set any driver specific session settings after the session
+ has been reset. If empty the session will still be reset but use the database
+ defaults in Go1.10+.
+
## Features
* Can be used with SQL Server 2005 or newer
@@ -154,7 +255,7 @@ These features still exist in the driver, but they are are deprecated.
### Query Parameter Token Replace (driver "mssql")
-If you use the driver name "mssql" (rather then "sqlserver" the SQL text
+If you use the driver name "mssql" (rather then "sqlserver") the SQL text
will be loosly parsed and an attempt to extract identifiers using one of
* ?
diff --git a/vendor/github.com/denisenkom/go-mssqldb/appveyor.yml b/vendor/github.com/denisenkom/go-mssqldb/appveyor.yml
index 2c1435507b..2ae5456d5c 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/appveyor.yml
+++ b/vendor/github.com/denisenkom/go-mssqldb/appveyor.yml
@@ -14,6 +14,8 @@ environment:
matrix:
- GOVERSION: 18
SQLINSTANCE: SQL2016
+ - GOVERSION: 19
+ SQLINSTANCE: SQL2016
- GOVERSION: 110
SQLINSTANCE: SQL2016
- SQLINSTANCE: SQL2014
@@ -25,6 +27,7 @@ install:
- set PATH=%GOPATH%\bin;%GOROOT%\bin;%PATH%
- go version
- go env
+ - go get -u cloud.google.com/go/civil
build_script:
- go build
@@ -41,5 +44,5 @@ before_test:
test_script:
- - go test -race -coverprofile=coverage.txt -covermode=atomic
+ - go test -race -cpu 4 -coverprofile=coverage.txt -covermode=atomic
- codecov -f coverage.txt
diff --git a/vendor/github.com/denisenkom/go-mssqldb/buf.go b/vendor/github.com/denisenkom/go-mssqldb/buf.go
index 365acd4833..927d75d1b7 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/buf.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/buf.go
@@ -101,11 +101,10 @@ func (w *tdsBuffer) Write(p []byte) (total int, err error) {
}
p = p[copied:]
}
- return
}
func (w *tdsBuffer) WriteByte(b byte) error {
- if int(w.wpos) == len(w.wbuf) {
+ if int(w.wpos) == len(w.wbuf) || w.wpos == w.packetSize {
if err := w.flush(); err != nil {
return err
}
@@ -115,15 +114,23 @@ func (w *tdsBuffer) WriteByte(b byte) error {
return nil
}
-func (w *tdsBuffer) BeginPacket(packetType packetType) {
- w.wbuf[1] = 0 // Packet is incomplete. This byte is set again in FinishPacket.
+func (w *tdsBuffer) BeginPacket(packetType packetType, resetSession bool) {
+ status := byte(0)
+ if resetSession {
+ switch packetType {
+ // Reset session can only be set on the following packet types.
+ case packSQLBatch, packRPCRequest, packTransMgrReq:
+ status = 0x8
+ }
+ }
+ w.wbuf[1] = status // Packet is incomplete. This byte is set again in FinishPacket.
w.wpos = 8
w.wPacketSeq = 1
w.wPacketType = packetType
}
func (w *tdsBuffer) FinishPacket() error {
- w.wbuf[1] = 1 // Mark this as the last packet in the message.
+ w.wbuf[1] |= 1 // Mark this as the last packet in the message.
return w.flush()
}
@@ -136,7 +143,7 @@ func (r *tdsBuffer) readNextPacket() error {
if err != nil {
return err
}
- if int(h.Size) > len(r.rbuf) {
+ if int(h.Size) > r.packetSize {
return errors.New("Invalid packet size, it is longer than buffer size")
}
if headerSize > int(h.Size) {
diff --git a/vendor/github.com/denisenkom/go-mssqldb/bulkcopy.go b/vendor/github.com/denisenkom/go-mssqldb/bulkcopy.go
index 8c0a4e0a2a..3b319af893 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/bulkcopy.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/bulkcopy.go
@@ -13,6 +13,12 @@ import (
)
type Bulk struct {
+ // ctx is used only for AddRow and Done methods.
+ // This could be removed if AddRow and Done accepted
+ // a ctx field as well, which is available with the
+ // database/sql call.
+ ctx context.Context
+
cn *Conn
metadata []columnStruct
bulkColumns []columnStruct
@@ -37,14 +43,20 @@ type BulkOptions struct {
type DataValue interface{}
func (cn *Conn) CreateBulk(table string, columns []string) (_ *Bulk) {
- b := Bulk{cn: cn, tablename: table, headerSent: false, columnsName: columns}
+ b := Bulk{ctx: context.Background(), cn: cn, tablename: table, headerSent: false, columnsName: columns}
+ b.Debug = false
+ return &b
+}
+
+func (cn *Conn) CreateBulkContext(ctx context.Context, table string, columns []string) (_ *Bulk) {
+ b := Bulk{ctx: ctx, cn: cn, tablename: table, headerSent: false, columnsName: columns}
b.Debug = false
return &b
}
-func (b *Bulk) sendBulkCommand() (err error) {
+func (b *Bulk) sendBulkCommand(ctx context.Context) (err error) {
//get table columns info
- err = b.getMetadata()
+ err = b.getMetadata(ctx)
if err != nil {
return err
}
@@ -114,13 +126,13 @@ func (b *Bulk) sendBulkCommand() (err error) {
query := fmt.Sprintf("INSERT BULK %s (%s) %s", b.tablename, col_defs.String(), with_part)
- stmt, err := b.cn.Prepare(query)
+ stmt, err := b.cn.PrepareContext(ctx, query)
if err != nil {
return fmt.Errorf("Prepare failed: %s", err.Error())
}
b.dlogf(query)
- _, err = stmt.Exec(nil)
+ _, err = stmt.(*Stmt).ExecContext(ctx, nil)
if err != nil {
return err
}
@@ -128,9 +140,9 @@ func (b *Bulk) sendBulkCommand() (err error) {
b.headerSent = true
var buf = b.cn.sess.buf
- buf.BeginPacket(packBulkLoadBCP)
+ buf.BeginPacket(packBulkLoadBCP, false)
- // send the columns metadata
+ // Send the columns metadata.
columnMetadata := b.createColMetadata()
_, err = buf.Write(columnMetadata)
@@ -141,7 +153,7 @@ func (b *Bulk) sendBulkCommand() (err error) {
// The arguments are the row values in the order they were specified.
func (b *Bulk) AddRow(row []interface{}) (err error) {
if !b.headerSent {
- err = b.sendBulkCommand()
+ err = b.sendBulkCommand(b.ctx)
if err != nil {
return
}
@@ -216,7 +228,7 @@ func (b *Bulk) Done() (rowcount int64, err error) {
buf.FinishPacket()
tokchan := make(chan tokenStruct, 5)
- go processResponse(context.Background(), b.cn.sess, tokchan, nil)
+ go processResponse(b.ctx, b.cn.sess, tokchan, nil)
var rowCount int64
for token := range tokchan {
@@ -267,28 +279,27 @@ func (b *Bulk) createColMetadata() []byte {
return buf.Bytes()
}
-func (b *Bulk) getMetadata() (err error) {
- stmt, err := b.cn.Prepare("SET FMTONLY ON")
+func (b *Bulk) getMetadata(ctx context.Context) (err error) {
+ stmt, err := b.cn.prepareContext(ctx, "SET FMTONLY ON")
if err != nil {
return
}
- _, err = stmt.Exec(nil)
+ _, err = stmt.ExecContext(ctx, nil)
if err != nil {
return
}
- //get columns info
- stmt, err = b.cn.Prepare(fmt.Sprintf("select * from %s SET FMTONLY OFF", b.tablename))
+ // Get columns info.
+ stmt, err = b.cn.prepareContext(ctx, fmt.Sprintf("select * from %s SET FMTONLY OFF", b.tablename))
if err != nil {
return
}
- stmt2 := stmt.(*Stmt)
- cols, err := stmt2.QueryMeta()
+ rows, err := stmt.QueryContext(ctx, nil)
if err != nil {
- return fmt.Errorf("get columns info failed: %v", err.Error())
+ return fmt.Errorf("get columns info failed: %v", err)
}
- b.metadata = cols
+ b.metadata = rows.(*Rows).cols
if b.Debug {
for _, col := range b.metadata {
@@ -298,33 +309,10 @@ func (b *Bulk) getMetadata() (err error) {
}
}
- return nil
-}
-
-// QueryMeta is almost the same as mssql.Stmt.Query, but returns all the columns info.
-func (s *Stmt) QueryMeta() (cols []columnStruct, err error) {
- if err = s.sendQuery(nil); err != nil {
- return
- }
- tokchan := make(chan tokenStruct, 5)
- go processResponse(context.Background(), s.c.sess, tokchan, s.c.outs)
- s.c.clearOuts()
-loop:
- for tok := range tokchan {
- switch token := tok.(type) {
- case doneStruct:
- break loop
- case []columnStruct:
- cols = token
- break loop
- case error:
- return nil, s.c.checkBadConn(token)
- }
- }
- return cols, nil
+ return rows.Close()
}
-func (b *Bulk) makeParam(val DataValue, col columnStruct) (res Param, err error) {
+func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error) {
res.ti.Size = col.ti.Size
res.ti.TypeId = col.ti.TypeId
@@ -420,60 +408,30 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res Param, err error)
if val.(bool) {
res.buffer[0] = 1
}
-
- case typeDateTime2N, typeDateTimeOffsetN:
+ case typeDateTime2N:
switch val := val.(type) {
case time.Time:
- days, ns := dateTime2(val)
- ns /= int64(math.Pow10(int(col.ti.Scale)*-1) * 1000000000)
-
- var data = make([]byte, 5)
-
- data[0] = byte(ns)
- data[1] = byte(ns >> 8)
- data[2] = byte(ns >> 16)
- data[3] = byte(ns >> 24)
- data[4] = byte(ns >> 32)
-
- if col.ti.Scale <= 2 {
- res.ti.Size = 6
- } else if col.ti.Scale <= 4 {
- res.ti.Size = 7
- } else {
- res.ti.Size = 8
- }
- var buf []byte
- buf = make([]byte, res.ti.Size)
- copy(buf, data[0:res.ti.Size-3])
-
- buf[res.ti.Size-3] = byte(days)
- buf[res.ti.Size-2] = byte(days >> 8)
- buf[res.ti.Size-1] = byte(days >> 16)
-
- if col.ti.TypeId == typeDateTimeOffsetN {
- _, offset := val.Zone()
- var offsetMinute = uint16(offset / 60)
- buf = append(buf, byte(offsetMinute))
- buf = append(buf, byte(offsetMinute>>8))
- res.ti.Size = res.ti.Size + 2
- }
-
- res.buffer = buf
-
+ res.buffer = encodeDateTime2(val, int(col.ti.Scale))
+ res.ti.Size = len(res.buffer)
default:
err = fmt.Errorf("mssql: invalid type for datetime2 column: %s", val)
return
}
- case typeDateN:
+ case typeDateTimeOffsetN:
switch val := val.(type) {
case time.Time:
- days, _ := dateTime2(val)
+ res.buffer = encodeDateTimeOffset(val, int(res.ti.Scale))
+ res.ti.Size = len(res.buffer)
- res.ti.Size = 3
- res.buffer = make([]byte, 3)
- res.buffer[0] = byte(days)
- res.buffer[1] = byte(days >> 8)
- res.buffer[2] = byte(days >> 16)
+ default:
+ err = fmt.Errorf("mssql: invalid type for datetimeoffset column: %s", val)
+ return
+ }
+ case typeDateN:
+ switch val := val.(type) {
+ case time.Time:
+ res.buffer = encodeDate(val)
+ res.ti.Size = len(res.buffer)
default:
err = fmt.Errorf("mssql: invalid type for date column: %s", val)
return
@@ -482,31 +440,11 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res Param, err error)
switch val := val.(type) {
case time.Time:
if col.ti.Size == 4 {
- res.ti.Size = 4
- res.buffer = make([]byte, 4)
-
- ref := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC)
- dur := val.Sub(ref)
- days := dur / (24 * time.Hour)
- if days < 0 {
- err = fmt.Errorf("mssql: Date %s is out of range", val)
- return
- }
- mins := val.Hour()*60 + val.Minute()
-
- binary.LittleEndian.PutUint16(res.buffer[0:2], uint16(days))
- binary.LittleEndian.PutUint16(res.buffer[2:4], uint16(mins))
+ res.buffer = encodeDateTim4(val)
+ res.ti.Size = len(res.buffer)
} else if col.ti.Size == 8 {
- res.ti.Size = 8
- res.buffer = make([]byte, 8)
-
- days := divFloor(val.Unix(), 24*60*60)
- //25567 - number of days since Jan 1 1900 UTC to Jan 1 1970
- days = days + 25567
- tm := (val.Hour()*60*60+val.Minute()*60+val.Second())*300 + int(val.Nanosecond()/10000000*3)
-
- binary.LittleEndian.PutUint32(res.buffer[0:4], uint32(days))
- binary.LittleEndian.PutUint32(res.buffer[4:8], uint32(tm))
+ res.buffer = encodeDateTime(val)
+ res.ti.Size = len(res.buffer)
} else {
err = fmt.Errorf("mssql: invalid size of column")
}
@@ -583,7 +521,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res Param, err error)
buf[i] = ub[j]
}
res.buffer = buf
- case typeBigVarBin:
+ case typeBigVarBin, typeBigBinary:
switch val := val.(type) {
case []byte:
res.ti.Size = len(val)
diff --git a/vendor/github.com/denisenkom/go-mssqldb/bulkcopy_sql.go b/vendor/github.com/denisenkom/go-mssqldb/bulkcopy_sql.go
index 0af51df890..709505b2a0 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/bulkcopy_sql.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/bulkcopy_sql.go
@@ -23,7 +23,7 @@ func (d *Driver) OpenConnection(dsn string) (*Conn, error) {
return d.open(context.Background(), dsn)
}
-func (c *Conn) prepareCopyIn(query string) (_ driver.Stmt, err error) {
+func (c *Conn) prepareCopyIn(ctx context.Context, query string) (_ driver.Stmt, err error) {
config_json := query[11:]
bulkconfig := serializableBulkConfig{}
@@ -32,7 +32,7 @@ func (c *Conn) prepareCopyIn(query string) (_ driver.Stmt, err error) {
return
}
- bulkcopy := c.CreateBulk(bulkconfig.TableName, bulkconfig.ColumnsName)
+ bulkcopy := c.CreateBulkContext(ctx, bulkconfig.TableName, bulkconfig.ColumnsName)
bulkcopy.Options = bulkconfig.Options
ci := &copyin{
@@ -61,12 +61,12 @@ func (ci *copyin) NumInput() int {
}
func (ci *copyin) Query(v []driver.Value) (r driver.Rows, err error) {
- return nil, errors.New("ErrNotSupported")
+ panic("should never be called")
}
func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
if ci.closed {
- return nil, errors.New("errCopyInClosed")
+ return nil, errors.New("copyin query is closed")
}
if len(v) == 0 {
diff --git a/vendor/github.com/denisenkom/go-mssqldb/convert.go b/vendor/github.com/denisenkom/go-mssqldb/convert.go
new file mode 100644
index 0000000000..51bd4ee3ac
--- /dev/null
+++ b/vendor/github.com/denisenkom/go-mssqldb/convert.go
@@ -0,0 +1,306 @@
+package mssql
+
+import "errors"
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Type conversions for Scan.
+
+// This file was imported from database.sql.convert for go 1.10.3 with minor modifications to get
+// convertAssign function
+// This function is used internally by sql to convert values during call to Scan, we need same
+// logic to return values for OUTPUT parameters.
+// TODO: sql library should instead expose function defaultCheckNamedValue to be callable by drivers
+
+import (
+ "database/sql"
+ "database/sql/driver"
+ "fmt"
+ "reflect"
+ "strconv"
+ "time"
+)
+
+var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
+
+// convertAssign copies to dest the value in src, converting it if possible.
+// An error is returned if the copy would result in loss of information.
+// dest should be a pointer type.
+func convertAssign(dest, src interface{}) error {
+ // Common cases, without reflect.
+ switch s := src.(type) {
+ case string:
+ switch d := dest.(type) {
+ case *string:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = s
+ return nil
+ case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = []byte(s)
+ return nil
+ case *sql.RawBytes:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = append((*d)[:0], s...)
+ return nil
+ }
+ case []byte:
+ switch d := dest.(type) {
+ case *string:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = string(s)
+ return nil
+ case *interface{}:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = cloneBytes(s)
+ return nil
+ case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = cloneBytes(s)
+ return nil
+ case *sql.RawBytes:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = s
+ return nil
+ }
+ case time.Time:
+ switch d := dest.(type) {
+ case *time.Time:
+ *d = s
+ return nil
+ case *string:
+ *d = s.Format(time.RFC3339Nano)
+ return nil
+ case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = []byte(s.Format(time.RFC3339Nano))
+ return nil
+ case *sql.RawBytes:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
+ return nil
+ }
+ case nil:
+ switch d := dest.(type) {
+ case *interface{}:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = nil
+ return nil
+ case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = nil
+ return nil
+ case *sql.RawBytes:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = nil
+ return nil
+ }
+ }
+
+ var sv reflect.Value
+
+ switch d := dest.(type) {
+ case *string:
+ sv = reflect.ValueOf(src)
+ switch sv.Kind() {
+ case reflect.Bool,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+ reflect.Float32, reflect.Float64:
+ *d = asString(src)
+ return nil
+ }
+ case *[]byte:
+ sv = reflect.ValueOf(src)
+ if b, ok := asBytes(nil, sv); ok {
+ *d = b
+ return nil
+ }
+ case *sql.RawBytes:
+ sv = reflect.ValueOf(src)
+ if b, ok := asBytes([]byte(*d)[:0], sv); ok {
+ *d = sql.RawBytes(b)
+ return nil
+ }
+ case *bool:
+ bv, err := driver.Bool.ConvertValue(src)
+ if err == nil {
+ *d = bv.(bool)
+ }
+ return err
+ case *interface{}:
+ *d = src
+ return nil
+ }
+
+ if scanner, ok := dest.(sql.Scanner); ok {
+ return scanner.Scan(src)
+ }
+
+ dpv := reflect.ValueOf(dest)
+ if dpv.Kind() != reflect.Ptr {
+ return errors.New("destination not a pointer")
+ }
+ if dpv.IsNil() {
+ return errNilPtr
+ }
+
+ if !sv.IsValid() {
+ sv = reflect.ValueOf(src)
+ }
+
+ dv := reflect.Indirect(dpv)
+ if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
+ switch b := src.(type) {
+ case []byte:
+ dv.Set(reflect.ValueOf(cloneBytes(b)))
+ default:
+ dv.Set(sv)
+ }
+ return nil
+ }
+
+ if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
+ dv.Set(sv.Convert(dv.Type()))
+ return nil
+ }
+
+ // The following conversions use a string value as an intermediate representation
+ // to convert between various numeric types.
+ //
+ // This also allows scanning into user defined types such as "type Int int64".
+ // For symmetry, also check for string destination types.
+ switch dv.Kind() {
+ case reflect.Ptr:
+ if src == nil {
+ dv.Set(reflect.Zero(dv.Type()))
+ return nil
+ } else {
+ dv.Set(reflect.New(dv.Type().Elem()))
+ return convertAssign(dv.Interface(), src)
+ }
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ s := asString(src)
+ i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+ }
+ dv.SetInt(i64)
+ return nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ s := asString(src)
+ u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+ }
+ dv.SetUint(u64)
+ return nil
+ case reflect.Float32, reflect.Float64:
+ s := asString(src)
+ f64, err := strconv.ParseFloat(s, dv.Type().Bits())
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+ }
+ dv.SetFloat(f64)
+ return nil
+ case reflect.String:
+ switch v := src.(type) {
+ case string:
+ dv.SetString(v)
+ return nil
+ case []byte:
+ dv.SetString(string(v))
+ return nil
+ }
+ }
+
+ return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
+}
+
+func strconvErr(err error) error {
+ if ne, ok := err.(*strconv.NumError); ok {
+ return ne.Err
+ }
+ return err
+}
+
+func cloneBytes(b []byte) []byte {
+ if b == nil {
+ return nil
+ } else {
+ c := make([]byte, len(b))
+ copy(c, b)
+ return c
+ }
+}
+
+func asString(src interface{}) string {
+ switch v := src.(type) {
+ case string:
+ return v
+ case []byte:
+ return string(v)
+ }
+ rv := reflect.ValueOf(src)
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return strconv.FormatInt(rv.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return strconv.FormatUint(rv.Uint(), 10)
+ case reflect.Float64:
+ return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
+ case reflect.Float32:
+ return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
+ case reflect.Bool:
+ return strconv.FormatBool(rv.Bool())
+ }
+ return fmt.Sprintf("%v", src)
+}
+
+func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return strconv.AppendInt(buf, rv.Int(), 10), true
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return strconv.AppendUint(buf, rv.Uint(), 10), true
+ case reflect.Float32:
+ return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
+ case reflect.Float64:
+ return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
+ case reflect.Bool:
+ return strconv.AppendBool(buf, rv.Bool()), true
+ case reflect.String:
+ s := rv.String()
+ return append(buf, s...), true
+ }
+ return
+}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/doc.go b/vendor/github.com/denisenkom/go-mssqldb/doc.go
index 1bb80c442b..2e54929c57 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/doc.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/doc.go
@@ -1,12 +1,14 @@
// package mssql implements the TDS protocol used to connect to MS SQL Server (sqlserver)
// database servers.
//
-// This package registers two drivers:
+// This package registers the driver:
// sqlserver: uses native "@" parameter placeholder names and does no pre-processing.
-// mssql: expects identifiers to be prefixed with ":" and pre-processes queries.
//
// If the ordinal position is used for query parameters, identifiers will be named
// "@p1", "@p2", ... "@pN".
//
-// Please refer to the README for the format of the DSN.
+// Please refer to the README for the format of the DSN. There are multiple DSN
+// formats accepted: ADO style, ODBC style, and URL style. The following is an
+// example of a URL style DSN:
+// sqlserver://sa:mypass@localhost:1234?database=master&connection+timeout=30
package mssql
diff --git a/vendor/github.com/denisenkom/go-mssqldb/go.mod b/vendor/github.com/denisenkom/go-mssqldb/go.mod
new file mode 100644
index 0000000000..096fc96b20
--- /dev/null
+++ b/vendor/github.com/denisenkom/go-mssqldb/go.mod
@@ -0,0 +1,10 @@
+module github.com/denisenkom/go-mssqldb
+
+go 1.11
+
+require (
+ cloud.google.com/go v0.37.4
+ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c
+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
+ gopkg.in/yaml.v2 v2.2.2 // indirect
+)
diff --git a/vendor/github.com/denisenkom/go-mssqldb/go.sum b/vendor/github.com/denisenkom/go-mssqldb/go.sum
new file mode 100644
index 0000000000..e1936ecf70
--- /dev/null
+++ b/vendor/github.com/denisenkom/go-mssqldb/go.sum
@@ -0,0 +1,168 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.37.2 h1:4y4L7BdHenTfZL0HervofNTHh9Ad6mNX72cQvl+5eH0=
+cloud.google.com/go v0.37.2/go.mod h1:H8IAquKe2L30IxoupDgqTaQvKSwF/c8prYHynGIWQbA=
+git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
+git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
+github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
+github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
+go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
+go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A=
+go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M=
+go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
+golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
+google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
+google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
+google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU=
+google.golang.org/api v0.3.0/go.mod h1:IuvZyQh8jgscv8qWfQ4ABd8m7hEudgBFM/EdhA3BnXw=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/denisenkom/go-mssqldb/parser.go b/vendor/github.com/denisenkom/go-mssqldb/internal/querytext/parser.go
index 8021ca603c..14650e3894 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/parser.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/internal/querytext/parser.go
@@ -1,4 +1,8 @@
-package mssql
+// Package querytext is the old query parser and parameter substitute process.
+// Do not use on new code.
+//
+// This package is not subject to any API compatibility guarantee.
+package querytext
import (
"bytes"
@@ -40,7 +44,11 @@ func (p *parser) write(ch rune) {
type stateFunc func(*parser) stateFunc
-func parseParams(query string) (string, int) {
+// ParseParams rewrites the query from using "?" placeholders
+// to using "@pN" parameter names that SQL Server will accept.
+//
+// This function and package is not subject to any API compatibility guarantee.
+func ParseParams(query string) (string, int) {
p := &parser{
r: bytes.NewReader([]byte(query)),
namedParams: map[string]bool{},
diff --git a/vendor/github.com/denisenkom/go-mssqldb/mssql.go b/vendor/github.com/denisenkom/go-mssqldb/mssql.go
index 8f5ff2d0ce..cf84f3a12b 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/mssql.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/mssql.go
@@ -13,32 +13,37 @@ import (
"reflect"
"strings"
"time"
+ "unicode"
+
+ "github.com/denisenkom/go-mssqldb/internal/querytext"
)
+// ReturnStatus may be used to return the return value from a proc.
+//
+// var rs mssql.ReturnStatus
+// _, err := db.Exec("theproc", &rs)
+// log.Printf("return status = %d", rs)
+type ReturnStatus int32
+
var driverInstance = &Driver{processQueryText: true}
var driverInstanceNoProcess = &Driver{processQueryText: false}
func init() {
sql.Register("mssql", driverInstance)
sql.Register("sqlserver", driverInstanceNoProcess)
- createDialer = func(p *connectParams) dialer {
- return tcpDialer{&net.Dialer{Timeout: p.dial_timeout, KeepAlive: p.keepAlive}}
+ createDialer = func(p *connectParams) Dialer {
+ return netDialer{&net.Dialer{KeepAlive: p.keepAlive}}
}
}
-// Abstract the dialer for testing and for non-TCP based connections.
-type dialer interface {
- Dial(ctx context.Context, addr string) (net.Conn, error)
-}
+var createDialer func(p *connectParams) Dialer
-var createDialer func(p *connectParams) dialer
-
-type tcpDialer struct {
+type netDialer struct {
nd *net.Dialer
}
-func (d tcpDialer) Dial(ctx context.Context, addr string) (net.Conn, error) {
- return d.nd.DialContext(ctx, "tcp", addr)
+func (d netDialer) DialContext(ctx context.Context, network string, addr string) (net.Conn, error) {
+ return d.nd.DialContext(ctx, network, addr)
}
type Driver struct {
@@ -63,6 +68,29 @@ func (d *Driver) Open(dsn string) (driver.Conn, error) {
return d.open(context.Background(), dsn)
}
+func SetLogger(logger Logger) {
+ driverInstance.SetLogger(logger)
+ driverInstanceNoProcess.SetLogger(logger)
+}
+
+func (d *Driver) SetLogger(logger Logger) {
+ d.log = optionalLogger{logger}
+}
+
+// NewConnector creates a new connector from a DSN.
+// The returned connector may be used with sql.OpenDB.
+func NewConnector(dsn string) (*Connector, error) {
+ params, err := parseConnectParams(dsn)
+ if err != nil {
+ return nil, err
+ }
+ c := &Connector{
+ params: params,
+ driver: driverInstanceNoProcess,
+ }
+ return c, nil
+}
+
// Connector holds the parsed DSN and is ready to make a new connection
// at any time.
//
@@ -71,35 +99,64 @@ func (d *Driver) Open(dsn string) (driver.Conn, error) {
type Connector struct {
params connectParams
driver *Driver
-}
-
-// Connect to the server and return a TDS connection.
-func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {
- return c.driver.connect(ctx, c.params)
-}
-// Driver underlying the Connector.
-func (c *Connector) Driver() driver.Driver {
- return c.driver
-}
-
-func SetLogger(logger Logger) {
- driverInstance.SetLogger(logger)
- driverInstanceNoProcess.SetLogger(logger)
-}
-
-func (d *Driver) SetLogger(logger Logger) {
- d.log = optionalLogger{logger}
+ // SessionInitSQL is executed after marking a given session to be reset.
+ // When not present, the next query will still reset the session to the
+ // database defaults.
+ //
+ // When present the connection will immediately mark the session to
+ // be reset, then execute the SessionInitSQL text to setup the session
+ // that may be different from the base database defaults.
+ //
+ // For Example, the application relies on the following defaults
+ // but is not allowed to set them at the database system level.
+ //
+ // SET XACT_ABORT ON;
+ // SET TEXTSIZE -1;
+ // SET ANSI_NULLS ON;
+ // SET LOCK_TIMEOUT 10000;
+ //
+ // SessionInitSQL should not attempt to manually call sp_reset_connection.
+ // This will happen at the TDS layer.
+ //
+ // SessionInitSQL is optional. The session will be reset even if
+ // SessionInitSQL is empty.
+ SessionInitSQL string
+
+ // Dialer sets a custom dialer for all network operations.
+ // If Dialer is not set, normal net dialers are used.
+ Dialer Dialer
+}
+
+type Dialer interface {
+ DialContext(ctx context.Context, network string, addr string) (net.Conn, error)
+}
+
+func (c *Connector) getDialer(p *connectParams) Dialer {
+ if c != nil && c.Dialer != nil {
+ return c.Dialer
+ }
+ return createDialer(p)
}
type Conn struct {
+ connector *Connector
sess *tdsSession
transactionCtx context.Context
+ resetSession bool
processQueryText bool
connectionGood bool
- outs map[string]interface{}
+ outs map[string]interface{}
+ returnStatus *ReturnStatus
+}
+
+func (c *Conn) setReturnStatus(s ReturnStatus) {
+ if c.returnStatus == nil {
+ return
+ }
+ *c.returnStatus = s
}
func (c *Conn) checkBadConn(err error) error {
@@ -117,6 +174,7 @@ func (c *Conn) checkBadConn(err error) error {
case nil:
return nil
case io.EOF:
+ c.connectionGood = false
return driver.ErrBadConn
case driver.ErrBadConn:
// It is an internal programming error if driver.ErrBadConn
@@ -174,7 +232,9 @@ func (c *Conn) sendCommitRequest() error {
{hdrtype: dataStmHdrTransDescr,
data: transDescrHdr{c.sess.tranid, 1}.pack()},
}
- if err := sendCommitXact(c.sess.buf, headers, "", 0, 0, ""); err != nil {
+ reset := c.resetSession
+ c.resetSession = false
+ if err := sendCommitXact(c.sess.buf, headers, "", 0, 0, "", reset); err != nil {
if c.sess.logFlags&logErrors != 0 {
c.sess.log.Printf("Failed to send CommitXact with %v", err)
}
@@ -199,7 +259,9 @@ func (c *Conn) sendRollbackRequest() error {
{hdrtype: dataStmHdrTransDescr,
data: transDescrHdr{c.sess.tranid, 1}.pack()},
}
- if err := sendRollbackXact(c.sess.buf, headers, "", 0, 0, ""); err != nil {
+ reset := c.resetSession
+ c.resetSession = false
+ if err := sendRollbackXact(c.sess.buf, headers, "", 0, 0, "", reset); err != nil {
if c.sess.logFlags&logErrors != 0 {
c.sess.log.Printf("Failed to send RollbackXact with %v", err)
}
@@ -234,12 +296,14 @@ func (c *Conn) sendBeginRequest(ctx context.Context, tdsIsolation isoLevel) erro
{hdrtype: dataStmHdrTransDescr,
data: transDescrHdr{0, 1}.pack()},
}
- if err := sendBeginXact(c.sess.buf, headers, tdsIsolation, ""); err != nil {
+ reset := c.resetSession
+ c.resetSession = false
+ if err := sendBeginXact(c.sess.buf, headers, tdsIsolation, "", reset); err != nil {
if c.sess.logFlags&logErrors != 0 {
c.sess.log.Printf("Failed to send BeginXact with %v", err)
}
c.connectionGood = false
- return fmt.Errorf("Failed to send BiginXant: %v", err)
+ return fmt.Errorf("Failed to send BeginXact: %v", err)
}
return nil
}
@@ -258,12 +322,12 @@ func (d *Driver) open(ctx context.Context, dsn string) (*Conn, error) {
if err != nil {
return nil, err
}
- return d.connect(ctx, params)
+ return d.connect(ctx, nil, params)
}
// connect to the server, using the provided context for dialing only.
-func (d *Driver) connect(ctx context.Context, params connectParams) (*Conn, error) {
- sess, err := connect(ctx, d.log, params)
+func (d *Driver) connect(ctx context.Context, c *Connector, params connectParams) (*Conn, error) {
+ sess, err := connect(ctx, c, d.log, params)
if err != nil {
// main server failed, try fail-over partner
if params.failOverPartner == "" {
@@ -275,7 +339,7 @@ func (d *Driver) connect(ctx context.Context, params connectParams) (*Conn, erro
params.port = params.failOverPort
}
- sess, err = connect(ctx, d.log, params)
+ sess, err = connect(ctx, c, d.log, params)
if err != nil {
// fail-over partner also failed, now fail
return nil, err
@@ -283,12 +347,13 @@ func (d *Driver) connect(ctx context.Context, params connectParams) (*Conn, erro
}
conn := &Conn{
+ connector: c,
sess: sess,
transactionCtx: context.Background(),
processQueryText: d.processQueryText,
connectionGood: true,
}
- conn.sess.log = d.log
+
return conn, nil
}
@@ -314,16 +379,15 @@ func (c *Conn) Prepare(query string) (driver.Stmt, error) {
return nil, driver.ErrBadConn
}
if len(query) > 10 && strings.EqualFold(query[:10], "INSERTBULK") {
- return c.prepareCopyIn(query)
+ return c.prepareCopyIn(context.Background(), query)
}
-
return c.prepareContext(context.Background(), query)
}
func (c *Conn) prepareContext(ctx context.Context, query string) (*Stmt, error) {
paramCount := -1
if c.processQueryText {
- query, paramCount = parseParams(query)
+ query, paramCount = querytext.ParseParams(query)
}
return &Stmt{c, query, paramCount, nil}, nil
}
@@ -362,11 +426,13 @@ func (s *Stmt) sendQuery(args []namedValue) (err error) {
})
}
+ conn := s.c
+
// no need to check number of parameters here, it is checked by database/sql
- if s.c.sess.logFlags&logSQL != 0 {
- s.c.sess.log.Println(s.query)
+ if conn.sess.logFlags&logSQL != 0 {
+ conn.sess.log.Println(s.query)
}
- if s.c.sess.logFlags&logParams != 0 && len(args) > 0 {
+ if conn.sess.logFlags&logParams != 0 && len(args) > 0 {
for i := 0; i < len(args); i++ {
if len(args[i].Name) > 0 {
s.c.sess.log.Printf("\t@%s\t%v\n", args[i].Name, args[i].Value)
@@ -374,36 +440,41 @@ func (s *Stmt) sendQuery(args []namedValue) (err error) {
s.c.sess.log.Printf("\t@p%d\t%v\n", i+1, args[i].Value)
}
}
-
}
+
+ reset := conn.resetSession
+ conn.resetSession = false
if len(args) == 0 {
- if err = sendSqlBatch72(s.c.sess.buf, s.query, headers); err != nil {
- if s.c.sess.logFlags&logErrors != 0 {
- s.c.sess.log.Printf("Failed to send SqlBatch with %v", err)
+ if err = sendSqlBatch72(conn.sess.buf, s.query, headers, reset); err != nil {
+ if conn.sess.logFlags&logErrors != 0 {
+ conn.sess.log.Printf("Failed to send SqlBatch with %v", err)
}
- s.c.connectionGood = false
+ conn.connectionGood = false
return fmt.Errorf("failed to send SQL Batch: %v", err)
}
} else {
- proc := Sp_ExecuteSql
- var params []Param
+ proc := sp_ExecuteSql
+ var params []param
if isProc(s.query) {
proc.name = s.query
- params, _, err = s.makeRPCParams(args, 0)
+ params, _, err = s.makeRPCParams(args, true)
+ if err != nil {
+ return
+ }
} else {
var decls []string
- params, decls, err = s.makeRPCParams(args, 2)
+ params, decls, err = s.makeRPCParams(args, false)
if err != nil {
return
}
params[0] = makeStrParam(s.query)
params[1] = makeStrParam(strings.Join(decls, ","))
}
- if err = sendRpc(s.c.sess.buf, headers, proc, 0, params); err != nil {
- if s.c.sess.logFlags&logErrors != 0 {
- s.c.sess.log.Printf("Failed to send Rpc with %v", err)
+ if err = sendRpc(conn.sess.buf, headers, proc, 0, params, reset); err != nil {
+ if conn.sess.logFlags&logErrors != 0 {
+ conn.sess.log.Printf("Failed to send Rpc with %v", err)
}
- s.c.connectionGood = false
+ conn.connectionGood = false
return fmt.Errorf("Failed to send RPC: %v", err)
}
}
@@ -416,15 +487,61 @@ func isProc(s string) bool {
if len(s) == 0 {
return false
}
- if s[0] == '[' && s[len(s)-1] == ']' && strings.ContainsAny(s, "\n\r") == false {
- return true
+ const (
+ outside = iota
+ text
+ escaped
+ )
+ st := outside
+ var rn1, rPrev rune
+ for _, r := range s {
+ rPrev = rn1
+ rn1 = r
+ switch r {
+ // No newlines or string sequences.
+ case '\n', '\r', '\'', ';':
+ return false
+ }
+ switch st {
+ case outside:
+ switch {
+ case unicode.IsSpace(r):
+ return false
+ case r == '[':
+ st = escaped
+ continue
+ case r == ']' && rPrev == ']':
+ st = escaped
+ continue
+ case unicode.IsLetter(r):
+ st = text
+ }
+ case text:
+ switch {
+ case r == '.':
+ st = outside
+ continue
+ case unicode.IsSpace(r):
+ return false
+ }
+ case escaped:
+ switch {
+ case r == ']':
+ st = outside
+ continue
+ }
+ }
}
- return !strings.ContainsAny(s, " \t\n\r;")
+ return true
}
-func (s *Stmt) makeRPCParams(args []namedValue, offset int) ([]Param, []string, error) {
+func (s *Stmt) makeRPCParams(args []namedValue, isProc bool) ([]param, []string, error) {
var err error
- params := make([]Param, len(args)+offset)
+ var offset int
+ if !isProc {
+ offset = 2
+ }
+ params := make([]param, len(args)+offset)
decls := make([]string, len(args))
for i, val := range args {
params[i+offset], err = s.makeParam(val.Value)
@@ -434,7 +551,7 @@ func (s *Stmt) makeRPCParams(args []namedValue, offset int) ([]Param, []string,
var name string
if len(val.Name) > 0 {
name = "@" + val.Name
- } else {
+ } else if !isProc {
name = fmt.Sprintf("@p%d", val.Ordinal)
}
params[i+offset].Name = name
@@ -498,6 +615,8 @@ loop:
if token.isError() {
return nil, s.c.checkBadConn(token.getError())
}
+ case ReturnStatus:
+ s.c.setReturnStatus(token)
case error:
return nil, s.c.checkBadConn(token)
}
@@ -541,6 +660,8 @@ func (s *Stmt) processExec(ctx context.Context) (res driver.Result, err error) {
if token.isError() {
return nil, token.getError()
}
+ case ReturnStatus:
+ s.c.setReturnStatus(token)
case error:
return nil, token
}
@@ -666,14 +787,14 @@ func (r *Rows) ColumnTypeNullable(index int) (nullable, ok bool) {
return
}
-func makeStrParam(val string) (res Param) {
+func makeStrParam(val string) (res param) {
res.ti.TypeId = typeNVarChar
res.buffer = str2ucs2(val)
res.ti.Size = len(res.buffer)
return
}
-func (s *Stmt) makeParam(val driver.Value) (res Param, err error) {
+func (s *Stmt) makeParam(val driver.Value) (res param, err error) {
if val == nil {
res.ti.TypeId = typeNull
res.buffer = nil
@@ -686,17 +807,34 @@ func (s *Stmt) makeParam(val driver.Value) (res Param, err error) {
res.buffer = make([]byte, 8)
res.ti.Size = 8
binary.LittleEndian.PutUint64(res.buffer, uint64(val))
+ case sql.NullInt64:
+ // only null values should be getting here
+ res.ti.TypeId = typeIntN
+ res.ti.Size = 8
+ res.buffer = []byte{}
+
case float64:
res.ti.TypeId = typeFltN
res.ti.Size = 8
res.buffer = make([]byte, 8)
binary.LittleEndian.PutUint64(res.buffer, math.Float64bits(val))
+ case sql.NullFloat64:
+ // only null values should be getting here
+ res.ti.TypeId = typeFltN
+ res.ti.Size = 8
+ res.buffer = []byte{}
+
case []byte:
res.ti.TypeId = typeBigVarBin
res.ti.Size = len(val)
res.buffer = val
case string:
res = makeStrParam(val)
+ case sql.NullString:
+ // only null values should be getting here
+ res.ti.TypeId = typeNVarChar
+ res.buffer = nil
+ res.ti.Size = 8000
case bool:
res.ti.TypeId = typeBitN
res.ti.Size = 1
@@ -704,37 +842,22 @@ func (s *Stmt) makeParam(val driver.Value) (res Param, err error) {
if val {
res.buffer[0] = 1
}
+ case sql.NullBool:
+ // only null values should be getting here
+ res.ti.TypeId = typeBitN
+ res.ti.Size = 1
+ res.buffer = []byte{}
+
case time.Time:
if s.c.sess.loginAck.TDSVersion >= verTDS73 {
res.ti.TypeId = typeDateTimeOffsetN
res.ti.Scale = 7
- res.ti.Size = 10
- buf := make([]byte, 10)
- res.buffer = buf
- days, ns := dateTime2(val)
- ns /= 100
- buf[0] = byte(ns)
- buf[1] = byte(ns >> 8)
- buf[2] = byte(ns >> 16)
- buf[3] = byte(ns >> 24)
- buf[4] = byte(ns >> 32)
- buf[5] = byte(days)
- buf[6] = byte(days >> 8)
- buf[7] = byte(days >> 16)
- _, offset := val.Zone()
- offset /= 60
- buf[8] = byte(offset)
- buf[9] = byte(offset >> 8)
+ res.buffer = encodeDateTimeOffset(val, int(res.ti.Scale))
+ res.ti.Size = len(res.buffer)
} else {
res.ti.TypeId = typeDateTimeN
- res.ti.Size = 8
- res.buffer = make([]byte, 8)
- ref := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC)
- dur := val.Sub(ref)
- days := dur / (24 * time.Hour)
- tm := (300 * (dur % (24 * time.Hour))) / time.Second
- binary.LittleEndian.PutUint32(res.buffer[0:4], uint32(days))
- binary.LittleEndian.PutUint32(res.buffer[4:8], uint32(tm))
+ res.buffer = encodeDateTime(val)
+ res.ti.Size = len(res.buffer)
}
default:
return s.makeParamExtra(val)
@@ -773,3 +896,83 @@ func (r *Result) LastInsertId() (int64, error) {
lastInsertId := dest[0].(int64)
return lastInsertId, nil
}
+
+var _ driver.Pinger = &Conn{}
+
+// Ping is used to check if the remote server is available and satisfies the Pinger interface.
+func (c *Conn) Ping(ctx context.Context) error {
+ if !c.connectionGood {
+ return driver.ErrBadConn
+ }
+ stmt := &Stmt{c, `select 1;`, 0, nil}
+ _, err := stmt.ExecContext(ctx, nil)
+ return err
+}
+
+var _ driver.ConnBeginTx = &Conn{}
+
+// BeginTx satisfies ConnBeginTx.
+func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
+ if !c.connectionGood {
+ return nil, driver.ErrBadConn
+ }
+ if opts.ReadOnly {
+ return nil, errors.New("Read-only transactions are not supported")
+ }
+
+ var tdsIsolation isoLevel
+ switch sql.IsolationLevel(opts.Isolation) {
+ case sql.LevelDefault:
+ tdsIsolation = isolationUseCurrent
+ case sql.LevelReadUncommitted:
+ tdsIsolation = isolationReadUncommited
+ case sql.LevelReadCommitted:
+ tdsIsolation = isolationReadCommited
+ case sql.LevelWriteCommitted:
+ return nil, errors.New("LevelWriteCommitted isolation level is not supported")
+ case sql.LevelRepeatableRead:
+ tdsIsolation = isolationRepeatableRead
+ case sql.LevelSnapshot:
+ tdsIsolation = isolationSnapshot
+ case sql.LevelSerializable:
+ tdsIsolation = isolationSerializable
+ case sql.LevelLinearizable:
+ return nil, errors.New("LevelLinearizable isolation level is not supported")
+ default:
+ return nil, errors.New("Isolation level is not supported or unknown")
+ }
+ return c.begin(ctx, tdsIsolation)
+}
+
+func (c *Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
+ if !c.connectionGood {
+ return nil, driver.ErrBadConn
+ }
+ if len(query) > 10 && strings.EqualFold(query[:10], "INSERTBULK") {
+ return c.prepareCopyIn(ctx, query)
+ }
+
+ return c.prepareContext(ctx, query)
+}
+
+func (s *Stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
+ if !s.c.connectionGood {
+ return nil, driver.ErrBadConn
+ }
+ list := make([]namedValue, len(args))
+ for i, nv := range args {
+ list[i] = namedValue(nv)
+ }
+ return s.queryContext(ctx, list)
+}
+
+func (s *Stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
+ if !s.c.connectionGood {
+ return nil, driver.ErrBadConn
+ }
+ list := make([]namedValue, len(args))
+ for i, nv := range args {
+ list[i] = namedValue(nv)
+ }
+ return s.exec(ctx, list)
+}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/mssql_go110.go b/vendor/github.com/denisenkom/go-mssqldb/mssql_go110.go
new file mode 100644
index 0000000000..833f047163
--- /dev/null
+++ b/vendor/github.com/denisenkom/go-mssqldb/mssql_go110.go
@@ -0,0 +1,47 @@
+// +build go1.10
+
+package mssql
+
+import (
+ "context"
+ "database/sql/driver"
+)
+
+var _ driver.Connector = &Connector{}
+var _ driver.SessionResetter = &Conn{}
+
+func (c *Conn) ResetSession(ctx context.Context) error {
+ if !c.connectionGood {
+ return driver.ErrBadConn
+ }
+ c.resetSession = true
+
+ if c.connector == nil || len(c.connector.SessionInitSQL) == 0 {
+ return nil
+ }
+
+ s, err := c.prepareContext(ctx, c.connector.SessionInitSQL)
+ if err != nil {
+ return driver.ErrBadConn
+ }
+ _, err = s.exec(ctx, nil)
+ if err != nil {
+ return driver.ErrBadConn
+ }
+
+ return nil
+}
+
+// Connect to the server and return a TDS connection.
+func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {
+ conn, err := c.driver.connect(ctx, c, c.params)
+ if err == nil {
+ err = conn.ResetSession(ctx)
+ }
+ return conn, err
+}
+
+// Driver underlying the Connector.
+func (c *Connector) Driver() driver.Driver {
+ return c.driver
+}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/mssql_go18.go b/vendor/github.com/denisenkom/go-mssqldb/mssql_go18.go
deleted file mode 100644
index 74179c4720..0000000000
--- a/vendor/github.com/denisenkom/go-mssqldb/mssql_go18.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// +build go1.8
-
-package mssql
-
-import (
- "context"
- "database/sql"
- "database/sql/driver"
- "errors"
- "strings"
-)
-
-var _ driver.Pinger = &Conn{}
-
-// Ping is used to check if the remote server is available and satisfies the Pinger interface.
-func (c *Conn) Ping(ctx context.Context) error {
- if !c.connectionGood {
- return driver.ErrBadConn
- }
- stmt := &Stmt{c, `select 1;`, 0, nil}
- _, err := stmt.ExecContext(ctx, nil)
- return err
-}
-
-var _ driver.ConnBeginTx = &Conn{}
-
-// BeginTx satisfies ConnBeginTx.
-func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
- if !c.connectionGood {
- return nil, driver.ErrBadConn
- }
- if opts.ReadOnly {
- return nil, errors.New("Read-only transactions are not supported")
- }
-
- var tdsIsolation isoLevel
- switch sql.IsolationLevel(opts.Isolation) {
- case sql.LevelDefault:
- tdsIsolation = isolationUseCurrent
- case sql.LevelReadUncommitted:
- tdsIsolation = isolationReadUncommited
- case sql.LevelReadCommitted:
- tdsIsolation = isolationReadCommited
- case sql.LevelWriteCommitted:
- return nil, errors.New("LevelWriteCommitted isolation level is not supported")
- case sql.LevelRepeatableRead:
- tdsIsolation = isolationRepeatableRead
- case sql.LevelSnapshot:
- tdsIsolation = isolationSnapshot
- case sql.LevelSerializable:
- tdsIsolation = isolationSerializable
- case sql.LevelLinearizable:
- return nil, errors.New("LevelLinearizable isolation level is not supported")
- default:
- return nil, errors.New("Isolation level is not supported or unknown")
- }
- return c.begin(ctx, tdsIsolation)
-}
-
-func (c *Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
- if !c.connectionGood {
- return nil, driver.ErrBadConn
- }
- if len(query) > 10 && strings.EqualFold(query[:10], "INSERTBULK") {
- return c.prepareCopyIn(query)
- }
-
- return c.prepareContext(ctx, query)
-}
-
-func (s *Stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
- if !s.c.connectionGood {
- return nil, driver.ErrBadConn
- }
- list := make([]namedValue, len(args))
- for i, nv := range args {
- list[i] = namedValue(nv)
- }
- return s.queryContext(ctx, list)
-}
-
-func (s *Stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
- if !s.c.connectionGood {
- return nil, driver.ErrBadConn
- }
- list := make([]namedValue, len(args))
- for i, nv := range args {
- list[i] = namedValue(nv)
- }
- return s.exec(ctx, list)
-}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/mssql_go19.go b/vendor/github.com/denisenkom/go-mssqldb/mssql_go19.go
index 250151abc3..7f2295c384 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/mssql_go19.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/mssql_go19.go
@@ -5,23 +5,64 @@ package mssql
import (
"database/sql"
"database/sql/driver"
+ "errors"
"fmt"
+ "reflect"
+ "time"
+
// "github.com/cockroachdb/apd"
+ "cloud.google.com/go/civil"
)
-// Type alias provided for compibility.
-//
-// Deprecated: users should transition to the new names when possible.
-type MssqlDriver = Driver
-type MssqlBulk = Bulk
-type MssqlBulkOptions = BulkOptions
-type MssqlConn = Conn
-type MssqlResult = Result
-type MssqlRows = Rows
-type MssqlStmt = Stmt
+// Type alias provided for compatibility.
+
+type MssqlDriver = Driver // Deprecated: users should transition to the new name when possible.
+type MssqlBulk = Bulk // Deprecated: users should transition to the new name when possible.
+type MssqlBulkOptions = BulkOptions // Deprecated: users should transition to the new name when possible.
+type MssqlConn = Conn // Deprecated: users should transition to the new name when possible.
+type MssqlResult = Result // Deprecated: users should transition to the new name when possible.
+type MssqlRows = Rows // Deprecated: users should transition to the new name when possible.
+type MssqlStmt = Stmt // Deprecated: users should transition to the new name when possible.
var _ driver.NamedValueChecker = &Conn{}
+// VarChar parameter types.
+type VarChar string
+
+type NVarCharMax string
+type VarCharMax string
+
+// DateTime1 encodes parameters to original DateTime SQL types.
+type DateTime1 time.Time
+
+// DateTimeOffset encodes parameters to DateTimeOffset, preserving the UTC offset.
+type DateTimeOffset time.Time
+
+func convertInputParameter(val interface{}) (interface{}, error) {
+ switch v := val.(type) {
+ case VarChar:
+ return val, nil
+ case NVarCharMax:
+ return val, nil
+ case VarCharMax:
+ return val, nil
+ case DateTime1:
+ return val, nil
+ case DateTimeOffset:
+ return val, nil
+ case civil.Date:
+ return val, nil
+ case civil.DateTime:
+ return val, nil
+ case civil.Time:
+ return val, nil
+ // case *apd.Decimal:
+ // return nil
+ default:
+ return driver.DefaultParameterConverter.ConvertValue(v)
+ }
+}
+
func (c *Conn) CheckNamedValue(nv *driver.NamedValue) error {
switch v := nv.Value.(type) {
case sql.Out:
@@ -30,35 +71,126 @@ func (c *Conn) CheckNamedValue(nv *driver.NamedValue) error {
}
c.outs[nv.Name] = v.Dest
+ if v.Dest == nil {
+ return errors.New("destination is a nil pointer")
+ }
+
+ dest_info := reflect.ValueOf(v.Dest)
+ if dest_info.Kind() != reflect.Ptr {
+ return errors.New("destination not a pointer")
+ }
+
+ if dest_info.IsNil() {
+ return errors.New("destination is a nil pointer")
+ }
+
+ pointed_value := reflect.Indirect(dest_info)
+
+ // don't allow pointer to a pointer, only pointer to a value can be handled
+ // correctly
+ if pointed_value.Kind() == reflect.Ptr {
+ return errors.New("destination is a pointer to a pointer")
+ }
+
// Unwrap the Out value and check the inner value.
- lnv := *nv
- lnv.Value = v.Dest
- err := c.CheckNamedValue(&lnv)
+ val := pointed_value.Interface()
+ if val == nil {
+ return errors.New("MSSQL does not allow NULL value without type for OUTPUT parameters")
+ }
+ conv, err := convertInputParameter(val)
if err != nil {
- if err != driver.ErrSkip {
- return err
- }
- lnv.Value, err = driver.DefaultParameterConverter.ConvertValue(lnv.Value)
- if err != nil {
- return err
- }
+ return err
}
- nv.Value = sql.Out{Dest: lnv.Value}
+ if conv == nil {
+ // if we replace with nil we would lose type information
+ nv.Value = sql.Out{Dest: val}
+ } else {
+ nv.Value = sql.Out{Dest: conv}
+ }
+ return nil
+ case *ReturnStatus:
+ *v = 0 // By default the return value should be zero.
+ c.returnStatus = v
+ return driver.ErrRemoveArgument
+ case TVP:
return nil
- // case *apd.Decimal:
- // return nil
default:
- return driver.ErrSkip
+ var err error
+ nv.Value, err = convertInputParameter(nv.Value)
+ return err
}
}
-func (s *Stmt) makeParamExtra(val driver.Value) (res Param, err error) {
+func (s *Stmt) makeParamExtra(val driver.Value) (res param, err error) {
switch val := val.(type) {
+ case VarChar:
+ res.ti.TypeId = typeBigVarChar
+ res.buffer = []byte(val)
+ res.ti.Size = len(res.buffer)
+ case VarCharMax:
+ res.ti.TypeId = typeBigVarChar
+ res.buffer = []byte(val)
+ res.ti.Size = 0 // currently zero forces varchar(max)
+ case NVarCharMax:
+ res.ti.TypeId = typeNVarChar
+ res.buffer = str2ucs2(string(val))
+ res.ti.Size = 0 // currently zero forces nvarchar(max)
+ case DateTime1:
+ t := time.Time(val)
+ res.ti.TypeId = typeDateTimeN
+ res.buffer = encodeDateTime(t)
+ res.ti.Size = len(res.buffer)
+ case DateTimeOffset:
+ res.ti.TypeId = typeDateTimeOffsetN
+ res.ti.Scale = 7
+ res.buffer = encodeDateTimeOffset(time.Time(val), int(res.ti.Scale))
+ res.ti.Size = len(res.buffer)
+ case civil.Date:
+ res.ti.TypeId = typeDateN
+ res.buffer = encodeDate(val.In(time.UTC))
+ res.ti.Size = len(res.buffer)
+ case civil.DateTime:
+ res.ti.TypeId = typeDateTime2N
+ res.ti.Scale = 7
+ res.buffer = encodeDateTime2(val.In(time.UTC), int(res.ti.Scale))
+ res.ti.Size = len(res.buffer)
+ case civil.Time:
+ res.ti.TypeId = typeTimeN
+ res.ti.Scale = 7
+ res.buffer = encodeTime(val.Hour, val.Minute, val.Second, val.Nanosecond, int(res.ti.Scale))
+ res.ti.Size = len(res.buffer)
case sql.Out:
res, err = s.makeParam(val.Dest)
res.Flags = fByRevValue
+ case TVP:
+ err = val.check()
+ if err != nil {
+ return
+ }
+ schema, name, errGetName := getSchemeAndName(val.TypeName)
+ if errGetName != nil {
+ return
+ }
+ res.ti.UdtInfo.TypeName = name
+ res.ti.UdtInfo.SchemaName = schema
+ res.ti.TypeId = typeTvp
+ columnStr, tvpFieldIndexes, errCalTypes := val.columnTypes()
+ if errCalTypes != nil {
+ err = errCalTypes
+ return
+ }
+ res.buffer, err = val.encode(schema, name, columnStr, tvpFieldIndexes)
+ if err != nil {
+ return
+ }
+ res.ti.Size = len(res.buffer)
+
default:
err = fmt.Errorf("mssql: unknown type for %T", val)
}
return
}
+
+func scanIntoOut(name string, fromServer, scanInto interface{}) error {
+ return convertAssign(scanInto, fromServer)
+}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/mssql_go19pre.go b/vendor/github.com/denisenkom/go-mssqldb/mssql_go19pre.go
index 3bad7fb008..9680f5107e 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/mssql_go19pre.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/mssql_go19pre.go
@@ -7,6 +7,10 @@ import (
"fmt"
)
-func (s *Stmt) makeParamExtra(val driver.Value) (Param, error) {
- return Param{}, fmt.Errorf("mssql: unknown type for %T", val)
+func (s *Stmt) makeParamExtra(val driver.Value) (param, error) {
+ return param{}, fmt.Errorf("mssql: unknown type for %T", val)
+}
+
+func scanIntoOut(name string, fromServer, scanInto interface{}) error {
+ return fmt.Errorf("mssql: unsupported OUTPUT type, use a newer Go version")
}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/net.go b/vendor/github.com/denisenkom/go-mssqldb/net.go
index 8c3c8ef8b1..e3864d1a22 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/net.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/net.go
@@ -14,7 +14,7 @@ type timeoutConn struct {
continueRead bool
}
-func NewTimeoutConn(conn net.Conn, timeout time.Duration) *timeoutConn {
+func newTimeoutConn(conn net.Conn, timeout time.Duration) *timeoutConn {
return &timeoutConn{
c: conn,
timeout: timeout,
@@ -48,9 +48,11 @@ func (c *timeoutConn) Read(b []byte) (n int, err error) {
n, err = c.buf.Read(b)
return
}
- err = c.c.SetDeadline(time.Now().Add(c.timeout))
- if err != nil {
- return
+ if c.timeout > 0 {
+ err = c.c.SetDeadline(time.Now().Add(c.timeout))
+ if err != nil {
+ return
+ }
}
return c.c.Read(b)
}
@@ -58,7 +60,7 @@ func (c *timeoutConn) Read(b []byte) (n int, err error) {
func (c *timeoutConn) Write(b []byte) (n int, err error) {
if c.buf != nil {
if !c.packetPending {
- c.buf.BeginPacket(packPrelogin)
+ c.buf.BeginPacket(packPrelogin, false)
c.packetPending = true
}
n, err = c.buf.Write(b)
@@ -67,9 +69,11 @@ func (c *timeoutConn) Write(b []byte) (n int, err error) {
}
return
}
- err = c.c.SetDeadline(time.Now().Add(c.timeout))
- if err != nil {
- return
+ if c.timeout > 0 {
+ err = c.c.SetDeadline(time.Now().Add(c.timeout))
+ if err != nil {
+ return
+ }
}
return c.c.Write(b)
}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/ntlm.go b/vendor/github.com/denisenkom/go-mssqldb/ntlm.go
index 5bed668430..7c0cc4f785 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/ntlm.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/ntlm.go
@@ -15,44 +15,44 @@ import (
)
const (
- NEGOTIATE_MESSAGE = 1
- CHALLENGE_MESSAGE = 2
- AUTHENTICATE_MESSAGE = 3
+ _NEGOTIATE_MESSAGE = 1
+ _CHALLENGE_MESSAGE = 2
+ _AUTHENTICATE_MESSAGE = 3
)
const (
- NEGOTIATE_UNICODE = 0x00000001
- NEGOTIATE_OEM = 0x00000002
- NEGOTIATE_TARGET = 0x00000004
- NEGOTIATE_SIGN = 0x00000010
- NEGOTIATE_SEAL = 0x00000020
- NEGOTIATE_DATAGRAM = 0x00000040
- NEGOTIATE_LMKEY = 0x00000080
- NEGOTIATE_NTLM = 0x00000200
- NEGOTIATE_ANONYMOUS = 0x00000800
- NEGOTIATE_OEM_DOMAIN_SUPPLIED = 0x00001000
- NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000
- NEGOTIATE_ALWAYS_SIGN = 0x00008000
- NEGOTIATE_TARGET_TYPE_DOMAIN = 0x00010000
- NEGOTIATE_TARGET_TYPE_SERVER = 0x00020000
- NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000
- NEGOTIATE_IDENTIFY = 0x00100000
- REQUEST_NON_NT_SESSION_KEY = 0x00400000
- NEGOTIATE_TARGET_INFO = 0x00800000
- NEGOTIATE_VERSION = 0x02000000
- NEGOTIATE_128 = 0x20000000
- NEGOTIATE_KEY_EXCH = 0x40000000
- NEGOTIATE_56 = 0x80000000
+ _NEGOTIATE_UNICODE = 0x00000001
+ _NEGOTIATE_OEM = 0x00000002
+ _NEGOTIATE_TARGET = 0x00000004
+ _NEGOTIATE_SIGN = 0x00000010
+ _NEGOTIATE_SEAL = 0x00000020
+ _NEGOTIATE_DATAGRAM = 0x00000040
+ _NEGOTIATE_LMKEY = 0x00000080
+ _NEGOTIATE_NTLM = 0x00000200
+ _NEGOTIATE_ANONYMOUS = 0x00000800
+ _NEGOTIATE_OEM_DOMAIN_SUPPLIED = 0x00001000
+ _NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000
+ _NEGOTIATE_ALWAYS_SIGN = 0x00008000
+ _NEGOTIATE_TARGET_TYPE_DOMAIN = 0x00010000
+ _NEGOTIATE_TARGET_TYPE_SERVER = 0x00020000
+ _NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000
+ _NEGOTIATE_IDENTIFY = 0x00100000
+ _REQUEST_NON_NT_SESSION_KEY = 0x00400000
+ _NEGOTIATE_TARGET_INFO = 0x00800000
+ _NEGOTIATE_VERSION = 0x02000000
+ _NEGOTIATE_128 = 0x20000000
+ _NEGOTIATE_KEY_EXCH = 0x40000000
+ _NEGOTIATE_56 = 0x80000000
)
-const NEGOTIATE_FLAGS = NEGOTIATE_UNICODE |
- NEGOTIATE_NTLM |
- NEGOTIATE_OEM_DOMAIN_SUPPLIED |
- NEGOTIATE_OEM_WORKSTATION_SUPPLIED |
- NEGOTIATE_ALWAYS_SIGN |
- NEGOTIATE_EXTENDED_SESSIONSECURITY
+const _NEGOTIATE_FLAGS = _NEGOTIATE_UNICODE |
+ _NEGOTIATE_NTLM |
+ _NEGOTIATE_OEM_DOMAIN_SUPPLIED |
+ _NEGOTIATE_OEM_WORKSTATION_SUPPLIED |
+ _NEGOTIATE_ALWAYS_SIGN |
+ _NEGOTIATE_EXTENDED_SESSIONSECURITY
-type NTLMAuth struct {
+type ntlmAuth struct {
Domain string
UserName string
Password string
@@ -64,7 +64,7 @@ func getAuth(user, password, service, workstation string) (auth, bool) {
return nil, false
}
domain_user := strings.SplitN(user, "\\", 2)
- return &NTLMAuth{
+ return &ntlmAuth{
Domain: domain_user[0],
UserName: domain_user[1],
Password: password,
@@ -86,13 +86,13 @@ func utf16le(val string) []byte {
return v
}
-func (auth *NTLMAuth) InitialBytes() ([]byte, error) {
+func (auth *ntlmAuth) InitialBytes() ([]byte, error) {
domain_len := len(auth.Domain)
workstation_len := len(auth.Workstation)
msg := make([]byte, 40+domain_len+workstation_len)
copy(msg, []byte("NTLMSSP\x00"))
- binary.LittleEndian.PutUint32(msg[8:], NEGOTIATE_MESSAGE)
- binary.LittleEndian.PutUint32(msg[12:], NEGOTIATE_FLAGS)
+ binary.LittleEndian.PutUint32(msg[8:], _NEGOTIATE_MESSAGE)
+ binary.LittleEndian.PutUint32(msg[12:], _NEGOTIATE_FLAGS)
// Domain Name Fields
binary.LittleEndian.PutUint16(msg[16:], uint16(domain_len))
binary.LittleEndian.PutUint16(msg[18:], uint16(domain_len))
@@ -198,11 +198,11 @@ func ntlmSessionResponse(clientNonce [8]byte, serverChallenge [8]byte, password
return response(hash, passwordHash)
}
-func (auth *NTLMAuth) NextBytes(bytes []byte) ([]byte, error) {
+func (auth *ntlmAuth) NextBytes(bytes []byte) ([]byte, error) {
if string(bytes[0:8]) != "NTLMSSP\x00" {
return nil, errorNTLM
}
- if binary.LittleEndian.Uint32(bytes[8:12]) != CHALLENGE_MESSAGE {
+ if binary.LittleEndian.Uint32(bytes[8:12]) != _CHALLENGE_MESSAGE {
return nil, errorNTLM
}
flags := binary.LittleEndian.Uint32(bytes[20:24])
@@ -210,7 +210,7 @@ func (auth *NTLMAuth) NextBytes(bytes []byte) ([]byte, error) {
copy(challenge[:], bytes[24:32])
var lm, nt []byte
- if (flags & NEGOTIATE_EXTENDED_SESSIONSECURITY) != 0 {
+ if (flags & _NEGOTIATE_EXTENDED_SESSIONSECURITY) != 0 {
nonce := clientChallenge()
var lm_bytes [24]byte
copy(lm_bytes[:8], nonce[:])
@@ -235,7 +235,7 @@ func (auth *NTLMAuth) NextBytes(bytes []byte) ([]byte, error) {
msg := make([]byte, 88+lm_len+nt_len+domain_len+user_len+workstation_len)
copy(msg, []byte("NTLMSSP\x00"))
- binary.LittleEndian.PutUint32(msg[8:], AUTHENTICATE_MESSAGE)
+ binary.LittleEndian.PutUint32(msg[8:], _AUTHENTICATE_MESSAGE)
// Lm Challenge Response Fields
binary.LittleEndian.PutUint16(msg[12:], uint16(lm_len))
binary.LittleEndian.PutUint16(msg[14:], uint16(lm_len))
@@ -279,5 +279,5 @@ func (auth *NTLMAuth) NextBytes(bytes []byte) ([]byte, error) {
return msg, nil
}
-func (auth *NTLMAuth) Free() {
+func (auth *ntlmAuth) Free() {
}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/rpc.go b/vendor/github.com/denisenkom/go-mssqldb/rpc.go
index 00b9b1e217..4ca22578fa 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/rpc.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/rpc.go
@@ -4,7 +4,7 @@ import (
"encoding/binary"
)
-type ProcId struct {
+type procId struct {
id uint16
name string
}
@@ -15,24 +15,13 @@ const (
fDefaultValue = 2
)
-type Param struct {
+type param struct {
Name string
Flags uint8
ti typeInfo
buffer []byte
}
-func MakeProcId(name string) (res ProcId) {
- res.name = name
- if len(name) == 0 {
- panic("Proc name shouln't be empty")
- }
- if len(name) >= 0xffff {
- panic("Invalid length of procedure name, should be less than 0xffff")
- }
- return res
-}
-
const (
fWithRecomp = 1
fNoMetaData = 2
@@ -40,25 +29,25 @@ const (
)
var (
- Sp_Cursor = ProcId{1, ""}
- Sp_CursorOpen = ProcId{2, ""}
- Sp_CursorPrepare = ProcId{3, ""}
- Sp_CursorExecute = ProcId{4, ""}
- Sp_CursorPrepExec = ProcId{5, ""}
- Sp_CursorUnprepare = ProcId{6, ""}
- Sp_CursorFetch = ProcId{7, ""}
- Sp_CursorOption = ProcId{8, ""}
- Sp_CursorClose = ProcId{9, ""}
- Sp_ExecuteSql = ProcId{10, ""}
- Sp_Prepare = ProcId{11, ""}
- Sp_PrepExec = ProcId{13, ""}
- Sp_PrepExecRpc = ProcId{14, ""}
- Sp_Unprepare = ProcId{15, ""}
+ sp_Cursor = procId{1, ""}
+ sp_CursorOpen = procId{2, ""}
+ sp_CursorPrepare = procId{3, ""}
+ sp_CursorExecute = procId{4, ""}
+ sp_CursorPrepExec = procId{5, ""}
+ sp_CursorUnprepare = procId{6, ""}
+ sp_CursorFetch = procId{7, ""}
+ sp_CursorOption = procId{8, ""}
+ sp_CursorClose = procId{9, ""}
+ sp_ExecuteSql = procId{10, ""}
+ sp_Prepare = procId{11, ""}
+ sp_PrepExec = procId{13, ""}
+ sp_PrepExecRpc = procId{14, ""}
+ sp_Unprepare = procId{15, ""}
)
// http://msdn.microsoft.com/en-us/library/dd357576.aspx
-func sendRpc(buf *tdsBuffer, headers []headerStruct, proc ProcId, flags uint16, params []Param) (err error) {
- buf.BeginPacket(packRPCRequest)
+func sendRpc(buf *tdsBuffer, headers []headerStruct, proc procId, flags uint16, params []param, resetSession bool) (err error) {
+ buf.BeginPacket(packRPCRequest, resetSession)
writeAllHeaders(buf, headers)
if len(proc.name) == 0 {
var idswitch uint16 = 0xffff
diff --git a/vendor/github.com/denisenkom/go-mssqldb/tds.go b/vendor/github.com/denisenkom/go-mssqldb/tds.go
index 54ac6dbad5..a924e90109 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/tds.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/tds.go
@@ -50,16 +50,16 @@ func parseInstances(msg []byte) map[string]map[string]string {
return results
}
-func getInstances(ctx context.Context, address string) (map[string]map[string]string, error) {
- dialer := &net.Dialer{
- Timeout: 5 * time.Second,
- }
- conn, err := dialer.DialContext(ctx, "udp", address+":1434")
+func getInstances(ctx context.Context, d Dialer, address string) (map[string]map[string]string, error) {
+ maxTime := 5 * time.Second
+ ctx, cancel := context.WithTimeout(ctx, maxTime)
+ defer cancel()
+ conn, err := d.DialContext(ctx, "udp", address+":1434")
if err != nil {
return nil, err
}
defer conn.Close()
- conn.SetDeadline(time.Now().Add(5 * time.Second))
+ conn.SetDeadline(time.Now().Add(maxTime))
_, err = conn.Write([]byte{3})
if err != nil {
return nil, err
@@ -152,19 +152,19 @@ type columnStruct struct {
ti typeInfo
}
-type KeySlice []uint8
+type keySlice []uint8
-func (p KeySlice) Len() int { return len(p) }
-func (p KeySlice) Less(i, j int) bool { return p[i] < p[j] }
-func (p KeySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p keySlice) Len() int { return len(p) }
+func (p keySlice) Less(i, j int) bool { return p[i] < p[j] }
+func (p keySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// http://msdn.microsoft.com/en-us/library/dd357559.aspx
func writePrelogin(w *tdsBuffer, fields map[uint8][]byte) error {
var err error
- w.BeginPacket(packPrelogin)
+ w.BeginPacket(packPrelogin, false)
offset := uint16(5*len(fields) + 1)
- keys := make(KeySlice, 0, len(fields))
+ keys := make(keySlice, 0, len(fields))
for k, _ := range fields {
keys = append(keys, k)
}
@@ -352,7 +352,7 @@ func manglePassword(password string) []byte {
// http://msdn.microsoft.com/en-us/library/dd304019.aspx
func sendLogin(w *tdsBuffer, login login) error {
- w.BeginPacket(packLogin7)
+ w.BeginPacket(packLogin7, false)
hostname := str2ucs2(login.HostName)
username := str2ucs2(login.UserName)
password := manglePassword(login.Password)
@@ -633,8 +633,8 @@ func writeAllHeaders(w io.Writer, headers []headerStruct) (err error) {
return nil
}
-func sendSqlBatch72(buf *tdsBuffer, sqltext string, headers []headerStruct) (err error) {
- buf.BeginPacket(packSQLBatch)
+func sendSqlBatch72(buf *tdsBuffer, sqltext string, headers []headerStruct, resetSession bool) (err error) {
+ buf.BeginPacket(packSQLBatch, resetSession)
if err = writeAllHeaders(buf, headers); err != nil {
return
@@ -650,33 +650,34 @@ func sendSqlBatch72(buf *tdsBuffer, sqltext string, headers []headerStruct) (err
// 2.2.1.7 Attention: https://msdn.microsoft.com/en-us/library/dd341449.aspx
// 4.19.2 Out-of-Band Attention Signal: https://msdn.microsoft.com/en-us/library/dd305167.aspx
func sendAttention(buf *tdsBuffer) error {
- buf.BeginPacket(packAttention)
+ buf.BeginPacket(packAttention, false)
return buf.FinishPacket()
}
type connectParams struct {
- logFlags uint64
- port uint64
- host string
- instance string
- database string
- user string
- password string
- dial_timeout time.Duration
- conn_timeout time.Duration
- keepAlive time.Duration
- encrypt bool
- disableEncryption bool
- trustServerCertificate bool
- certificate string
- hostInCertificate string
- serverSPN string
- workstation string
- appname string
- typeFlags uint8
- failOverPartner string
- failOverPort uint64
- packetSize uint16
+ logFlags uint64
+ port uint64
+ host string
+ instance string
+ database string
+ user string
+ password string
+ dial_timeout time.Duration
+ conn_timeout time.Duration
+ keepAlive time.Duration
+ encrypt bool
+ disableEncryption bool
+ trustServerCertificate bool
+ certificate string
+ hostInCertificate string
+ hostInCertificateProvided bool
+ serverSPN string
+ workstation string
+ appname string
+ typeFlags uint8
+ failOverPartner string
+ failOverPort uint64
+ packetSize uint16
}
func splitConnectionString(dsn string) (res map[string]string) {
@@ -938,13 +939,13 @@ func parseConnectParams(dsn string) (connectParams, error) {
strlog, ok := params["log"]
if ok {
var err error
- p.logFlags, err = strconv.ParseUint(strlog, 10, 0)
+ p.logFlags, err = strconv.ParseUint(strlog, 10, 64)
if err != nil {
return p, fmt.Errorf("Invalid log parameter '%s': %s", strlog, err.Error())
}
}
server := params["server"]
- parts := strings.SplitN(server, "\\", 2)
+ parts := strings.SplitN(server, `\`, 2)
p.host = parts[0]
if p.host == "." || strings.ToUpper(p.host) == "(LOCAL)" || p.host == "" {
p.host = "localhost"
@@ -960,7 +961,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
strport, ok := params["port"]
if ok {
var err error
- p.port, err = strconv.ParseUint(strport, 0, 16)
+ p.port, err = strconv.ParseUint(strport, 10, 16)
if err != nil {
f := "Invalid tcp port '%v': %v"
return p, fmt.Errorf(f, strport, err.Error())
@@ -992,20 +993,20 @@ func parseConnectParams(dsn string) (connectParams, error) {
}
// https://msdn.microsoft.com/en-us/library/dd341108.aspx
- p.dial_timeout = 15 * time.Second
- p.conn_timeout = 30 * time.Second
- strconntimeout, ok := params["connection timeout"]
- if ok {
- timeout, err := strconv.ParseUint(strconntimeout, 0, 16)
+ //
+ // Do not set a connection timeout. Use Context to manage such things.
+ // Default to zero, but still allow it to be set.
+ if strconntimeout, ok := params["connection timeout"]; ok {
+ timeout, err := strconv.ParseUint(strconntimeout, 10, 64)
if err != nil {
f := "Invalid connection timeout '%v': %v"
return p, fmt.Errorf(f, strconntimeout, err.Error())
}
p.conn_timeout = time.Duration(timeout) * time.Second
}
- strdialtimeout, ok := params["dial timeout"]
- if ok {
- timeout, err := strconv.ParseUint(strdialtimeout, 0, 16)
+ p.dial_timeout = 15 * time.Second
+ if strdialtimeout, ok := params["dial timeout"]; ok {
+ timeout, err := strconv.ParseUint(strdialtimeout, 10, 64)
if err != nil {
f := "Invalid dial timeout '%v': %v"
return p, fmt.Errorf(f, strdialtimeout, err.Error())
@@ -1016,9 +1017,8 @@ func parseConnectParams(dsn string) (connectParams, error) {
// default keep alive should be 30 seconds according to spec:
// https://msdn.microsoft.com/en-us/library/dd341108.aspx
p.keepAlive = 30 * time.Second
-
if keepAlive, ok := params["keepalive"]; ok {
- timeout, err := strconv.ParseUint(keepAlive, 0, 16)
+ timeout, err := strconv.ParseUint(keepAlive, 10, 64)
if err != nil {
f := "Invalid keepAlive value '%s': %s"
return p, fmt.Errorf(f, keepAlive, err.Error())
@@ -1051,8 +1051,11 @@ func parseConnectParams(dsn string) (connectParams, error) {
}
p.certificate = params["certificate"]
p.hostInCertificate, ok = params["hostnameincertificate"]
- if !ok {
+ if ok {
+ p.hostInCertificateProvided = true
+ } else {
p.hostInCertificate = p.host
+ p.hostInCertificateProvided = false
}
serverSPN, ok := params["serverspn"]
@@ -1112,7 +1115,7 @@ type auth interface {
// SQL Server AlwaysOn Availability Group Listeners are bound by DNS to a
// list of IP addresses. So if there is more than one, try them all and
// use the first one that allows a connection.
-func dialConnection(ctx context.Context, p connectParams) (conn net.Conn, err error) {
+func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn net.Conn, err error) {
var ips []net.IP
ips, err = net.LookupIP(p.host)
if err != nil {
@@ -1123,9 +1126,9 @@ func dialConnection(ctx context.Context, p connectParams) (conn net.Conn, err er
ips = []net.IP{ip}
}
if len(ips) == 1 {
- d := createDialer(&p)
+ d := c.getDialer(&p)
addr := net.JoinHostPort(ips[0].String(), strconv.Itoa(int(p.port)))
- conn, err = d.Dial(ctx, addr)
+ conn, err = d.DialContext(ctx, "tcp", addr)
} else {
//Try Dials in parallel to avoid waiting for timeouts.
@@ -1134,9 +1137,9 @@ func dialConnection(ctx context.Context, p connectParams) (conn net.Conn, err er
portStr := strconv.Itoa(int(p.port))
for _, ip := range ips {
go func(ip net.IP) {
- d := createDialer(&p)
+ d := c.getDialer(&p)
addr := net.JoinHostPort(ip.String(), portStr)
- conn, err := d.Dial(ctx, addr)
+ conn, err := d.DialContext(ctx, "tcp", addr)
if err == nil {
connChan <- conn
} else {
@@ -1174,12 +1177,18 @@ func dialConnection(ctx context.Context, p connectParams) (conn net.Conn, err er
return conn, err
}
-func connect(ctx context.Context, log optionalLogger, p connectParams) (res *tdsSession, err error) {
- res = nil
+func connect(ctx context.Context, c *Connector, log optionalLogger, p connectParams) (res *tdsSession, err error) {
+ dialCtx := ctx
+ if p.dial_timeout > 0 {
+ var cancel func()
+ dialCtx, cancel = context.WithTimeout(ctx, p.dial_timeout)
+ defer cancel()
+ }
// if instance is specified use instance resolution service
if p.instance != "" {
p.instance = strings.ToUpper(p.instance)
- instances, err := getInstances(ctx, p.host)
+ d := c.getDialer(&p)
+ instances, err := getInstances(dialCtx, d, p.host)
if err != nil {
f := "Unable to get instances from Sql Server Browser on host %v: %v"
return nil, fmt.Errorf(f, p.host, err.Error())
@@ -1197,12 +1206,12 @@ func connect(ctx context.Context, log optionalLogger, p connectParams) (res *tds
}
initiate_connection:
- conn, err := dialConnection(ctx, p)
+ conn, err := dialConnection(dialCtx, c, p)
if err != nil {
return nil, err
}
- toconn := NewTimeoutConn(conn, p.conn_timeout)
+ toconn := newTimeoutConn(conn, p.conn_timeout)
outbuf := newTdsBuffer(p.packetSize, toconn)
sess := tdsSession{
@@ -1313,42 +1322,43 @@ initiate_connection:
}
// processing login response
- var sspi_msg []byte
-continue_login:
- tokchan := make(chan tokenStruct, 5)
- go processResponse(context.Background(), &sess, tokchan, nil)
success := false
- for tok := range tokchan {
- switch token := tok.(type) {
- case sspiMsg:
- sspi_msg, err = auth.NextBytes(token)
- if err != nil {
- return nil, err
- }
- case loginAckStruct:
- success = true
- sess.loginAck = token
- case error:
- return nil, fmt.Errorf("Login error: %s", token.Error())
- case doneStruct:
- if token.isError() {
- return nil, fmt.Errorf("Login error: %s", token.getError())
+ for {
+ tokchan := make(chan tokenStruct, 5)
+ go processResponse(context.Background(), &sess, tokchan, nil)
+ for tok := range tokchan {
+ switch token := tok.(type) {
+ case sspiMsg:
+ sspi_msg, err := auth.NextBytes(token)
+ if err != nil {
+ return nil, err
+ }
+ if sspi_msg != nil && len(sspi_msg) > 0 {
+ outbuf.BeginPacket(packSSPIMessage, false)
+ _, err = outbuf.Write(sspi_msg)
+ if err != nil {
+ return nil, err
+ }
+ err = outbuf.FinishPacket()
+ if err != nil {
+ return nil, err
+ }
+ sspi_msg = nil
+ }
+ case loginAckStruct:
+ success = true
+ sess.loginAck = token
+ case error:
+ return nil, fmt.Errorf("Login error: %s", token.Error())
+ case doneStruct:
+ if token.isError() {
+ return nil, fmt.Errorf("Login error: %s", token.getError())
+ }
+ goto loginEnd
}
}
}
- if sspi_msg != nil {
- outbuf.BeginPacket(packSSPIMessage)
- _, err = outbuf.Write(sspi_msg)
- if err != nil {
- return nil, err
- }
- err = outbuf.FinishPacket()
- if err != nil {
- return nil, err
- }
- sspi_msg = nil
- goto continue_login
- }
+loginEnd:
if !success {
return nil, fmt.Errorf("Login failed")
}
@@ -1356,6 +1366,9 @@ continue_login:
toconn.Close()
p.host = sess.routedServer
p.port = uint64(sess.routedPort)
+ if !p.hostInCertificateProvided {
+ p.hostInCertificate = sess.routedServer
+ }
goto initiate_connection
}
return &sess, nil
diff --git a/vendor/github.com/denisenkom/go-mssqldb/token.go b/vendor/github.com/denisenkom/go-mssqldb/token.go
index 5f2167eb86..1acac8a5d2 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/token.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/token.go
@@ -213,7 +213,7 @@ func processEnvChg(sess *tdsSession) {
// SQL Collation data should contain 5 bytes in length
if collationSize != 5 {
- badStreamPanicf("Invalid SQL Collation size value returned from server: %s", collationSize)
+ badStreamPanicf("Invalid SQL Collation size value returned from server: %d", collationSize)
}
// 4 bytes, contains: LCID ColFlags Version
@@ -385,11 +385,9 @@ func processEnvChg(sess *tdsSession) {
}
}
-type returnStatus int32
-
// http://msdn.microsoft.com/en-us/library/dd358180.aspx
-func parseReturnStatus(r *tdsBuffer) returnStatus {
- return returnStatus(r.int32())
+func parseReturnStatus(r *tdsBuffer) ReturnStatus {
+ return ReturnStatus(r.int32())
}
func parseOrder(r *tdsBuffer) (res orderStruct) {
@@ -640,7 +638,7 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
if len(nv.Name) > 0 {
name := nv.Name[1:] // Remove the leading "@".
if ov, has := outs[name]; has {
- err = scanIntoOut(nv.Value, ov)
+ err = scanIntoOut(name, nv.Value, ov)
if err != nil {
fmt.Println("scan error", err)
ch <- err
@@ -653,28 +651,6 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
}
}
-func scanIntoOut(fromServer, scanInto interface{}) error {
- switch fs := fromServer.(type) {
- case int64:
- switch si := scanInto.(type) {
- case *int64:
- *si = fs
- default:
- return fmt.Errorf("unsupported scan into type %[1]T for server type %[2]T", scanInto, fromServer)
- }
- return nil
- case string:
- switch si := scanInto.(type) {
- case *string:
- *si = fs
- default:
- return fmt.Errorf("unsupported scan into type %[1]T for server type %[2]T", scanInto, fromServer)
- }
- return nil
- }
- return fmt.Errorf("unsupported type from server %[1]T=%[1]v", fromServer)
-}
-
type parseRespIter byte
const (
diff --git a/vendor/github.com/denisenkom/go-mssqldb/tran.go b/vendor/github.com/denisenkom/go-mssqldb/tran.go
index 75e7a2ae65..cb6436816f 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/tran.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/tran.go
@@ -28,9 +28,8 @@ const (
isolationSnapshot = 5
)
-func sendBeginXact(buf *tdsBuffer, headers []headerStruct, isolation isoLevel,
- name string) (err error) {
- buf.BeginPacket(packTransMgrReq)
+func sendBeginXact(buf *tdsBuffer, headers []headerStruct, isolation isoLevel, name string, resetSession bool) (err error) {
+ buf.BeginPacket(packTransMgrReq, resetSession)
writeAllHeaders(buf, headers)
var rqtype uint16 = tmBeginXact
err = binary.Write(buf, binary.LittleEndian, &rqtype)
@@ -52,8 +51,8 @@ const (
fBeginXact = 1
)
-func sendCommitXact(buf *tdsBuffer, headers []headerStruct, name string, flags uint8, isolation uint8, newname string) error {
- buf.BeginPacket(packTransMgrReq)
+func sendCommitXact(buf *tdsBuffer, headers []headerStruct, name string, flags uint8, isolation uint8, newname string, resetSession bool) error {
+ buf.BeginPacket(packTransMgrReq, resetSession)
writeAllHeaders(buf, headers)
var rqtype uint16 = tmCommitXact
err := binary.Write(buf, binary.LittleEndian, &rqtype)
@@ -81,8 +80,8 @@ func sendCommitXact(buf *tdsBuffer, headers []headerStruct, name string, flags u
return buf.FinishPacket()
}
-func sendRollbackXact(buf *tdsBuffer, headers []headerStruct, name string, flags uint8, isolation uint8, newname string) error {
- buf.BeginPacket(packTransMgrReq)
+func sendRollbackXact(buf *tdsBuffer, headers []headerStruct, name string, flags uint8, isolation uint8, newname string, resetSession bool) error {
+ buf.BeginPacket(packTransMgrReq, resetSession)
writeAllHeaders(buf, headers)
var rqtype uint16 = tmRollbackXact
err := binary.Write(buf, binary.LittleEndian, &rqtype)
diff --git a/vendor/github.com/denisenkom/go-mssqldb/tvp_go19.go b/vendor/github.com/denisenkom/go-mssqldb/tvp_go19.go
new file mode 100644
index 0000000000..64e5e21fbd
--- /dev/null
+++ b/vendor/github.com/denisenkom/go-mssqldb/tvp_go19.go
@@ -0,0 +1,231 @@
+// +build go1.9
+
+package mssql
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+ "time"
+)
+
+const (
+ jsonTag = "json"
+ tvpTag = "tvp"
+ skipTagValue = "-"
+ sqlSeparator = "."
+)
+
+var (
+ ErrorEmptyTVPTypeName = errors.New("TypeName must not be empty")
+ ErrorTypeSlice = errors.New("TVP must be slice type")
+ ErrorTypeSliceIsEmpty = errors.New("TVP mustn't be null value")
+ ErrorSkip = errors.New("all fields mustn't skip")
+ ErrorObjectName = errors.New("wrong tvp name")
+ ErrorWrongTyping = errors.New("the number of elements in columnStr and tvpFieldIndexes do not align")
+)
+
+//TVP is driver type, which allows supporting Table Valued Parameters (TVP) in SQL Server
+type TVP struct {
+ //TypeName mustn't be default value
+ TypeName string
+ //Value must be the slice, mustn't be nil
+ Value interface{}
+}
+
+func (tvp TVP) check() error {
+ if len(tvp.TypeName) == 0 {
+ return ErrorEmptyTVPTypeName
+ }
+ if !isProc(tvp.TypeName) {
+ return ErrorEmptyTVPTypeName
+ }
+ if sepCount := getCountSQLSeparators(tvp.TypeName); sepCount > 1 {
+ return ErrorObjectName
+ }
+ valueOf := reflect.ValueOf(tvp.Value)
+ if valueOf.Kind() != reflect.Slice {
+ return ErrorTypeSlice
+ }
+ if valueOf.IsNil() {
+ return ErrorTypeSliceIsEmpty
+ }
+ if reflect.TypeOf(tvp.Value).Elem().Kind() != reflect.Struct {
+ return ErrorTypeSlice
+ }
+ return nil
+}
+
+func (tvp TVP) encode(schema, name string, columnStr []columnStruct, tvpFieldIndexes []int) ([]byte, error) {
+ if len(columnStr) != len(tvpFieldIndexes) {
+ return nil, ErrorWrongTyping
+ }
+ preparedBuffer := make([]byte, 0, 20+(10*len(columnStr)))
+ buf := bytes.NewBuffer(preparedBuffer)
+ err := writeBVarChar(buf, "")
+ if err != nil {
+ return nil, err
+ }
+
+ writeBVarChar(buf, schema)
+ writeBVarChar(buf, name)
+ binary.Write(buf, binary.LittleEndian, uint16(len(columnStr)))
+
+ for i, column := range columnStr {
+ binary.Write(buf, binary.LittleEndian, uint32(column.UserType))
+ binary.Write(buf, binary.LittleEndian, uint16(column.Flags))
+ writeTypeInfo(buf, &columnStr[i].ti)
+ writeBVarChar(buf, "")
+ }
+ // The returned error is always nil
+ buf.WriteByte(_TVP_END_TOKEN)
+
+ conn := new(Conn)
+ conn.sess = new(tdsSession)
+ conn.sess.loginAck = loginAckStruct{TDSVersion: verTDS73}
+ stmt := &Stmt{
+ c: conn,
+ }
+
+ val := reflect.ValueOf(tvp.Value)
+ for i := 0; i < val.Len(); i++ {
+ refStr := reflect.ValueOf(val.Index(i).Interface())
+ buf.WriteByte(_TVP_ROW_TOKEN)
+ for columnStrIdx, fieldIdx := range tvpFieldIndexes {
+ field := refStr.Field(fieldIdx)
+ tvpVal := field.Interface()
+ valOf := reflect.ValueOf(tvpVal)
+ elemKind := field.Kind()
+ if elemKind == reflect.Ptr && valOf.IsNil() {
+ switch tvpVal.(type) {
+ case *bool, *time.Time, *int8, *int16, *int32, *int64, *float32, *float64, *int:
+ binary.Write(buf, binary.LittleEndian, uint8(0))
+ continue
+ default:
+ binary.Write(buf, binary.LittleEndian, uint64(_PLP_NULL))
+ continue
+ }
+ }
+ if elemKind == reflect.Slice && valOf.IsNil() {
+ binary.Write(buf, binary.LittleEndian, uint64(_PLP_NULL))
+ continue
+ }
+
+ cval, err := convertInputParameter(tvpVal)
+ if err != nil {
+ return nil, fmt.Errorf("failed to convert tvp parameter row col: %s", err)
+ }
+ param, err := stmt.makeParam(cval)
+ if err != nil {
+ return nil, fmt.Errorf("failed to make tvp parameter row col: %s", err)
+ }
+ columnStr[columnStrIdx].ti.Writer(buf, param.ti, param.buffer)
+ }
+ }
+ buf.WriteByte(_TVP_END_TOKEN)
+ return buf.Bytes(), nil
+}
+
+func (tvp TVP) columnTypes() ([]columnStruct, []int, error) {
+ val := reflect.ValueOf(tvp.Value)
+ var firstRow interface{}
+ if val.Len() != 0 {
+ firstRow = val.Index(0).Interface()
+ } else {
+ firstRow = reflect.New(reflect.TypeOf(tvp.Value).Elem()).Elem().Interface()
+ }
+
+ tvpRow := reflect.TypeOf(firstRow)
+ columnCount := tvpRow.NumField()
+ defaultValues := make([]interface{}, 0, columnCount)
+ tvpFieldIndexes := make([]int, 0, columnCount)
+ for i := 0; i < columnCount; i++ {
+ field := tvpRow.Field(i)
+ tvpTagValue, isTvpTag := field.Tag.Lookup(tvpTag)
+ jsonTagValue, isJsonTag := field.Tag.Lookup(jsonTag)
+ if IsSkipField(tvpTagValue, isTvpTag, jsonTagValue, isJsonTag) {
+ continue
+ }
+ tvpFieldIndexes = append(tvpFieldIndexes, i)
+ if field.Type.Kind() == reflect.Ptr {
+ v := reflect.New(field.Type.Elem())
+ defaultValues = append(defaultValues, v.Interface())
+ continue
+ }
+ defaultValues = append(defaultValues, reflect.Zero(field.Type).Interface())
+ }
+
+ if columnCount-len(tvpFieldIndexes) == columnCount {
+ return nil, nil, ErrorSkip
+ }
+
+ conn := new(Conn)
+ conn.sess = new(tdsSession)
+ conn.sess.loginAck = loginAckStruct{TDSVersion: verTDS73}
+ stmt := &Stmt{
+ c: conn,
+ }
+
+ columnConfiguration := make([]columnStruct, 0, columnCount)
+ for index, val := range defaultValues {
+ cval, err := convertInputParameter(val)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to convert tvp parameter row %d col %d: %s", index, val, err)
+ }
+ param, err := stmt.makeParam(cval)
+ if err != nil {
+ return nil, nil, err
+ }
+ column := columnStruct{
+ ti: param.ti,
+ }
+ switch param.ti.TypeId {
+ case typeNVarChar, typeBigVarBin:
+ column.ti.Size = 0
+ }
+ columnConfiguration = append(columnConfiguration, column)
+ }
+
+ return columnConfiguration, tvpFieldIndexes, nil
+}
+
+func IsSkipField(tvpTagValue string, isTvpValue bool, jsonTagValue string, isJsonTagValue bool) bool {
+ if !isTvpValue && !isJsonTagValue {
+ return false
+ } else if isTvpValue && tvpTagValue != skipTagValue {
+ return false
+ } else if !isTvpValue && isJsonTagValue && jsonTagValue != skipTagValue {
+ return false
+ }
+ return true
+}
+
+func getSchemeAndName(tvpName string) (string, string, error) {
+ if len(tvpName) == 0 {
+ return "", "", ErrorEmptyTVPTypeName
+ }
+ splitVal := strings.Split(tvpName, ".")
+ if len(splitVal) > 2 {
+ return "", "", errors.New("wrong tvp name")
+ }
+ if len(splitVal) == 2 {
+ res := make([]string, 2)
+ for key, value := range splitVal {
+ tmp := strings.Replace(value, "[", "", -1)
+ tmp = strings.Replace(tmp, "]", "", -1)
+ res[key] = tmp
+ }
+ return res[0], res[1], nil
+ }
+ tmp := strings.Replace(splitVal[0], "[", "", -1)
+ tmp = strings.Replace(tmp, "]", "", -1)
+
+ return "", tmp, nil
+}
+
+func getCountSQLSeparators(str string) int {
+ return strings.Count(str, sqlSeparator)
+}
diff --git a/vendor/github.com/denisenkom/go-mssqldb/types.go b/vendor/github.com/denisenkom/go-mssqldb/types.go
index 9ae5c5f761..c9f17b9e71 100644
--- a/vendor/github.com/denisenkom/go-mssqldb/types.go
+++ b/vendor/github.com/denisenkom/go-mssqldb/types.go
@@ -62,6 +62,7 @@ const (
typeNChar = 0xef
typeXml = 0xf1
typeUdt = 0xf0
+ typeTvp = 0xf3
// long length types
typeText = 0x23
@@ -69,9 +70,13 @@ const (
typeNText = 0x63
typeVariant = 0x62
)
-const PLP_NULL = 0xFFFFFFFFFFFFFFFF
-const UNKNOWN_PLP_LEN = 0xFFFFFFFFFFFFFFFE
-const PLP_TERMINATOR = 0x00000000
+const _PLP_NULL = 0xFFFFFFFFFFFFFFFF
+const _UNKNOWN_PLP_LEN = 0xFFFFFFFFFFFFFFFE
+const _PLP_TERMINATOR = 0x00000000
+
+// TVP COLUMN FLAGS
+const _TVP_END_TOKEN = 0x00
+const _TVP_ROW_TOKEN = 0x01
// TYPE_INFO rule
// http://msdn.microsoft.com/en-us/library/dd358284.aspx
@@ -133,6 +138,7 @@ func readTypeInfo(r *tdsBuffer) (res typeInfo) {
return
}
+// https://msdn.microsoft.com/en-us/library/dd358284.aspx
func writeTypeInfo(w io.Writer, ti *typeInfo) (err error) {
err = binary.Write(w, binary.LittleEndian, ti.TypeId)
if err != nil {
@@ -142,6 +148,9 @@ func writeTypeInfo(w io.Writer, ti *typeInfo) (err error) {
case typeNull, typeInt1, typeBit, typeInt2, typeInt4, typeDateTim4,
typeFlt4, typeMoney, typeDateTime, typeFlt8, typeMoney4, typeInt8:
// those are fixed length
+ // https://msdn.microsoft.com/en-us/library/dd341171.aspx
+ ti.Writer = writeFixedType
+ case typeTvp:
ti.Writer = writeFixedType
default: // all others are VARLENTYPE
err = writeVarLen(w, ti)
@@ -157,8 +166,10 @@ func writeFixedType(w io.Writer, ti typeInfo, buf []byte) (err error) {
return
}
+// https://msdn.microsoft.com/en-us/library/dd358341.aspx
func writeVarLen(w io.Writer, ti *typeInfo) (err error) {
switch ti.TypeId {
+
case typeDateN:
ti.Writer = writeByteLenType
case typeTimeN, typeDateTime2N, typeDateTimeOffsetN:
@@ -200,6 +211,7 @@ func writeVarLen(w io.Writer, ti *typeInfo) (err error) {
ti.Writer = writeByteLenType
case typeBigVarBin, typeBigVarChar, typeBigBinary, typeBigChar,
typeNVarChar, typeNChar, typeXml, typeUdt:
+
// short len types
if ti.Size > 8000 || ti.Size == 0 {
if err = binary.Write(w, binary.LittleEndian, uint16(0xffff)); err != nil {
@@ -245,6 +257,48 @@ func decodeDateTim4(buf []byte) time.Time {
0, int(mins), 0, 0, time.UTC)
}
+func encodeDateTim4(val time.Time) (buf []byte) {
+ buf = make([]byte, 4)
+
+ ref := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC)
+ dur := val.Sub(ref)
+ days := dur / (24 * time.Hour)
+ mins := val.Hour()*60 + val.Minute()
+ if days < 0 {
+ days = 0
+ mins = 0
+ }
+
+ binary.LittleEndian.PutUint16(buf[:2], uint16(days))
+ binary.LittleEndian.PutUint16(buf[2:], uint16(mins))
+ return
+}
+
+// encodes datetime value
+// type identifier is typeDateTimeN
+func encodeDateTime(t time.Time) (res []byte) {
+ // base date in days since Jan 1st 1900
+ basedays := gregorianDays(1900, 1)
+ // days since Jan 1st 1900 (same TZ as t)
+ days := gregorianDays(t.Year(), t.YearDay()) - basedays
+ tm := 300*(t.Second()+t.Minute()*60+t.Hour()*60*60) + t.Nanosecond()*300/1e9
+ // minimum and maximum possible
+ mindays := gregorianDays(1753, 1) - basedays
+ maxdays := gregorianDays(9999, 365) - basedays
+ if days < mindays {
+ days = mindays
+ tm = 0
+ }
+ if days > maxdays {
+ days = maxdays
+ tm = (23*60*60+59*60+59)*300 + 299
+ }
+ res = make([]byte, 8)
+ binary.LittleEndian.PutUint32(res[0:4], uint32(days))
+ binary.LittleEndian.PutUint32(res[4:8], uint32(tm))
+ return
+}
+
func decodeDateTime(buf []byte) time.Time {
days := int32(binary.LittleEndian.Uint32(buf))
tm := binary.LittleEndian.Uint32(buf[4:])
@@ -320,7 +374,7 @@ func readByteLenType(ti *typeInfo, r *tdsBuffer) interface{} {
case 8:
return int64(binary.LittleEndian.Uint64(buf))
default:
- badStreamPanicf("Invalid size for INTNTYPE")
+ badStreamPanicf("Invalid size for INTNTYPE: %d", len(buf))
}
case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
return decodeDecimal(ti.Prec, ti.Scale, buf)
@@ -379,7 +433,7 @@ func writeByteLenType(w io.Writer, ti typeInfo, buf []byte) (err error) {
if ti.Size > 0xff {
panic("Invalid size for BYTELEN_TYPE")
}
- err = binary.Write(w, binary.LittleEndian, uint8(ti.Size))
+ err = binary.Write(w, binary.LittleEndian, uint8(len(buf)))
if err != nil {
return
}
@@ -601,10 +655,10 @@ func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
size := r.uint64()
var buf *bytes.Buffer
switch size {
- case PLP_NULL:
+ case _PLP_NULL:
// null
return nil
- case UNKNOWN_PLP_LEN:
+ case _UNKNOWN_PLP_LEN:
// size unknown
buf = bytes.NewBuffer(make([]byte, 0, 1000))
default:
@@ -635,13 +689,13 @@ func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
}
func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) {
- if err = binary.Write(w, binary.LittleEndian, uint64(UNKNOWN_PLP_LEN)); err != nil {
+ if err = binary.Write(w, binary.LittleEndian, uint64(_UNKNOWN_PLP_LEN)); err != nil {
return
}
for {
chunksize := uint32(len(buf))
if chunksize == 0 {
- err = binary.Write(w, binary.LittleEndian, uint32(PLP_TERMINATOR))
+ err = binary.Write(w, binary.LittleEndian, uint32(_PLP_TERMINATOR))
return
}
if err = binary.Write(w, binary.LittleEndian, chunksize); err != nil {
@@ -805,6 +859,15 @@ func decodeDate(buf []byte) time.Time {
return time.Date(1, 1, 1+decodeDateInt(buf), 0, 0, 0, 0, time.UTC)
}
+func encodeDate(val time.Time) (buf []byte) {
+ days, _, _ := dateTime2(val)
+ buf = make([]byte, 3)
+ buf[0] = byte(days)
+ buf[1] = byte(days >> 8)
+ buf[2] = byte(days >> 16)
+ return
+}
+
func decodeTimeInt(scale uint8, buf []byte) (sec int, ns int) {
var acc uint64 = 0
for i := len(buf) - 1; i >= 0; i-- {
@@ -820,11 +883,41 @@ func decodeTimeInt(scale uint8, buf []byte) (sec int, ns int) {
return
}
+// calculate size of time field in bytes
+func calcTimeSize(scale int) int {
+ if scale <= 2 {
+ return 3
+ } else if scale <= 4 {
+ return 4
+ } else {
+ return 5
+ }
+}
+
+// writes time value into a field buffer
+// buffer should be at least calcTimeSize long
+func encodeTimeInt(seconds, ns, scale int, buf []byte) {
+ ns_total := int64(seconds)*1000*1000*1000 + int64(ns)
+ t := ns_total / int64(math.Pow10(int(scale)*-1)*1e9)
+ buf[0] = byte(t)
+ buf[1] = byte(t >> 8)
+ buf[2] = byte(t >> 16)
+ buf[3] = byte(t >> 24)
+ buf[4] = byte(t >> 32)
+}
+
func decodeTime(scale uint8, buf []byte) time.Time {
sec, ns := decodeTimeInt(scale, buf)
return time.Date(1, 1, 1, 0, 0, sec, ns, time.UTC)
}
+func encodeTime(hour, minute, second, ns, scale int) (buf []byte) {
+ seconds := hour*3600 + minute*60 + second
+ buf = make([]byte, calcTimeSize(scale))
+ encodeTimeInt(seconds, ns, scale, buf)
+ return
+}
+
func decodeDateTime2(scale uint8, buf []byte) time.Time {
timesize := len(buf) - 3
sec, ns := decodeTimeInt(scale, buf[:timesize])
@@ -832,6 +925,17 @@ func decodeDateTime2(scale uint8, buf []byte) time.Time {
return time.Date(1, 1, 1+days, 0, 0, sec, ns, time.UTC)
}
+func encodeDateTime2(val time.Time, scale int) (buf []byte) {
+ days, seconds, ns := dateTime2(val)
+ timesize := calcTimeSize(scale)
+ buf = make([]byte, 3+timesize)
+ encodeTimeInt(seconds, ns, scale, buf)
+ buf[timesize] = byte(days)
+ buf[timesize+1] = byte(days >> 8)
+ buf[timesize+2] = byte(days >> 16)
+ return
+}
+
func decodeDateTimeOffset(scale uint8, buf []byte) time.Time {
timesize := len(buf) - 3 - 2
sec, ns := decodeTimeInt(scale, buf[:timesize])
@@ -843,24 +947,43 @@ func decodeDateTimeOffset(scale uint8, buf []byte) time.Time {
time.FixedZone("", offset*60))
}
-func divFloor(x int64, y int64) int64 {
- q := x / y
- r := x % y
- if r != 0 && ((r < 0) != (y < 0)) {
- q--
- }
- return q
+func encodeDateTimeOffset(val time.Time, scale int) (buf []byte) {
+ timesize := calcTimeSize(scale)
+ buf = make([]byte, timesize+2+3)
+ days, seconds, ns := dateTime2(val.In(time.UTC))
+ encodeTimeInt(seconds, ns, scale, buf)
+ buf[timesize] = byte(days)
+ buf[timesize+1] = byte(days >> 8)
+ buf[timesize+2] = byte(days >> 16)
+ _, offset := val.Zone()
+ offset /= 60
+ buf[timesize+3] = byte(offset)
+ buf[timesize+4] = byte(offset >> 8)
+ return
}
-func dateTime2(t time.Time) (days int32, ns int64) {
- // number of days since Jan 1 1970 UTC
- days64 := divFloor(t.Unix(), 24*60*60)
- // number of days since Jan 1 1 UTC
- days = int32(days64) + 1969*365 + 1969/4 - 1969/100 + 1969/400
- // number of seconds within day
- secs := t.Unix() - days64*24*60*60
- // number of nanoseconds within day
- ns = secs*1e9 + int64(t.Nanosecond())
+// returns days since Jan 1st 0001 in Gregorian calendar
+func gregorianDays(year, yearday int) int {
+ year0 := year - 1
+ return year0*365 + year0/4 - year0/100 + year0/400 + yearday - 1
+}
+
+func dateTime2(t time.Time) (days int, seconds int, ns int) {
+ // days since Jan 1 1 (in same TZ as t)
+ days = gregorianDays(t.Year(), t.YearDay())
+ seconds = t.Second() + t.Minute()*60 + t.Hour()*60*60
+ ns = t.Nanosecond()
+ if days < 0 {
+ days = 0
+ seconds = 0
+ ns = 0
+ }
+ max := gregorianDays(9999, 365)
+ if days > max {
+ days = max
+ seconds = 59 + 59*60 + 23*60*60
+ ns = 999999900
+ }
return
}
@@ -989,7 +1112,7 @@ func makeGoLangScanType(ti typeInfo) reflect.Type {
case typeVariant:
return reflect.TypeOf(nil)
default:
- panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
+ panic(fmt.Sprintf("not implemented makeGoLangScanType for type %d", ti.TypeId))
}
}
@@ -1001,6 +1124,8 @@ func makeDecl(ti typeInfo) string {
return "nvarchar(1)"
case typeInt1:
return "tinyint"
+ case typeBigBinary:
+ return fmt.Sprintf("binary(%d)", ti.Size)
case typeInt2:
return "smallint"
case typeInt4:
@@ -1089,6 +1214,8 @@ func makeDecl(ti typeInfo) string {
default:
panic("invalid size of DATETIMNTYPE")
}
+ case typeTimeN:
+ return "time"
case typeDateTime2N:
return fmt.Sprintf("datetime2(%d)", ti.Scale)
case typeDateTimeOffsetN:
@@ -1101,6 +1228,11 @@ func makeDecl(ti typeInfo) string {
return ti.UdtInfo.TypeName
case typeGuid:
return "uniqueidentifier"
+ case typeTvp:
+ if ti.UdtInfo.SchemaName != "" {
+ return fmt.Sprintf("%s.%s READONLY", ti.UdtInfo.SchemaName, ti.UdtInfo.TypeName)
+ }
+ return fmt.Sprintf("%s READONLY", ti.UdtInfo.TypeName)
default:
panic(fmt.Sprintf("not implemented makeDecl for type %#x", ti.TypeId))
}
@@ -1209,7 +1341,7 @@ func makeGoLangTypeName(ti typeInfo) string {
case typeBigBinary:
return "BINARY"
default:
- panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
+ panic(fmt.Sprintf("not implemented makeGoLangTypeName for type %d", ti.TypeId))
}
}
@@ -1332,7 +1464,7 @@ func makeGoLangTypeLength(ti typeInfo) (int64, bool) {
case typeBigBinary:
return 0, false
default:
- panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
+ panic(fmt.Sprintf("not implemented makeGoLangTypeLength for type %d", ti.TypeId))
}
}
@@ -1443,6 +1575,6 @@ func makeGoLangTypePrecisionScale(ti typeInfo) (int64, int64, bool) {
case typeBigBinary:
return 0, 0, false
default:
- panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
+ panic(fmt.Sprintf("not implemented makeGoLangTypePrecisionScale for type %d", ti.TypeId))
}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 77d7305b24..66572549f2 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,3 +1,5 @@
+# cloud.google.com/go v0.37.4
+cloud.google.com/go/civil
# github.com/BurntSushi/toml v0.3.1
github.com/BurntSushi/toml
# github.com/PuerkitoBio/goquery v0.0.0-20170324135448-ed7d758e9a34
@@ -87,9 +89,10 @@ github.com/couchbase/vellum/utf8
github.com/couchbaselabs/go-couchbase
# github.com/davecgh/go-spew v1.1.1
github.com/davecgh/go-spew/spew
-# github.com/denisenkom/go-mssqldb v0.0.0-20190724012636-11b2859924c1 => github.com/denisenkom/go-mssqldb v0.0.0-20180315180555-6a30f4e59a44
+# github.com/denisenkom/go-mssqldb v0.0.0-20190724012636-11b2859924c1
github.com/denisenkom/go-mssqldb
github.com/denisenkom/go-mssqldb/internal/cp
+github.com/denisenkom/go-mssqldb/internal/querytext
# github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dgrijalva/jwt-go
# github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712