rebel 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rebel/sql.rb +137 -37
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10809e6c0a432430cd14bff789a33f4e931d8d19
|
4
|
+
data.tar.gz: f09ec1c343f3202fdec996cbea89cc8b5c88eccc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb6c20a31bac4c52a5b2dba793608c53544b5abe713540b733e614009747a4f7e216e6bf998aee9b56985d4becc7c3b9552f35f93241c9cd50b462696a2a8c5a
|
7
|
+
data.tar.gz: dac1d09cbbc44bc324441295848757be87f77b48e362eda69417d15c770e8ceb8dd9a359bead9072c2d2173cc0a7d45320da7cbc4cc9888c43013c7c0acebeef
|
data/lib/rebel/sql.rb
CHANGED
@@ -51,6 +51,24 @@ module Rebel::SQL
|
|
51
51
|
end
|
52
52
|
|
53
53
|
class Raw < String
|
54
|
+
def wants_parens!
|
55
|
+
@wants_parens = true
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def wants_parens?
|
60
|
+
@wants_parens = false unless instance_variable_defined?(:@wants_parens)
|
61
|
+
@wants_parens
|
62
|
+
end
|
63
|
+
|
64
|
+
def parens
|
65
|
+
Raw.new("(#{self})")
|
66
|
+
end
|
67
|
+
|
68
|
+
def parens?
|
69
|
+
wants_parens? ? parens : self
|
70
|
+
end
|
71
|
+
|
54
72
|
def as(n)
|
55
73
|
Raw.new(self + " AS #{Rebel::SQL.name(n)}")
|
56
74
|
end
|
@@ -59,48 +77,117 @@ module Rebel::SQL
|
|
59
77
|
n ? as(n) : self
|
60
78
|
end
|
61
79
|
|
62
|
-
def on(clause)
|
63
|
-
Raw.new(self + " ON #{Rebel::SQL.and_clause(clause)}")
|
80
|
+
def on(*clause)
|
81
|
+
Raw.new(self + " ON #{Rebel::SQL.and_clause(*clause)}")
|
82
|
+
end
|
83
|
+
|
84
|
+
def on?(*clause)
|
85
|
+
clause.any? ? on(clause) : self
|
86
|
+
end
|
87
|
+
|
88
|
+
def and(*clause)
|
89
|
+
Raw.new("#{self.parens?} AND #{Rebel::SQL.and_clause(*clause)}")
|
64
90
|
end
|
65
91
|
|
66
|
-
def
|
67
|
-
|
92
|
+
def or(*clause)
|
93
|
+
Raw.new("#{self} OR #{Rebel::SQL.and_clause(*clause)}").wants_parens!
|
94
|
+
end
|
95
|
+
|
96
|
+
def eq(n)
|
97
|
+
case n
|
98
|
+
when nil
|
99
|
+
Raw.new("#{self} IS NULL")
|
100
|
+
else
|
101
|
+
Raw.new("#{self} = #{Rebel::SQL.name_or_value(n)}")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
alias == eq
|
105
|
+
alias is eq
|
106
|
+
|
107
|
+
def ne(n)
|
108
|
+
case n
|
109
|
+
when nil
|
110
|
+
Raw.new("#{self} IS NOT NULL")
|
111
|
+
else
|
112
|
+
Raw.new("#{self} != #{Rebel::SQL.name_or_value(n)}")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
alias != ne
|
116
|
+
|
117
|
+
def lt(n)
|
118
|
+
Raw.new("#{self} < #{Rebel::SQL.name_or_value(n)}")
|
119
|
+
end
|
120
|
+
alias < lt
|
121
|
+
|
122
|
+
def gt(n)
|
123
|
+
Raw.new("#{self} > #{Rebel::SQL.name_or_value(n)}")
|
124
|
+
end
|
125
|
+
alias > gt
|
126
|
+
|
127
|
+
def le(n)
|
128
|
+
Raw.new("#{self} <= #{Rebel::SQL.name_or_value(n)}")
|
129
|
+
end
|
130
|
+
alias <= le
|
131
|
+
|
132
|
+
def ge(n)
|
133
|
+
Raw.new("#{self} >= #{Rebel::SQL.name_or_value(n)}")
|
134
|
+
end
|
135
|
+
alias >= ge
|
136
|
+
|
137
|
+
def in(*v)
|
138
|
+
Raw.new("#{self} IN (#{Rebel::SQL.values(*v)})")
|
68
139
|
end
|
69
140
|
end
|
70
141
|
|
142
|
+
@identifier_quote = '"'
|
143
|
+
@string_quote = "'"
|
144
|
+
@escaped_string_quote = "''"
|
145
|
+
|
71
146
|
class << self
|
147
|
+
def identifier_quote=(str)
|
148
|
+
@identifier_quote = str
|
149
|
+
end
|
150
|
+
|
151
|
+
def string_quote=(str)
|
152
|
+
@string_quote = str
|
153
|
+
end
|
154
|
+
|
155
|
+
def escaped_string_quote=(str)
|
156
|
+
@escaped_string_quote = str
|
157
|
+
end
|
158
|
+
|
72
159
|
def raw(str)
|
73
160
|
Raw.new(str)
|
74
161
|
end
|
75
162
|
|
76
163
|
def create_table(table_name, desc)
|
77
164
|
<<-SQL
|
78
|
-
CREATE TABLE #{
|
79
|
-
#{
|
165
|
+
CREATE TABLE #{name(table_name)} (
|
166
|
+
#{list(desc.map { |k, v| "#{name(k)} #{v}" })}
|
80
167
|
);
|
81
168
|
SQL
|
82
169
|
end
|
83
170
|
|
84
171
|
def drop_table(table_name)
|
85
172
|
<<-SQL
|
86
|
-
DROP TABLE #{
|
173
|
+
DROP TABLE #{name(table_name)};
|
87
174
|
SQL
|
88
175
|
end
|
89
176
|
|
90
177
|
def select(*fields, from: nil, where: nil, inner: nil, left: nil, right: nil)
|
91
178
|
<<-SQL
|
92
179
|
SELECT #{names(*fields)} FROM #{name(from)}
|
93
|
-
#{
|
94
|
-
#{
|
95
|
-
#{
|
96
|
-
#{
|
180
|
+
#{inner?(inner)}
|
181
|
+
#{left?(left)}
|
182
|
+
#{right?(right)}
|
183
|
+
#{where?(where)};
|
97
184
|
SQL
|
98
185
|
end
|
99
186
|
|
100
187
|
def insert_into(table_name, *rows)
|
101
188
|
<<-SQL
|
102
|
-
INSERT INTO #{
|
103
|
-
VALUES #{
|
189
|
+
INSERT INTO #{name(table_name)} (#{names(*rows.first.keys)})
|
190
|
+
VALUES #{list(rows.map { |r| "(#{values(*r.values)})" })};
|
104
191
|
SQL
|
105
192
|
end
|
106
193
|
|
@@ -108,33 +195,38 @@ module Rebel::SQL
|
|
108
195
|
raise ArgumentError if set.nil?
|
109
196
|
|
110
197
|
<<-SQL
|
111
|
-
UPDATE #{
|
112
|
-
SET #{
|
113
|
-
#{
|
114
|
-
#{
|
115
|
-
#{
|
116
|
-
#{
|
198
|
+
UPDATE #{name(table_name)}
|
199
|
+
SET #{assign_clause(set)}
|
200
|
+
#{inner?(inner)}
|
201
|
+
#{left?(left)}
|
202
|
+
#{right?(right)}
|
203
|
+
#{where?(where)};
|
117
204
|
SQL
|
118
205
|
end
|
119
206
|
|
120
207
|
def delete_from(table_name, where: nil, inner: nil, left: nil, right: nil)
|
121
208
|
<<-SQL
|
122
|
-
DELETE FROM #{
|
123
|
-
#{
|
124
|
-
#{
|
125
|
-
#{
|
126
|
-
#{
|
209
|
+
DELETE FROM #{name(table_name)}
|
210
|
+
#{inner?(inner)}
|
211
|
+
#{left?(left)}
|
212
|
+
#{right?(right)}
|
213
|
+
#{where?(where)};
|
127
214
|
SQL
|
128
215
|
end
|
129
216
|
|
130
217
|
def truncate(table_name)
|
131
218
|
<<-SQL
|
132
|
-
TRUNCATE #{
|
219
|
+
TRUNCATE #{name(table_name)};
|
133
220
|
SQL
|
134
221
|
end
|
135
222
|
|
136
223
|
## Functions
|
137
224
|
|
225
|
+
def function(name, *args)
|
226
|
+
raw("#{name}(#{names_or_values(*args)})")
|
227
|
+
end
|
228
|
+
alias fn function
|
229
|
+
|
138
230
|
def count(*n)
|
139
231
|
raw("COUNT(#{names(*n)})")
|
140
232
|
end
|
@@ -165,7 +257,7 @@ module Rebel::SQL
|
|
165
257
|
return name if name.is_a?(Raw)
|
166
258
|
return raw('*') if name == '*'
|
167
259
|
|
168
|
-
name.to_s.split('.').map { |e| "
|
260
|
+
raw(name.to_s.split('.').map { |e| "#{@identifier_quote}#{e}#{@identifier_quote}" }.join('.'))
|
169
261
|
end
|
170
262
|
|
171
263
|
def names(*names)
|
@@ -176,11 +268,17 @@ module Rebel::SQL
|
|
176
268
|
items.join(', ')
|
177
269
|
end
|
178
270
|
|
271
|
+
def escape_str(str)
|
272
|
+
str.tr(@string_quote, @escaped_string_quote)
|
273
|
+
end
|
274
|
+
|
179
275
|
def value(v)
|
180
276
|
case v
|
181
277
|
when Raw then v
|
182
|
-
when String then raw "'#{v
|
278
|
+
when String then raw "'#{escape_str(v)}'"
|
183
279
|
when Integer then raw v.to_s
|
280
|
+
when TrueClass, FalseClass then raw(v ? 'TRUE' : 'FALSE')
|
281
|
+
when Date, Time, DateTime then value(v.iso8601)
|
184
282
|
when nil then raw 'NULL'
|
185
283
|
else raise NotImplementedError, v.inspect
|
186
284
|
end
|
@@ -194,6 +292,10 @@ module Rebel::SQL
|
|
194
292
|
item.is_a?(Symbol) ? name(item) : value(item)
|
195
293
|
end
|
196
294
|
|
295
|
+
def names_or_values(*items)
|
296
|
+
list(items.map { |v| name_or_value(v) })
|
297
|
+
end
|
298
|
+
|
197
299
|
def equal(l, r)
|
198
300
|
"#{name_or_value(l)} = #{name_or_value(r)}"
|
199
301
|
end
|
@@ -205,28 +307,26 @@ module Rebel::SQL
|
|
205
307
|
def clause_term(left, right)
|
206
308
|
case right
|
207
309
|
when Array
|
208
|
-
|
310
|
+
name(left).in(*right)
|
209
311
|
else
|
210
|
-
|
312
|
+
name(left).eq(name_or_value(right))
|
211
313
|
end
|
212
314
|
end
|
213
315
|
|
214
|
-
def and_clause(clause)
|
215
|
-
return clause if clause.is_a?(Raw) || clause.is_a?(String)
|
216
|
-
|
316
|
+
def and_clause(*clause)
|
217
317
|
clause.map do |e|
|
218
318
|
case e
|
319
|
+
when Hash then and_clause(*e.to_a)
|
219
320
|
when Array then clause_term(e[0], e[1])
|
220
|
-
when Raw
|
321
|
+
when Raw then e.parens?
|
322
|
+
when String then e
|
221
323
|
else raise NotImplementedError, e.class
|
222
324
|
end
|
223
325
|
end.join(' AND ')
|
224
326
|
end
|
225
327
|
|
226
|
-
def where?(clause)
|
227
|
-
|
228
|
-
|
229
|
-
clause && clause.any? ? "WHERE #{Rebel::SQL.and_clause(clause)}" : nil
|
328
|
+
def where?(*clause)
|
329
|
+
clause.any? ? "WHERE #{and_clause(*clause)}" : nil
|
230
330
|
end
|
231
331
|
|
232
332
|
def inner?(join)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rebel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Loic Nageleisen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: SQL-flavoured Ruby, or is it the other way around?
|
14
14
|
email: loic.nageleisen@gmail.com
|
@@ -38,7 +38,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
38
38
|
version: '0'
|
39
39
|
requirements: []
|
40
40
|
rubyforge_project:
|
41
|
-
rubygems_version: 2.
|
41
|
+
rubygems_version: 2.5.2
|
42
42
|
signing_key:
|
43
43
|
specification_version: 4
|
44
44
|
summary: Fight against the Object tyranny
|