query-interpreter/q/select.go

124 lines
3.0 KiB
Go

package q
import (
"strings"
"github.com/DataDog/go-sqllexer"
)
type Select struct {
Table string
Columns []string
Conditionals []Conditional
IsWildcard bool
}
func (q *Select) GetFullSql() string {
var workingSqlSlice []string
workingSqlSlice = append(workingSqlSlice, "SELECT")
if q.IsWildcard {
workingSqlSlice = append(workingSqlSlice, "*")
} else {
for i, column := range q.Columns {
if i < (len(q.Columns) - 1) {
workingSqlSlice = append(workingSqlSlice, column+",")
} else {
workingSqlSlice = append(workingSqlSlice, column)
}
}
}
workingSqlSlice = append(workingSqlSlice, "FROM "+q.Table)
for _, condition := range q.Conditionals {
workingSqlSlice = append(workingSqlSlice, condition.Key)
workingSqlSlice = append(workingSqlSlice, condition.Operator)
workingSqlSlice = append(workingSqlSlice, condition.Value) // TODO: need to account for `AND` and `OR`s and stuff
}
fullSql := strings.Join(workingSqlSlice, " ")
return fullSql
}
func ParseSelectStatement(sql string) Select {
query := Select{}
passedSELECT := false
passedColumns := false
passedFROM := false
passedTable := false
passedWHERE := false
var workingConditional = Conditional{}
var columns []string
lexer := sqllexer.New(sql)
for {
token := lexer.Scan()
if IsTokenEndOfStatement(token) {
break
}
if !passedSELECT && strings.ToUpper(token.Value) != "SELECT" {
break
} else if !passedSELECT {
passedSELECT = true
continue
}
if !passedColumns {
if token.Type == sqllexer.WILDCARD {
passedColumns = true
columns = make([]string, 0)
query.IsWildcard = true
} else if token.Type == sqllexer.IDENT {
columns = append(columns, token.Value)
continue
} else if token.Type == sqllexer.PUNCTUATION || token.Type == sqllexer.SPACE {
continue
} else {
passedColumns = true // TODO: make sure that I should be doing this
query.Columns = columns
}
}
if !passedFROM && strings.ToUpper(token.Value) == "FROM" {
passedFROM = true
} else if !passedFROM {
continue // TODO: make sure to check for other keywords that are allowed
}
if !passedTable && token.Type == sqllexer.IDENT {
passedTable = true
query.Table = token.Value
} else if !passedTable {
continue
}
if !passedWHERE && strings.ToUpper(token.Value) == "WHERE" {
passedWHERE = true
} else if !passedWHERE {
continue
}
if token.Type == sqllexer.IDENT {
workingConditional.Key = token.Value
} else if token.Type == sqllexer.OPERATOR {
workingConditional.Operator = token.Value
} else if token.Type == sqllexer.BOOLEAN || token.Type == sqllexer.NULL || token.Type == sqllexer.STRING || token.Type == sqllexer.NUMBER {
workingConditional.Value = token.Value
} // TODO: add captire for data type
if workingConditional.Key != "" && workingConditional.Operator != "" && workingConditional.Value != "" {
query.Conditionals = append(query.Conditionals, workingConditional)
workingConditional = Conditional{}
continue
}
}
return query
}