rebel 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|