1 | isRaw = (x) ->
|
2 | x? and ('object' is typeof x) and ('function' is typeof x.sql)
|
3 |
|
4 | asRaw = (x) ->
|
5 | if isRaw x
|
6 | return x
|
7 |
|
8 | unless 'string' is typeof x
|
9 | throw new Exception 'raw or string expected'
|
10 |
|
11 | {
|
12 | sql: -> x
|
13 | params: -> []
|
14 | }
|
15 |
|
16 | insert =
|
17 | sql: (mohair) ->
|
18 | that = this
|
19 |
|
20 | unless mohair._table?
|
21 | throw new Error 'sql of insert requires call to table before it'
|
22 |
|
23 | table = mohair._escape mohair._table
|
24 | keys = Object.keys(that._data)
|
25 | escapedKeys = keys.map (key) -> mohair._escape key
|
26 | row = keys.map (key) ->
|
27 | if isRaw that._data[key]
|
28 | that._data[key].sql()
|
29 | else
|
30 | '?'
|
31 | "INSERT INTO #{table}(#{escapedKeys.join ', '}) VALUES (#{row.join ', '})"
|
32 | params: ->
|
33 | that = this
|
34 | params = []
|
35 | Object.keys(that._data).map (key) ->
|
36 | if isRaw that._data[key]
|
37 | params = params.concat that._data[key].params()
|
38 | else
|
39 | params.push that._data[key]
|
40 | params
|
41 |
|
42 | module.exports.insert = (data) ->
|
43 | object = Object.create insert
|
44 | object._data = data
|
45 | object
|
46 |
|
47 | insertMany =
|
48 | sql: (mohair) ->
|
49 | that = this
|
50 |
|
51 | unless mohair._table?
|
52 | throw new Error 'sql of insertMany requires call to table before it'
|
53 |
|
54 | table = mohair._escape mohair._table
|
55 | first = that._array[0]
|
56 | keys = Object.keys(first)
|
57 | escapedKeys = keys.map (key) -> mohair._escape key
|
58 | rows = that._array.map (data) ->
|
59 | row = keys.map (key) ->
|
60 | if isRaw data[key]
|
61 | data[key].sql()
|
62 | else
|
63 | '?'
|
64 | "(#{row.join ', '})"
|
65 | "INSERT INTO #{table}(#{escapedKeys.join ', '}) VALUES #{rows.join ', '}"
|
66 | params: (mohair) ->
|
67 | that = this
|
68 | firstKeys = Object.keys that._array[0]
|
69 | params = []
|
70 | that._array.forEach (data) ->
|
71 | firstKeys.forEach (key) ->
|
72 | if isRaw data[key]
|
73 | params = params.concat data[key].params()
|
74 | else
|
75 | params.push data[key]
|
76 | params
|
77 |
|
78 | module.exports.insertMany = (array) ->
|
79 | object = Object.create insertMany
|
80 | object._array = array
|
81 | object
|
82 |
|
83 | select =
|
84 | sql: (mohair) ->
|
85 | that = this
|
86 | table = mohair._escape mohair._table
|
87 | sql = ''
|
88 |
|
89 | if mohair._with?
|
90 | sql += 'WITH '
|
91 | parts = []
|
92 | parts = Object.keys(mohair._with).map (key) ->
|
93 | key + ' AS (' + asRaw(mohair._with[key]).sql() + ')'
|
94 | sql += parts.join(', ')
|
95 | sql += ' '
|
96 |
|
97 | sql += "SELECT "
|
98 | parts = []
|
99 | that._selects.forEach (s) ->
|
100 | if isRaw s
|
101 | parts.push '(' + s.sql() + ')'
|
102 | else if 'object' is typeof s
|
103 | keys = Object.keys s
|
104 | if keys.length is 0
|
105 | throw new Error 'select object must have at least one property'
|
106 | keys.forEach (key) ->
|
107 | value = s[key]
|
108 | if isRaw value
|
109 | parts.push '(' + value.sql() + ') AS ' + key
|
110 | else
|
111 | parts.push value + ' AS ' + key
|
112 | else
|
113 | parts.push s
|
114 | sql += parts.join ', '
|
115 | if mohair._table?
|
116 | sql += " FROM #{table}"
|
117 | mohair._joins.forEach (join) ->
|
118 | sql += " #{join.sql}"
|
119 | sql += " AND (#{join.criterion.sql()})" if join.criterion?
|
120 | sql += " WHERE #{mohair._where.sql()}" if mohair._where?
|
121 | sql += " GROUP BY #{mohair._group}" if mohair._group?
|
122 | sql += " HAVING #{mohair._having.sql()}" if mohair._having?
|
123 | sql += " ORDER BY #{mohair._order}" if mohair._order?
|
124 | sql += " LIMIT ?" if mohair._limit?
|
125 | sql += " OFFSET ?" if mohair._offset?
|
126 | sql
|
127 | params: (mohair) ->
|
128 | that = this
|
129 | params = []
|
130 |
|
131 | if mohair._with?
|
132 | Object.keys(mohair._with).forEach (key) ->
|
133 | params = params.concat asRaw(mohair._with[key]).params()
|
134 |
|
135 | that._selects.forEach (s) ->
|
136 | if isRaw s
|
137 | params = params.concat s.params()
|
138 | else if 'object' is typeof s
|
139 | keys = Object.keys s
|
140 | if keys.length is 0
|
141 | throw new Error 'select object must have at least one property'
|
142 | keys.forEach (key) ->
|
143 | params = params.concat asRaw(s[key]).params()
|
144 |
|
145 | mohair._joins.forEach (join) ->
|
146 | if join.criterion?
|
147 | params = params.concat join.criterion.params()
|
148 |
|
149 | params = params.concat mohair._where.params() if mohair._where?
|
150 | params.push mohair._limit if mohair._limit?
|
151 | params.push mohair._offset if mohair._offset?
|
152 | params
|
153 |
|
154 | module.exports.select = ->
|
155 | selects = Array.prototype.slice.call arguments
|
156 | object = Object.create select
|
157 | if selects.length is 0
|
158 | selects = ['*']
|
159 | object._selects = selects
|
160 | object
|
161 |
|
162 | update =
|
163 | sql: (mohair) ->
|
164 | that = this
|
165 |
|
166 | unless mohair._table?
|
167 | throw new Error 'sql of update requires call to table before it'
|
168 |
|
169 | table = mohair._escape mohair._table
|
170 | keys = Object.keys that._updates
|
171 |
|
172 | updates = keys.map (key) ->
|
173 | escapedKey = mohair._escape key
|
174 | if isRaw that._updates[key]
|
175 | "#{escapedKey} = #{that._updates[key].sql()}"
|
176 | else
|
177 | "#{escapedKey} = ?"
|
178 | sql = "UPDATE #{table} SET #{updates.join ', '}"
|
179 | sql += " WHERE #{mohair._where.sql()}" if mohair._where?
|
180 | sql
|
181 | params: (mohair) ->
|
182 | that = this
|
183 | params = []
|
184 | Object.keys(that._updates).forEach (key) ->
|
185 | if isRaw that._updates[key]
|
186 | params = params.concat that._updates[key].params()
|
187 | else
|
188 | params.push that._updates[key]
|
189 | params = params.concat mohair._where.params() if mohair._where?
|
190 | params
|
191 |
|
192 | module.exports.update = (updates) ->
|
193 | object = Object.create update
|
194 | object._updates = updates
|
195 | object
|
196 |
|
197 | deletePrototype =
|
198 | sql: (mohair) ->
|
199 | that = this
|
200 |
|
201 | unless mohair._table?
|
202 | throw new Error 'sql of delete requires call to table before it'
|
203 |
|
204 | table = mohair._escape mohair._table
|
205 | sql = "DELETE FROM #{table}"
|
206 | sql += " WHERE #{mohair._where.sql()}" if mohair._where?
|
207 | sql
|
208 | params: (mohair) ->
|
209 | if mohair._where?
|
210 | mohair._where.params()
|
211 | else []
|
212 |
|
213 | module.exports.delete = ->
|
214 | Object.create deletePrototype
|