This repository has been archived by the owner on Feb 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsqlclause.go
174 lines (159 loc) · 3.75 KB
/
sqlclause.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package sqlr
import (
"fmt"
"strings"
)
// sqlClause represents a specific SQL clause. Column lists
// and table names are represented differently depending on
// which SQL clause they appear in.
type sqlClause int
// All of the different clauses of an SQL statement where columns
// and table names can be found.
const (
clauseNone sqlClause = iota
clauseSelectColumns
clauseSelectFrom
clauseSelectWhere
clauseSelectOrderBy
clauseInsertColumns
clauseInsertValues
clauseUpdateTable
clauseUpdateSet
clauseUpdateWhere
clauseDeleteFrom
clauseDeleteWhere
)
// queryType deduces the type of query based on the SQL clause.
func (c sqlClause) queryType() queryType {
switch c {
case clauseSelectColumns, clauseSelectFrom, clauseSelectWhere, clauseSelectOrderBy:
return querySelect
case clauseInsertColumns, clauseInsertValues:
return queryInsert
case clauseUpdateTable, clauseUpdateSet, clauseUpdateWhere:
return queryUpdate
case clauseDeleteFrom, clauseDeleteWhere:
return queryDelete
}
return queryUnknown
}
func (c sqlClause) String() string {
switch c {
case clauseNone:
return "(no clause)"
case clauseSelectColumns:
return "select columns"
case clauseSelectFrom:
return "select from"
case clauseSelectWhere:
return "select where"
case clauseSelectOrderBy:
return "select order by"
case clauseInsertColumns:
return "insert columns"
case clauseInsertValues:
return "insert values"
case clauseUpdateTable:
return "update table"
case clauseUpdateSet:
return "update set"
case clauseUpdateWhere:
return "update where"
case clauseDeleteFrom:
return "delete from"
case clauseDeleteWhere:
return "delete where"
}
return fmt.Sprintf("Unknown %d", c)
}
// isInput identifies whether the SQL clause contains placeholders
// for variable input.
func (c sqlClause) isInput() bool {
return c.matchAny(
clauseInsertValues,
clauseUpdateSet,
clauseSelectWhere,
clauseUpdateWhere,
clauseDeleteWhere)
}
func (c sqlClause) isOutput() bool {
return c == clauseSelectColumns
}
func (c sqlClause) acceptsColumns() bool {
return c.isInput() ||
c.isOutput() ||
c.matchAny(clauseSelectOrderBy,
clauseInsertColumns)
}
func (c sqlClause) matchAny(clauses ...sqlClause) bool {
for _, clause := range clauses {
if c == clause {
return true
}
}
return false
}
func (c sqlClause) defaultFilter() func(col *Column) bool {
switch c {
case clauseSelectWhere, clauseSelectOrderBy, clauseUpdateWhere, clauseDeleteWhere:
return columnFilterPK
case clauseInsertColumns, clauseInsertValues:
return columnFilterInsertable
case clauseUpdateSet:
return columnFilterUpdateable
}
return columnFilterAll
}
// nextClause operates an extremely simple state transition
// keeping track of which part of an SQL clause we are in.
func (c sqlClause) nextClause(keyword string) sqlClause {
keyword = strings.ToLower(keyword)
switch keyword {
case "delete":
return clauseDeleteFrom
case "from":
switch c {
case clauseSelectColumns:
return clauseSelectFrom
}
case "insert", "into":
return clauseInsertColumns
case "order":
switch c {
case clauseSelectFrom, clauseSelectColumns, clauseSelectWhere:
return clauseSelectOrderBy
}
case "select":
return clauseSelectColumns
case "set":
switch c {
case clauseUpdateTable:
return clauseUpdateSet
}
case "update":
return clauseUpdateTable
case "values":
switch c {
case clauseInsertColumns:
return clauseInsertValues
}
case "where":
switch c {
case clauseSelectFrom, clauseSelectColumns:
return clauseSelectWhere
case clauseDeleteFrom:
return clauseDeleteWhere
case clauseUpdateSet, clauseUpdateTable:
return clauseUpdateWhere
}
}
return c
}
type queryType int
const (
queryUnknown queryType = iota
queryInsert
queryUpdate
queryDelete
querySelect
)