This repository has been archived by the owner on Jun 14, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
column_type.go
106 lines (99 loc) · 2.08 KB
/
column_type.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package mysql
import (
"strings"
"unicode"
"github.com/bbuck/go-lexer"
"github.com/fairyhunter13/xorm/lexer/general"
)
// List of all tokens used in this column type package.
const (
UsualToken lexer.TokenType = iota
WhitespaceToken
)
var (
isIgnored = func(ch rune) bool {
return unicode.IsSpace(ch) || unicode.IsControl(ch) || !general.IsAlphabetic(ch)
}
getType lexer.StateFunc
insideBrackets lexer.StateFunc
ignoredCharacter lexer.StateFunc
skipBrackets general.LexerFunc
)
func init() {
getType = func(l *lexer.L) (fn lexer.StateFunc) {
ch := l.Peek()
for ch != lexer.EOFRune {
if general.IsBrackets(ch) {
l.Emit(UsualToken)
fn = insideBrackets
return
}
if isIgnored(ch) {
l.Emit(UsualToken)
fn = ignoredCharacter
return
}
l.Next()
ch = l.Peek()
}
l.Emit(UsualToken)
return
}
ignoredCharacter = func(l *lexer.L) (fn lexer.StateFunc) {
ch := l.Peek()
if isIgnored(ch) {
general.IgnoreNextToken(l)
fn = ignoredCharacter
return
}
l.Emit(WhitespaceToken)
fn = getType
return
}
insideBrackets = func(l *lexer.L) (fn lexer.StateFunc) {
ch := l.Peek()
if general.IsBrackets(ch) {
skipBrackets(l)
fn = insideBrackets
return
}
fn = getType
return
}
skipBrackets = func(l *lexer.L) {
openBracket := l.Peek()
general.IgnoreNextToken(l)
closeBracket := general.GetClosingBracket(openBracket)
ch := l.Peek()
for ch != closeBracket && ch != lexer.EOFRune {
general.IgnoreNextToken(l)
ch = l.Peek()
}
general.IgnoreNextToken(l)
}
}
// GetType gets the mysqll type from column_type in the information schema.
func GetType(typeStr string) (res string) {
builder := general.GetBuilder()
defer general.PutBuilder(builder)
lex := lexer.New(typeStr, getType)
lex.Start()
LOOP:
for {
token, ok := lex.NextToken()
if ok {
break LOOP
}
switch token.Type {
case UsualToken:
builder.WriteString(token.Value)
if strings.EqualFold(token.Value, "unsigned") {
break LOOP
}
case WhitespaceToken:
builder.WriteString(" ")
}
}
res = builder.String()
return
}