summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/denisenkom/go-mssqldb/parser.go
diff options
context:
space:
mode:
authorbtrepp <beautrepp@gmail.com>2016-12-24 09:37:35 +0800
committerLunny Xiao <xiaolunwen@gmail.com>2016-12-24 09:37:35 +0800
commit25b5ffb6af390eac8d4a76c134379fd1ae88a423 (patch)
treee085f3f3af71ad81559ba8efeba05caceaa69fd2 /vendor/github.com/denisenkom/go-mssqldb/parser.go
parentf2ff0ee846e8ef42e2f7ba960e86bd8e397f007f (diff)
downloadgitea-25b5ffb6af390eac8d4a76c134379fd1ae88a423.tar.gz
gitea-25b5ffb6af390eac8d4a76c134379fd1ae88a423.zip
Enables mssql support (#383)
* Enables mssql support Port of dlobs work in gogs. Enables options in index.js Enables MSSQL as a database option in go. Sets ID to 0 on initial migration. Required for MSSQL insert statements. Signed-off-by: Beau Trepp <beautrepp@gmail.com> * Vendors in denisenkom/go-mssqldb Includes golang.org/x/crypto/md4 as this is required by go-msssqldb Signed-off-by: Beau Trepp <beautrepp@gmail.com>
Diffstat (limited to 'vendor/github.com/denisenkom/go-mssqldb/parser.go')
-rw-r--r--vendor/github.com/denisenkom/go-mssqldb/parser.go227
1 files changed, 227 insertions, 0 deletions
diff --git a/vendor/github.com/denisenkom/go-mssqldb/parser.go b/vendor/github.com/denisenkom/go-mssqldb/parser.go
new file mode 100644
index 0000000000..9e37c16a65
--- /dev/null
+++ b/vendor/github.com/denisenkom/go-mssqldb/parser.go
@@ -0,0 +1,227 @@
+package mssql
+
+import (
+ "bytes"
+ "io"
+ "strconv"
+)
+
+type parser struct {
+ r *bytes.Reader
+ w bytes.Buffer
+ paramCount int
+ paramMax int
+}
+
+func (p *parser) next() (rune, bool) {
+ ch, _, err := p.r.ReadRune()
+ if err != nil {
+ if err != io.EOF {
+ panic(err)
+ }
+ return 0, false
+ }
+ return ch, true
+}
+
+func (p *parser) unread() {
+ err := p.r.UnreadRune()
+ if err != nil {
+ panic(err)
+ }
+}
+
+func (p *parser) write(ch rune) {
+ p.w.WriteRune(ch)
+}
+
+type stateFunc func(*parser) stateFunc
+
+func parseParams(query string) (string, int) {
+ p := &parser{
+ r: bytes.NewReader([]byte(query)),
+ }
+ state := parseNormal
+ for state != nil {
+ state = state(p)
+ }
+ return p.w.String(), p.paramMax
+}
+
+func parseNormal(p *parser) stateFunc {
+ for {
+ ch, ok := p.next()
+ if !ok {
+ return nil
+ }
+ if ch == '?' {
+ return parseParameter
+ } else if ch == '$' || ch == ':' {
+ ch2, ok := p.next()
+ if !ok {
+ p.write(ch)
+ return nil
+ }
+ p.unread()
+ if ch2 >= '0' && ch2 <= '9' {
+ return parseParameter
+ }
+ }
+ p.write(ch)
+ switch ch {
+ case '\'':
+ return parseQuote
+ case '"':
+ return parseDoubleQuote
+ case '[':
+ return parseBracket
+ case '-':
+ return parseLineComment
+ case '/':
+ return parseComment
+ }
+ }
+}
+
+func parseParameter(p *parser) stateFunc {
+ var paramN int
+ var ok bool
+ for {
+ var ch rune
+ ch, ok = p.next()
+ if ok && ch >= '0' && ch <= '9' {
+ paramN = paramN*10 + int(ch-'0')
+ } else {
+ break
+ }
+ }
+ if ok {
+ p.unread()
+ }
+ if paramN == 0 {
+ p.paramCount++
+ paramN = p.paramCount
+ }
+ if paramN > p.paramMax {
+ p.paramMax = paramN
+ }
+ p.w.WriteString("@p")
+ p.w.WriteString(strconv.Itoa(paramN))
+ if !ok {
+ return nil
+ }
+ return parseNormal
+}
+
+func parseQuote(p *parser) stateFunc {
+ for {
+ ch, ok := p.next()
+ if !ok {
+ return nil
+ }
+ p.write(ch)
+ if ch == '\'' {
+ return parseNormal
+ }
+ }
+}
+
+func parseDoubleQuote(p *parser) stateFunc {
+ for {
+ ch, ok := p.next()
+ if !ok {
+ return nil
+ }
+ p.write(ch)
+ if ch == '"' {
+ return parseNormal
+ }
+ }
+}
+
+func parseBracket(p *parser) stateFunc {
+ for {
+ ch, ok := p.next()
+ if !ok {
+ return nil
+ }
+ p.write(ch)
+ if ch == ']' {
+ ch, ok = p.next()
+ if !ok {
+ return nil
+ }
+ if ch != ']' {
+ p.unread()
+ return parseNormal
+ }
+ p.write(ch)
+ }
+ }
+}
+
+func parseLineComment(p *parser) stateFunc {
+ ch, ok := p.next()
+ if !ok {
+ return nil
+ }
+ if ch != '-' {
+ p.unread()
+ return parseNormal
+ }
+ p.write(ch)
+ for {
+ ch, ok = p.next()
+ if !ok {
+ return nil
+ }
+ p.write(ch)
+ if ch == '\n' {
+ return parseNormal
+ }
+ }
+}
+
+func parseComment(p *parser) stateFunc {
+ var nested int
+ ch, ok := p.next()
+ if !ok {
+ return nil
+ }
+ if ch != '*' {
+ p.unread()
+ return parseNormal
+ }
+ p.write(ch)
+ for {
+ ch, ok = p.next()
+ if !ok {
+ return nil
+ }
+ p.write(ch)
+ for ch == '*' {
+ ch, ok = p.next()
+ if !ok {
+ return nil
+ }
+ p.write(ch)
+ if ch == '/' {
+ if nested == 0 {
+ return parseNormal
+ } else {
+ nested--
+ }
+ }
+ }
+ for ch == '/' {
+ ch, ok = p.next()
+ if !ok {
+ return nil
+ }
+ p.write(ch)
+ if ch == '*' {
+ nested++
+ }
+ }
+ }
+}