i_dig_sql 2.0.0 → 3.0.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/README.md +10 -19
- data/VERSION +1 -1
- data/bin/test +38 -1
- data/i_dig_sql.gemspec +8 -4
- data/lib/i_dig_sql.rb +388 -65
- data/lib/i_dig_sql/H.rb +43 -0
- data/specs/0000-I_Dig_Sql.rb +84 -0
- data/specs/0001-new.rb +20 -0
- data/specs/0010-vars.rb +38 -0
- data/specs/0011-to_pair.rb +15 -0
- data/specs/0020-to_sql.rb +31 -0
- data/specs/0030-funcs.rb +40 -0
- data/specs/helpers.rb +51 -0
- metadata +74 -12
- data/englishy_sql.rb +0 -98
- data/specs/i_dig_sql.rb +0 -203
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a72cee2c11ff760fcb5227b539fa976a39dfb56
|
4
|
+
data.tar.gz: a418aba79878b9361f980f137c7be1b108e3ee74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e7ef6053d12c991ab562da0c882bc510babae4c315e108e7bb34c67855e998106ea51ccc1f5c4384a88d9f5c0fdbaf8b2f183539d1c3a40b208b4be73431de5
|
7
|
+
data.tar.gz: 43c7bca10bbb494ab492e7ad1852ecbd992ba80b96832056bf6760b7f8c2a533023faeb8df91ab595bf30e04c38081d927367ad522f269245b1f6b5c8f113aae
|
data/README.md
CHANGED
@@ -1,29 +1,19 @@
|
|
1
1
|
# I\_Dig\_Sql
|
2
2
|
|
3
|
-
My way of managing SQL fragments using Ruby.
|
4
3
|
|
5
|
-
|
4
|
+
I'm still learning how to write decent SQL queries
|
5
|
+
in Postgresql 9.4. I'm using this to manage
|
6
|
+
sub-queries in complicated SQL queries.
|
6
7
|
|
7
|
-
You
|
8
|
-
|
8
|
+
You won't find this useful and I am too lazy/busy
|
9
|
+
to write decent documentation for something
|
10
|
+
no one but me will use for esoteric purposes.
|
11
|
+
|
12
|
+
Instead, this to for SQL + Ruby:
|
9
13
|
|
10
14
|
* [Arel](http://github.com/rails/arel).
|
11
15
|
* K'bam [https://github.com/vilnius-leopold/kbam](https://github.com/vilnius-leopold/kbam)
|
12
|
-
|
13
|
-
# History
|
14
|
-
|
15
|
-
I had trouble maintaining BIG sql queries.
|
16
|
-
|
17
|
-
I tried many things.
|
18
|
-
|
19
|
-
The best way (within my preferences)
|
20
|
-
was to use sub-queries, CTEs, avoid joins as much as possible,
|
21
|
-
and this gem to manage SQL fragments and CTEs.
|
22
|
-
|
23
|
-
Naturally, you would want to use prepared statements, compiled wat-cha-me-call-its,
|
24
|
-
functions, views, thing-ma-jig-ers, and other tools available in your RDBMS.
|
25
|
-
|
26
|
-
So this gem is for lazy, stupid people like me.
|
16
|
+
* Sequel [http://sequel.jeremyevans.net/rdoc/files/doc/querying_rdoc.html](http://sequel.jeremyevans.net/rdoc/files/doc/querying_rdoc.html)
|
27
17
|
|
28
18
|
# Usage
|
29
19
|
|
@@ -52,6 +42,7 @@ Please note that none of this is ready yet.
|
|
52
42
|
^
|
53
43
|
|
54
44
|
sql.to_sql
|
45
|
+
|
55
46
|
```
|
56
47
|
|
57
48
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.0
|
data/bin/test
CHANGED
@@ -2,9 +2,46 @@
|
|
2
2
|
# -*- bash -*-
|
3
3
|
#
|
4
4
|
#
|
5
|
+
x="$1"
|
5
6
|
set -u -e -o pipefail
|
6
7
|
|
8
|
+
if [[ "$x" == "watch" ]]; then
|
9
|
+
shift
|
7
10
|
|
8
|
-
|
11
|
+
echo ""
|
12
|
+
echo "=== Watching: $@"
|
13
|
+
|
14
|
+
echo -e "\n=== Running test:"
|
15
|
+
bin/test "$@" || echo ""
|
16
|
+
|
17
|
+
inotifywait -q -m -e close_write,close --exclude .git/ -r . | while read CHANGE
|
18
|
+
do
|
19
|
+
|
20
|
+
dir=$(echo "$CHANGE" | cut -d' ' -f 1)
|
21
|
+
op=$(echo "$CHANGE" | cut -d' ' -f 2)
|
22
|
+
file=$(echo "$CHANGE" | cut -d' ' -f 3)
|
23
|
+
path="${dir}$file"
|
24
|
+
|
25
|
+
if [[ "$op" == *CLOSE_WRITE* && $file == *.rb* ]]; then
|
26
|
+
echo -e "\n=== Running test:"
|
27
|
+
bin/test "$@" || echo ""
|
28
|
+
fi
|
29
|
+
|
30
|
+
done # === do
|
31
|
+
|
32
|
+
echo ""
|
33
|
+
exit 0
|
34
|
+
fi # === if watch
|
35
|
+
|
36
|
+
files="$(echo specs/*-$x.rb)"
|
37
|
+
if [[ -f "$files" ]]; then
|
38
|
+
shift
|
39
|
+
else
|
40
|
+
files="$(echo specs/*-*.rb)"
|
41
|
+
fi
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
bundle exec bacon -rpry -ri_dig_sql specs/helpers.rb $files "$@"
|
9
46
|
|
10
47
|
|
data/i_dig_sql.gemspec
CHANGED
@@ -21,8 +21,12 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.add_development_dependency "bundler"
|
25
|
-
spec.add_development_dependency "bacon"
|
26
|
-
spec.add_development_dependency "Bacon_Colored"
|
27
|
-
spec.add_development_dependency "pry"
|
24
|
+
spec.add_development_dependency "bundler" , "> 1.5"
|
25
|
+
spec.add_development_dependency "bacon" , '> 1.0'
|
26
|
+
spec.add_development_dependency "Bacon_Colored" , '> 0'
|
27
|
+
spec.add_development_dependency "pry" , '> 0'
|
28
|
+
spec.add_development_dependency "awesome_print" , '> 0'
|
29
|
+
spec.add_development_dependency "anbt-sql-formatter" , '> 0'
|
30
|
+
spec.add_development_dependency "rouge" , '> 0.0.0'
|
31
|
+
spec.add_development_dependency "unindent" , '> 0.0.0'
|
28
32
|
end
|
data/lib/i_dig_sql.rb
CHANGED
@@ -1,124 +1,447 @@
|
|
1
1
|
|
2
|
+
require "i_dig_sql/H"
|
3
|
+
|
2
4
|
class I_Dig_Sql
|
3
5
|
|
4
6
|
include Enumerable
|
7
|
+
|
5
8
|
HAS_VAR = /(\{\{|\<\<)[^\}\>]+(\}\}|\>\>)/
|
9
|
+
SELECT_FROM_REG = /SELECT.+FROM.+/
|
10
|
+
|
11
|
+
|
12
|
+
ALL_UNDERSCORE = /\A[_]+\Z/
|
13
|
+
COMBO_LEFT_RIGHT = [:left, :left, :right, :right]
|
14
|
+
COMBO_OUT_IN = [:out, :in, :out, :in]
|
6
15
|
|
7
16
|
Duplicate = Class.new RuntimeError
|
8
17
|
|
9
18
|
class << self
|
10
19
|
end # === class self ===
|
11
20
|
|
12
|
-
|
21
|
+
attr_reader :digs, :WITHS, :data
|
22
|
+
def initialize *args
|
23
|
+
@WITH = nil
|
24
|
+
@FRAGMENT = nil
|
25
|
+
@SQL = nil
|
26
|
+
@WITHS = []
|
13
27
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
28
|
+
@digs = []
|
29
|
+
@data = H.new(:allow_update)
|
30
|
+
.merge!(
|
31
|
+
:name => nil,
|
32
|
+
:raw => nil,
|
33
|
+
:vars => H.new,
|
34
|
+
:procs => H.new
|
35
|
+
)
|
18
36
|
|
19
|
-
|
20
|
-
if has_key?(name) && self[name] != val
|
21
|
-
fail ArgumentError, "Key already set: #{name.inspect}"
|
22
|
-
end
|
37
|
+
args.each { |a|
|
23
38
|
|
24
|
-
|
25
|
-
end
|
39
|
+
case a
|
26
40
|
|
27
|
-
|
28
|
-
|
29
|
-
h.each { |k,v|
|
30
|
-
self[k] = v
|
31
|
-
}
|
32
|
-
}
|
33
|
-
self
|
34
|
-
end
|
41
|
+
when Symbol
|
42
|
+
@data[:name] = a
|
35
43
|
|
36
|
-
|
44
|
+
when I_Dig_Sql
|
45
|
+
@digs << a
|
46
|
+
|
47
|
+
when String
|
48
|
+
@data.merge!(:raw=>a)
|
49
|
+
|
50
|
+
when Hash, H
|
51
|
+
if a.has_key?(:raw)
|
52
|
+
@data.merge! a
|
53
|
+
else
|
54
|
+
@data[:vars].merge! a
|
55
|
+
end
|
56
|
+
|
57
|
+
else
|
58
|
+
fail ArgumentError, "Unknown arg: #{a.inspect}"
|
59
|
+
|
60
|
+
end # === case
|
37
61
|
|
38
|
-
attr_reader :sqls, :vars
|
39
|
-
def initialize *args
|
40
|
-
@digs = args.select { |a|
|
41
|
-
a.is_a? I_Dig_Sql
|
42
62
|
}
|
43
63
|
|
44
|
-
|
45
|
-
|
64
|
+
end # === def initialize
|
65
|
+
|
66
|
+
%w{name raw vars}.each { |k|
|
67
|
+
eval <<-EOF.strip, nil, __FILE__, __LINE__
|
68
|
+
def #{k}
|
69
|
+
@data[:#{k}]
|
70
|
+
end
|
71
|
+
EOF
|
72
|
+
}
|
73
|
+
|
74
|
+
def vars!
|
75
|
+
vars = H.new.merge!(@data[:vars])
|
76
|
+
|
77
|
+
@digs.reverse.inject(vars) { |memo, dig|
|
78
|
+
if dig != self
|
79
|
+
memo.merge! dig.vars
|
80
|
+
end
|
81
|
+
memo
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def has_key? name
|
86
|
+
!!(search name)
|
87
|
+
end
|
46
88
|
|
47
|
-
|
48
|
-
|
89
|
+
def search name
|
90
|
+
fail ArgumentError, "No name specified: #{name.inspect}" if !name
|
91
|
+
return self if self.name == name
|
92
|
+
found = false
|
93
|
+
if @data[:procs].has_key?(name)
|
94
|
+
return @data[:procs][name]
|
95
|
+
end
|
49
96
|
|
50
|
-
@
|
97
|
+
@digs.reverse.detect { |d|
|
98
|
+
found = if d.name == name
|
99
|
+
d
|
100
|
+
elsif d.data[:procs].has_key?(name)
|
101
|
+
d.data[:procs][name]
|
102
|
+
else
|
103
|
+
d.digs.detect { |deep|
|
104
|
+
found = deep if deep.name == name
|
105
|
+
found = deep.data[:procs][name] if deep.data[:procs].has_key?(name)
|
106
|
+
found
|
107
|
+
}
|
108
|
+
end
|
109
|
+
}
|
110
|
+
found
|
51
111
|
end
|
52
112
|
|
53
113
|
def [] name
|
54
|
-
|
114
|
+
found = search(name)
|
115
|
+
fail ArgumentError, "SQL not found for: #{name.inspect}" unless found
|
116
|
+
found
|
55
117
|
end
|
56
118
|
|
57
119
|
def []= name, val
|
58
|
-
|
120
|
+
fail ArgumentError, "Name already taken: #{name.inspect}" if has_key?(name)
|
121
|
+
|
122
|
+
case val
|
123
|
+
when String
|
124
|
+
@digs << I_Dig_Sql.new(self, name, val)
|
125
|
+
|
126
|
+
when Hash, H
|
127
|
+
case
|
128
|
+
when val[:name] == :DEFAULT
|
129
|
+
@digs << I_Dig_Sql.new(:DEFAULT, val)
|
130
|
+
when val[:raw]
|
131
|
+
@data.merge! val
|
132
|
+
else
|
133
|
+
@digs << I_Dig_Sql.new(self, name, val)
|
134
|
+
end
|
135
|
+
|
136
|
+
when I_Dig_Sql
|
137
|
+
@digs << val
|
138
|
+
|
139
|
+
when Proc
|
140
|
+
@data[:procs][name] = val
|
141
|
+
|
142
|
+
else
|
143
|
+
fail ArgumentError, "Unknown class: #{name.inspect} -> #{val.class}"
|
144
|
+
|
145
|
+
end # === case
|
59
146
|
end
|
60
147
|
|
61
148
|
def each
|
149
|
+
digs = @digs.reverse
|
150
|
+
digs.unshift self
|
62
151
|
if block_given?
|
63
|
-
|
152
|
+
digs.each { |d| yield d.name, d }
|
64
153
|
else
|
65
|
-
|
154
|
+
digs.each
|
66
155
|
end
|
67
156
|
end
|
68
157
|
|
158
|
+
|
69
159
|
def << str
|
70
|
-
@
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
76
|
-
)
|
160
|
+
(@data[:raw] ||= "") << str
|
161
|
+
end
|
162
|
+
|
163
|
+
def has_raw?
|
164
|
+
!!(@data[:raw] && !@data[:raw].strip.empty?)
|
77
165
|
end
|
78
166
|
|
79
167
|
def to_pair
|
80
|
-
[to_sql, vars]
|
168
|
+
[to_sql, vars!]
|
169
|
+
end
|
170
|
+
|
171
|
+
def to_meta *args
|
172
|
+
compile *args
|
173
|
+
end
|
174
|
+
|
175
|
+
def to_sql *args
|
176
|
+
compile(*args)[:SQL]
|
177
|
+
end
|
178
|
+
|
179
|
+
%w{ FRAGMENT SQL }.each { |k|
|
180
|
+
eval <<-EOF.strip, nil, __FILE__, __LINE__ + 1
|
181
|
+
def #{k}
|
182
|
+
return @#{k} if @SQL
|
183
|
+
to_meta[:#{k}]
|
184
|
+
end
|
185
|
+
EOF
|
186
|
+
}
|
187
|
+
|
188
|
+
private # ==========================================
|
189
|
+
|
190
|
+
def prefix_raw sym
|
191
|
+
"raw_#{sym.to_s.split('_').first}".to_sym
|
81
192
|
end
|
82
193
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
194
|
+
def prefix sym
|
195
|
+
sym.to_s.split('_').first.to_sym
|
196
|
+
end
|
197
|
+
|
198
|
+
protected(
|
199
|
+
def table_name one, two = nil
|
200
|
+
if two
|
201
|
+
k = two
|
202
|
+
link_name = one
|
203
|
+
else
|
204
|
+
k = one
|
205
|
+
link_name = nil
|
206
|
+
end
|
207
|
+
|
208
|
+
case
|
209
|
+
when [:out_ftable, :in_ftable].include?(k)
|
210
|
+
"#{real_table}_#{ meta[prefix(k)] }_#{meta[k]}"
|
211
|
+
|
212
|
+
when link? && link_name && @data[link_name][:inner_join].include?(k)
|
213
|
+
"#{self.name}_#{@data[link_name][:name]}_#{k}"
|
214
|
+
|
215
|
+
else
|
216
|
+
fail ArgumentError, "Unknown key for table name: #{k.inspect}"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
) # === protected
|
220
|
+
|
221
|
+
#
|
222
|
+
# Examples:
|
223
|
+
#
|
224
|
+
# field :in, :owner_id
|
225
|
+
# field :screen_name, :screen_name
|
226
|
+
# field :in
|
227
|
+
# field :raw_in
|
228
|
+
#
|
229
|
+
protected(
|
230
|
+
def field *args
|
231
|
+
|
232
|
+
case args
|
233
|
+
when [:out], [:in]
|
234
|
+
"#{name}.#{data[args.last][:name]}"
|
235
|
+
when [:raw, :out], [:raw, :in]
|
236
|
+
"#{name}.#{self[:DEFAULT].data[args.last]}"
|
237
|
+
when [:owner_id], [:type_id]
|
238
|
+
"#{name}.#{args.first}"
|
239
|
+
else
|
240
|
+
fail ArgumentError, "Unknown args: #{args.inspect}"
|
241
|
+
end # === case
|
242
|
+
|
243
|
+
end # === def field
|
244
|
+
)
|
86
245
|
|
87
|
-
|
246
|
+
protected def compile target = nil
|
247
|
+
return(self[target].compile) if target && target != name
|
248
|
+
|
249
|
+
if !@SQL
|
250
|
+
compile_raw
|
251
|
+
end
|
252
|
+
|
253
|
+
{FRAGMENT: @FRAGMENT, SQL: @SQL, WITH: @WITH, VARS: vars!}
|
254
|
+
end # === def to_sql
|
255
|
+
|
256
|
+
def compile_raw
|
257
|
+
@data[:raw].freeze
|
258
|
+
|
259
|
+
s = @FRAGMENT = @data[:raw].dup
|
260
|
+
|
261
|
+
while s[HAS_VAR]
|
88
262
|
s.gsub!(/\{\{\s?([a-zA-Z0-9\_]+)\s?\}\}/) do |match|
|
89
263
|
key = $1.to_sym
|
90
|
-
|
264
|
+
@WITHS << key
|
91
265
|
key
|
92
266
|
end
|
93
267
|
|
94
268
|
s.gsub!(/\<\<\s?([a-zA-Z0-9\_\-\ \*]+)\s?\>\>/) do |match|
|
95
269
|
tokens = $1.split
|
96
|
-
key = tokens.pop.to_sym
|
97
|
-
field = tokens.empty? ? nil : tokens.join(' ')
|
98
270
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
271
|
+
key = tokens.last.to_sym
|
272
|
+
|
273
|
+
if has_key?(key)
|
274
|
+
|
275
|
+
tokens.pop
|
276
|
+
target = self[key]
|
277
|
+
|
278
|
+
if target.is_a?(Proc)
|
279
|
+
target.call self, *tokens
|
280
|
+
else
|
281
|
+
field = tokens.empty? ? nil : tokens.join(' ')
|
282
|
+
|
283
|
+
if field
|
284
|
+
@WITHS << key
|
285
|
+
tokens.pop
|
286
|
+
"SELECT #{field} FROM #{key}"
|
287
|
+
else
|
288
|
+
target.to_sql
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
elsif has_key?(tokens.first.to_sym)
|
293
|
+
self[tokens.shift.to_sym].call self, *tokens
|
294
|
+
|
103
295
|
else
|
104
|
-
|
105
|
-
|
296
|
+
fail ArgumentError, "Not found: #{$1}"
|
297
|
+
|
298
|
+
end # === if has_key?
|
106
299
|
end
|
300
|
+
end # === while s HAS_VAR
|
301
|
+
|
302
|
+
@WITH = if @WITHS.empty?
|
303
|
+
""
|
304
|
+
else
|
305
|
+
%^WITH\n #{WITH()}\n\n^
|
306
|
+
end
|
307
|
+
|
308
|
+
@SQL = (@WITH + @FRAGMENT).strip
|
309
|
+
end # === fragments_to_raw
|
310
|
+
|
311
|
+
def WITH
|
312
|
+
withs = @WITHS.dup
|
313
|
+
maps = []
|
314
|
+
done = {}
|
315
|
+
while name = withs.shift
|
316
|
+
next if done[name]
|
317
|
+
if name == :DEFAULT || !self.has_key?(name)
|
318
|
+
done[name] = true
|
319
|
+
next
|
320
|
+
end
|
321
|
+
|
322
|
+
fragment = self[name].FRAGMENT
|
323
|
+
fragment.gsub!(/^/, " ") if ENV['IS_DEV']
|
324
|
+
maps << "#{name} AS (\n#{fragment}\n )"
|
325
|
+
withs.concat self[name].WITHS
|
326
|
+
done[name] = true
|
327
|
+
end # === while name
|
328
|
+
|
329
|
+
maps.join ",\n "
|
330
|
+
end
|
331
|
+
|
332
|
+
def WHERE
|
333
|
+
wheres = @data[:WHERE].dup
|
334
|
+
|
335
|
+
if link? && name != :block
|
336
|
+
wheres << "#{field :type_id} = :#{name.to_s.upcase}_TYPE_ID"
|
337
|
+
|
338
|
+
pattern = [ data[:out][:inner_join], data[:in][:inner_join] ]
|
339
|
+
left, mid = data[:out][:inner_join]
|
340
|
+
right, _ = *data[:in][:inner_join]
|
341
|
+
|
342
|
+
|
343
|
+
case
|
344
|
+
when [[:screen_name], [:screen_name]], [[:screen_name, :computer],[:screen_name]]
|
345
|
+
# do nothing
|
346
|
+
else
|
347
|
+
fail "Programmer Error: Permissions not implemented for: #{pattern.inspect}"
|
348
|
+
end # === case
|
349
|
+
|
350
|
+
if left == :screen_name && right == :screen_name
|
351
|
+
default = self[:DEFAULT]
|
352
|
+
block = self[:block]
|
353
|
+
blocked = block.table_name(:out, :screen_name)
|
354
|
+
victim = block.table_name(:in, :screen_name)
|
355
|
+
f_in = table_name :in, :screen_name
|
356
|
+
f_out = table_name :out, :screen_name
|
357
|
+
|
358
|
+
wheres << %^
|
359
|
+
NOT EXISTS (
|
360
|
+
SELECT 1
|
361
|
+
FROM #{block.real_table} AS block
|
362
|
+
WHERE
|
363
|
+
(
|
364
|
+
block.type_id = :BLOCK_SCREEN_TYPE_ID
|
365
|
+
AND (
|
366
|
+
(
|
367
|
+
#{f_out}.owner_id = #{block.field :out}
|
368
|
+
AND
|
369
|
+
#{f_in}.owner_id = #{victim}.owner_id
|
370
|
+
)
|
371
|
+
OR
|
372
|
+
(
|
373
|
+
#{field :raw, :in} = #{block.field :out}
|
374
|
+
AND
|
375
|
+
#{blocked}.owner_id = #{victim}.owner_id
|
376
|
+
)
|
377
|
+
)
|
378
|
+
)
|
379
|
+
OR
|
380
|
+
(
|
381
|
+
block.type_id = :BLOCK_OWNER_TYPE_ID
|
382
|
+
AND (
|
383
|
+
(
|
384
|
+
#{f_out}.owner_id = #{blocked}.owner_id
|
385
|
+
AND
|
386
|
+
#{f_in}.owner_id = #{victim}.owner_id
|
387
|
+
)
|
388
|
+
OR
|
389
|
+
(
|
390
|
+
#{f_in}.owner_id = #{blocked}.owner_id
|
391
|
+
AND
|
392
|
+
#{f_out}.owner_id = #{victim}.owner_id
|
393
|
+
)
|
394
|
+
) -- AND
|
395
|
+
)
|
396
|
+
) -- NOT EXISTS
|
397
|
+
^
|
398
|
+
end # === if :screen_name, :screen_name
|
399
|
+
|
400
|
+
if mid == :computer
|
401
|
+
asql(wheres.last)
|
402
|
+
fail "COMPUTER not ready"
|
403
|
+
end
|
404
|
+
|
405
|
+
end # === if link?
|
406
|
+
|
407
|
+
if @data.has_key?(:OF)
|
408
|
+
table = self[@data[:FROM].first]
|
409
|
+
wheres << "#{table.field(:out)} = #{@data[:OF].first}"
|
107
410
|
end
|
108
411
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
412
|
+
if false && @data[:NOT_EXISTS]
|
413
|
+
block = self[meta[:not_exists]]
|
414
|
+
w = ""
|
415
|
+
w << %^ NOT EXISTS (\n^
|
416
|
+
w << %^ SELECT 1\n^
|
417
|
+
w << %^ FROM #{meta[:not_exists]}\n^
|
418
|
+
w << %^ WHERE\n^
|
419
|
+
|
420
|
+
conds = []
|
421
|
+
block[:where].each { |block_meta|
|
422
|
+
type_id = block_meta.first
|
423
|
+
c = ""
|
424
|
+
c << %^ (\n^
|
425
|
+
c << " #{field meta, block_meta[1][1], block_meta[1][2]} = #{field block, block_meta[2][1], block_meta[2][2]}\n"
|
426
|
+
c << " AND\n"
|
427
|
+
c << " #{meta[:not_exists]}.type_id = :#{type_id}_TYPE_ID\n"
|
428
|
+
c << " AND\n"
|
429
|
+
c << " #{field meta, block_meta[3][1], block_meta[3][2]} = #{field block, block_meta[4][1], block_meta[4][2]}\n"
|
430
|
+
c << %^ )\n^
|
431
|
+
conds << c
|
432
|
+
}
|
433
|
+
|
434
|
+
w << conds.join(" OR\n")
|
435
|
+
sql[:WHERE] << w
|
436
|
+
end
|
437
|
+
|
438
|
+
|
439
|
+
return nil if wheres.empty?
|
440
|
+
wheres.join " AND "
|
120
441
|
end
|
121
442
|
|
443
|
+
# === END: Rendering DSL ==========================================
|
444
|
+
|
122
445
|
end # === class I_Dig_Sql ===
|
123
446
|
|
124
447
|
|