deathkel /
sqlbuilder
| 1 | package sqlbuilder |
||
| 2 | |||
| 3 | import ( |
||
| 4 | "strings" |
||
| 5 | ) |
||
| 6 | |||
| 7 | type Grammar struct { |
||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 8 | selectComponents []string |
||
| 9 | operators []string |
||
| 10 | } |
||
| 11 | |||
| 12 | func wrapValue(value string) (string) { |
||
| 13 | if value == "*" { |
||
| 14 | return value |
||
| 15 | } |
||
| 16 | if strings.ContainsAny(value, ".()") { |
||
| 17 | return value |
||
| 18 | } |
||
| 19 | |||
| 20 | value = strings.Replace(value, "`", "", -1) |
||
| 21 | return "`" + value + "`" |
||
| 22 | } |
||
| 23 | |||
| 24 | func CompileSelect(query *Builder) (sql string, bindings []string) { |
||
|
0 ignored issues
–
show
|
|||
| 25 | |||
| 26 | //select |
||
| 27 | sql = addSelect(query) |
||
| 28 | |||
| 29 | //from |
||
| 30 | sql += addFrom(query) |
||
| 31 | |||
| 32 | //join |
||
| 33 | sql += addJoin(query) |
||
| 34 | |||
| 35 | //where |
||
| 36 | sql += addWhere(query) |
||
| 37 | |||
| 38 | //group by |
||
| 39 | sql += addGroupBy(query) |
||
| 40 | |||
| 41 | //having |
||
| 42 | sql += addHaving(query) |
||
| 43 | |||
| 44 | //order by |
||
| 45 | sql += addOrderBy(query) |
||
| 46 | |||
| 47 | //limit |
||
| 48 | sql += addLimit(query) |
||
| 49 | |||
| 50 | //offset |
||
| 51 | sql += addOffset(query) |
||
| 52 | |||
| 53 | bindings = append(query.bindings.where, query.bindings.having...) |
||
| 54 | |||
| 55 | if query.limit != "" { |
||
| 56 | bindings = append(bindings, query.limit) |
||
| 57 | } |
||
| 58 | |||
| 59 | if query.offset != "" { |
||
| 60 | bindings = append(bindings, query.offset) |
||
| 61 | } |
||
| 62 | |||
| 63 | return sql, bindings |
||
| 64 | } |
||
| 65 | |||
| 66 | func CompileUpdate(query *Builder) (sql string, bindings []string) { |
||
|
0 ignored issues
–
show
|
|||
| 67 | //update |
||
| 68 | sql = addUpdate(query) |
||
| 69 | |||
| 70 | //where |
||
| 71 | sql += addWhere(query) |
||
| 72 | |||
| 73 | //limit |
||
| 74 | sql += addLimit(query) |
||
| 75 | |||
| 76 | //offset |
||
| 77 | sql += addOffset(query) |
||
| 78 | |||
| 79 | bindings = append(query.bindings.update, query.bindings.where...) |
||
| 80 | |||
| 81 | if query.limit != "" { |
||
| 82 | bindings = append(bindings, query.limit) |
||
| 83 | } |
||
| 84 | |||
| 85 | if query.offset != "" { |
||
| 86 | bindings = append(bindings, query.offset) |
||
| 87 | } |
||
| 88 | |||
| 89 | return sql, bindings |
||
| 90 | } |
||
| 91 | |||
| 92 | func CompileInsert(query *Builder) (sql string, bindings []string) { |
||
|
0 ignored issues
–
show
|
|||
| 93 | //insert |
||
| 94 | sql = addInsert(query) |
||
| 95 | |||
| 96 | //limit |
||
| 97 | sql += addLimit(query) |
||
| 98 | |||
| 99 | //offset |
||
| 100 | sql += addOffset(query) |
||
| 101 | |||
| 102 | bindings = append(query.bindings.insert, query.bindings.where...) |
||
| 103 | |||
| 104 | if query.limit != "" { |
||
| 105 | bindings = append(bindings, query.limit) |
||
| 106 | } |
||
| 107 | |||
| 108 | if query.offset != "" { |
||
| 109 | bindings = append(bindings, query.offset) |
||
| 110 | } |
||
| 111 | |||
| 112 | return sql, bindings |
||
| 113 | } |
||
| 114 | |||
| 115 | func CompileDelete(query *Builder) (sql string, bindings []string) { |
||
|
0 ignored issues
–
show
|
|||
| 116 | //delete |
||
| 117 | sql = addDelete(query) |
||
| 118 | |||
| 119 | //where |
||
| 120 | sql += addWhere(query) |
||
| 121 | |||
| 122 | //limit |
||
| 123 | sql += addLimit(query) |
||
| 124 | |||
| 125 | //offset |
||
| 126 | sql += addOffset(query) |
||
| 127 | |||
| 128 | bindings = append(bindings, query.bindings.where...) |
||
| 129 | |||
| 130 | if query.limit != "" { |
||
| 131 | bindings = append(bindings, query.limit) |
||
| 132 | } |
||
| 133 | |||
| 134 | if query.offset != "" { |
||
| 135 | bindings = append(bindings, query.offset) |
||
| 136 | } |
||
| 137 | |||
| 138 | return sql, bindings |
||
| 139 | } |
||
| 140 | |||
| 141 | func addInsert(query *Builder) (sql string) { |
||
| 142 | sql = "insert into " + wrapValue(query.table) + " (" |
||
| 143 | lenInsert := len(query.insert) |
||
| 144 | idx := 0 |
||
| 145 | for _, column := range query.insert { |
||
| 146 | idx ++ |
||
| 147 | sql += wrapValue(column) |
||
| 148 | if idx < lenInsert { |
||
| 149 | sql += ", " |
||
| 150 | } |
||
| 151 | } |
||
| 152 | sql += ") values (" |
||
| 153 | for i := 1; i <= lenInsert; i++ { |
||
| 154 | sql += "?" |
||
| 155 | if i < lenInsert { |
||
| 156 | sql += ", " |
||
| 157 | } |
||
| 158 | } |
||
| 159 | sql += ")" |
||
| 160 | return |
||
| 161 | } |
||
| 162 | |||
| 163 | func addUpdate(query *Builder) (sql string) { |
||
| 164 | sql = "update " + wrapValue(query.table) + " set " |
||
| 165 | lenUpdate := len(query.update) |
||
| 166 | idx := 0 |
||
| 167 | for _, column := range query.update { |
||
| 168 | idx ++ |
||
| 169 | switch column.(type) { |
||
| 170 | case string: |
||
| 171 | sql += wrapValue(column.(string)) + " = ?" |
||
| 172 | case *Expression: |
||
| 173 | sql += column.(*Expression).Value |
||
| 174 | } |
||
| 175 | |||
| 176 | if idx < lenUpdate { |
||
| 177 | sql += ", " |
||
| 178 | } |
||
| 179 | } |
||
| 180 | return |
||
| 181 | } |
||
| 182 | |||
| 183 | func addDelete(query *Builder) (sql string) { |
||
| 184 | sql = "delete " + wrapValue(query.table) |
||
| 185 | return |
||
| 186 | } |
||
| 187 | |||
| 188 | func addSelect(query *Builder) (string) { |
||
| 189 | sql := "select" |
||
| 190 | lenColumns := len(query.columns) |
||
| 191 | if lenColumns == 0 { |
||
| 192 | sql += " *" |
||
| 193 | } else { |
||
| 194 | for key, column := range query.columns { |
||
| 195 | sql += " " + wrapValue(column) |
||
| 196 | if key < lenColumns-1 { |
||
| 197 | sql += "," |
||
| 198 | } |
||
| 199 | } |
||
| 200 | } |
||
| 201 | return sql |
||
| 202 | } |
||
| 203 | |||
| 204 | func addFrom(query *Builder) (sql string) { |
||
| 205 | sql = " from " + wrapValue(query.table) |
||
| 206 | return |
||
| 207 | } |
||
| 208 | |||
| 209 | func addJoin(query *Builder) (sql string) { |
||
| 210 | lenJoin := len(query.joins) |
||
| 211 | if lenJoin == 0 { |
||
| 212 | return sql |
||
| 213 | } |
||
| 214 | for _, val := range query.joins { |
||
| 215 | switch val.joinType { |
||
| 216 | case "left": |
||
| 217 | sql += " left join " |
||
| 218 | case "right": |
||
| 219 | sql += " right join " |
||
| 220 | default: |
||
| 221 | sql += " join " |
||
| 222 | } |
||
| 223 | sql += wrapValue(val.table) + " on " + val.condition |
||
| 224 | } |
||
| 225 | return sql |
||
| 226 | } |
||
| 227 | |||
| 228 | func addWhere(query *Builder) (sql string) { |
||
| 229 | lenWhere := len(query.wheres) |
||
| 230 | if lenWhere > 0 { |
||
| 231 | sql += " where (" |
||
| 232 | } |
||
| 233 | for key, where := range query.wheres { |
||
| 234 | if where.operator == "in" || where.operator == "not in" { |
||
| 235 | sql += wrapValue(where.column) + " " + where.operator + " (" |
||
| 236 | lenVal := len(where.value.([]string)) |
||
| 237 | for i := 0; i < lenVal; i++ { |
||
| 238 | if i == lenVal -1 { |
||
| 239 | sql += "? " |
||
| 240 | }else{ |
||
| 241 | sql += "?, " |
||
| 242 | } |
||
| 243 | } |
||
| 244 | |||
| 245 | sql += ")" |
||
| 246 | }else{ |
||
| 247 | sql += wrapValue(where.column) + " " + where.operator + " ?" |
||
| 248 | } |
||
| 249 | if key < lenWhere-1 { |
||
| 250 | sql += " " + where.boolean + " " |
||
| 251 | } |
||
| 252 | } |
||
| 253 | if lenWhere > 0 { |
||
| 254 | sql += ")" |
||
| 255 | } |
||
| 256 | |||
| 257 | return sql |
||
| 258 | } |
||
| 259 | |||
| 260 | func addGroupBy(query *Builder) (sql string) { |
||
| 261 | lenGroups := len(query.groups) |
||
| 262 | if lenGroups > 0 { |
||
| 263 | sql += " group by" |
||
| 264 | } |
||
| 265 | for key, column := range query.groups { |
||
| 266 | sql += " " + wrapValue(column) |
||
| 267 | if key < lenGroups-1 { |
||
| 268 | sql += "," |
||
| 269 | } |
||
| 270 | } |
||
| 271 | return sql |
||
| 272 | } |
||
| 273 | |||
| 274 | func addHaving(query *Builder) (sql string) { |
||
| 275 | lenHavings := len(query.havings) |
||
| 276 | if lenHavings > 0 { |
||
| 277 | sql += " having" |
||
| 278 | } |
||
| 279 | for key, where := range query.havings { |
||
| 280 | sql += " " + wrapValue(where.column) + " " + where.operator + " ?" |
||
| 281 | if key < lenHavings-1 { |
||
| 282 | sql += " " + where.boolean |
||
| 283 | } |
||
| 284 | } |
||
| 285 | return sql |
||
| 286 | } |
||
| 287 | |||
| 288 | func addOrderBy(query *Builder) (sql string) { |
||
| 289 | lenOrder := len(query.orders) |
||
| 290 | if lenOrder > 0 { |
||
| 291 | sql += " order by" |
||
| 292 | } |
||
| 293 | for key, order := range query.orders { |
||
| 294 | sql += " " + order.column + " " + order.direction |
||
| 295 | if key < lenOrder-1 { |
||
| 296 | sql += "," |
||
| 297 | } |
||
| 298 | } |
||
| 299 | return sql |
||
| 300 | } |
||
| 301 | |||
| 302 | func addOffset(query *Builder) (sql string) { |
||
| 303 | if query.offset != "" { |
||
| 304 | sql += " offset ?" |
||
| 305 | } |
||
| 306 | return sql |
||
| 307 | } |
||
| 308 | |||
| 309 | func addLimit(query *Builder) (sql string) { |
||
| 310 | if query.limit != "" { |
||
| 311 | sql += " limit ?" |
||
| 312 | } |
||
| 313 | return sql |
||
| 314 | } |
||
| 315 |