Add stack implementation for SmartQuote
This commit is contained in:
parent
a3ea7a3c0c
commit
01228b4e26
2 changed files with 110 additions and 0 deletions
|
@ -17,6 +17,37 @@ var (
|
|||
uppercaseWords = []string{"id", "uid", "uuid", "guid", "ssn", "tz"}
|
||||
)
|
||||
|
||||
type state int
|
||||
type smartStack []state
|
||||
|
||||
const (
|
||||
stateNothing = iota
|
||||
stateSubExpression
|
||||
stateFunction
|
||||
stateIdentifier
|
||||
)
|
||||
|
||||
func (stack *smartStack) push(s state) {
|
||||
*stack = append(*stack, s)
|
||||
}
|
||||
|
||||
func (stack *smartStack) pop() state {
|
||||
l := len(*stack)
|
||||
if l == 0 {
|
||||
return stateNothing
|
||||
}
|
||||
|
||||
v := (*stack)[l-1]
|
||||
*stack = (*stack)[:l-1]
|
||||
return v
|
||||
}
|
||||
|
||||
// SmartQuote intelligently quotes identifiers in sql statements
|
||||
func SmartQuote(s string) string {
|
||||
// split on comma, treat as individual thing
|
||||
return s
|
||||
}
|
||||
|
||||
// Identifier is a base conversion from Base 10 integers to Base 26
|
||||
// integers that are represented by an alphabet from a-z
|
||||
// See tests for example outputs.
|
||||
|
|
|
@ -5,6 +5,85 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func TestStack(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
stack := smartStack{}
|
||||
|
||||
if stack.pop() != stateNothing {
|
||||
t.Errorf("Expected state nothing for empty stack")
|
||||
}
|
||||
|
||||
stack.push(stateFunction)
|
||||
stack.push(stateSubExpression)
|
||||
stack.push(stateNothing)
|
||||
|
||||
if len(stack) != 3 {
|
||||
t.Errorf("Expected 3 state on stack, got %d", len(stack))
|
||||
}
|
||||
|
||||
if r := stack.pop(); r != stateNothing {
|
||||
t.Errorf("Expected stateNothing, got %v", r)
|
||||
}
|
||||
if len(stack) != 2 {
|
||||
t.Errorf("Expected 2 state on stack, got %d", len(stack))
|
||||
}
|
||||
|
||||
if r := stack.pop(); r != stateSubExpression {
|
||||
t.Errorf("Expected stateSubExpression, got %v", r)
|
||||
}
|
||||
if len(stack) != 1 {
|
||||
t.Errorf("Expected 1 state on stack, got %d", len(stack))
|
||||
}
|
||||
|
||||
stack.push(stateSubExpression)
|
||||
if len(stack) != 2 {
|
||||
t.Errorf("Expected 2 state on stack, got %d", len(stack))
|
||||
}
|
||||
|
||||
if r := stack.pop(); r != stateSubExpression {
|
||||
t.Errorf("Expected stateSubExpression, got %v", r)
|
||||
}
|
||||
if len(stack) != 1 {
|
||||
t.Errorf("Expected 1 state on stack, got %d", len(stack))
|
||||
}
|
||||
|
||||
if r := stack.pop(); r != stateFunction {
|
||||
t.Errorf("Expected stateFunction, got %v", r)
|
||||
}
|
||||
if len(stack) != 0 {
|
||||
t.Errorf("Expected 0 state on stack, got %d", len(stack))
|
||||
}
|
||||
if stack.pop() != stateNothing {
|
||||
t.Errorf("Expected state nothing for empty stack")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmartQuote(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
In string
|
||||
Out string
|
||||
}{
|
||||
{In: `count(*) as thing, thing as stuff`, Out: `count(*) as thing, "thing" as stuff`},
|
||||
{In: `select (select 1) as thing, thing as stuff`, Out: `select (select 1) as thing, "thing" as stuff`},
|
||||
{
|
||||
In: `select (select stuff as thing from thing where id=1 or name="thing") as stuff`,
|
||||
Out: `select (select "stuff" as thing from thing where id=1 or name="thing") as stuff`,
|
||||
},
|
||||
{In: `thing`, Out: `"thing"`},
|
||||
{In: `thing, stuff`, Out: `"thing", "stuff"`},
|
||||
{In: `*`, Out: `*`},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
if got := SmartQuote(test.In); got != test.Out {
|
||||
t.Errorf("want: %s, got: %s", test.Out, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDGen(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue