mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 14:09:13 +00:00
118 lines
2.7 KiB
Go
118 lines
2.7 KiB
Go
package gormlite
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
type parseAllColumnsState int
|
|
|
|
const (
|
|
parseAllColumnsState_NONE parseAllColumnsState = iota
|
|
parseAllColumnsState_Beginning
|
|
parseAllColumnsState_ReadingRawName
|
|
parseAllColumnsState_ReadingQuotedName
|
|
parseAllColumnsState_EndOfName
|
|
parseAllColumnsState_State_End
|
|
)
|
|
|
|
func parseAllColumns(in string) ([]string, error) {
|
|
s := []rune(in)
|
|
columns := make([]string, 0)
|
|
state := parseAllColumnsState_NONE
|
|
quote := rune(0)
|
|
name := make([]rune, 0)
|
|
for i := 0; i < len(s); i++ {
|
|
switch state {
|
|
case parseAllColumnsState_NONE:
|
|
if s[i] == '(' {
|
|
state = parseAllColumnsState_Beginning
|
|
}
|
|
case parseAllColumnsState_Beginning:
|
|
if isSpace(s[i]) {
|
|
continue
|
|
}
|
|
if isQuote(s[i]) {
|
|
state = parseAllColumnsState_ReadingQuotedName
|
|
quote = s[i]
|
|
continue
|
|
}
|
|
if s[i] == '[' {
|
|
state = parseAllColumnsState_ReadingQuotedName
|
|
quote = ']'
|
|
continue
|
|
} else if s[i] == ')' {
|
|
return columns, fmt.Errorf("unexpected token: %s", string(s[i]))
|
|
}
|
|
state = parseAllColumnsState_ReadingRawName
|
|
name = append(name, s[i])
|
|
case parseAllColumnsState_ReadingRawName:
|
|
if isSeparator(s[i]) {
|
|
state = parseAllColumnsState_Beginning
|
|
columns = append(columns, string(name))
|
|
name = make([]rune, 0)
|
|
continue
|
|
}
|
|
if s[i] == ')' {
|
|
state = parseAllColumnsState_State_End
|
|
columns = append(columns, string(name))
|
|
}
|
|
if isQuote(s[i]) {
|
|
return nil, fmt.Errorf("unexpected token: %s", string(s[i]))
|
|
}
|
|
if isSpace(s[i]) {
|
|
state = parseAllColumnsState_EndOfName
|
|
columns = append(columns, string(name))
|
|
name = make([]rune, 0)
|
|
continue
|
|
}
|
|
name = append(name, s[i])
|
|
case parseAllColumnsState_ReadingQuotedName:
|
|
if s[i] == quote {
|
|
// check if quote character is escaped
|
|
if i+1 < len(s) && s[i+1] == quote {
|
|
name = append(name, quote)
|
|
i++
|
|
continue
|
|
}
|
|
state = parseAllColumnsState_EndOfName
|
|
columns = append(columns, string(name))
|
|
name = make([]rune, 0)
|
|
continue
|
|
}
|
|
name = append(name, s[i])
|
|
case parseAllColumnsState_EndOfName:
|
|
if isSpace(s[i]) {
|
|
continue
|
|
}
|
|
if isSeparator(s[i]) {
|
|
state = parseAllColumnsState_Beginning
|
|
continue
|
|
}
|
|
if s[i] == ')' {
|
|
state = parseAllColumnsState_State_End
|
|
continue
|
|
}
|
|
return nil, fmt.Errorf("unexpected token: %s", string(s[i]))
|
|
case parseAllColumnsState_State_End:
|
|
break
|
|
}
|
|
}
|
|
if state != parseAllColumnsState_State_End {
|
|
return nil, errors.New("unexpected end")
|
|
}
|
|
return columns, nil
|
|
}
|
|
|
|
func isSpace(r rune) bool {
|
|
return r == ' ' || r == '\t'
|
|
}
|
|
|
|
func isQuote(r rune) bool {
|
|
return r == '`' || r == '"' || r == '\''
|
|
}
|
|
|
|
func isSeparator(r rune) bool {
|
|
return r == ','
|
|
}
|