i_dig_sql 3.0.0 → 4.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 +25 -9
- data/VERSION +1 -1
- data/bin/i_dig_sql +76 -0
- data/i_dig_sql.gemspec +2 -1
- data/lib/i_dig_sql.rb +154 -409
- data/lib/i_dig_sql/string.rb +10 -0
- data/specs/0000-I_Dig_Sql.rb +124 -39
- data/specs/helpers.rb +13 -4
- metadata +20 -24
- data/bin/test +0 -47
- data/lib/i_dig_sql/String.rb +0 -8
- data/specs/0001-new.rb +0 -20
- data/specs/0010-vars.rb +0 -38
- data/specs/0011-to_pair.rb +0 -15
- data/specs/0020-to_sql.rb +0 -31
- data/specs/0030-funcs.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31d1e3efcf21763358024010c06ded12c96db386
|
4
|
+
data.tar.gz: 406fb62530629737bc65194b61f971d30d817963
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0d7425d98fd9de91ad8a03169215bfeb34c895d54fb8fd3bcca9e58746e7dd819f96928ed091934b60058ed2e4529eccb73105766fb0475ca08a3e3cca38e8c
|
7
|
+
data.tar.gz: 0d429c6906c64c71beaf531b34a88a51313ad5ce559db376bc6e79dc28890db099c9221d4ca575e71ffcaae500434f822e48eccf3a6f661397bfeaa83cb48e90
|
data/README.md
CHANGED
@@ -24,24 +24,40 @@ Please note that none of this is ready yet.
|
|
24
24
|
require 'i_dig_sql'
|
25
25
|
|
26
26
|
sql = I_Dig_Sql.new
|
27
|
-
sql
|
28
|
-
sql
|
29
|
-
|
27
|
+
sql.sql :HEROES, "SELECT id FROM hero WHERE id = :PERSON_ID"
|
28
|
+
sql.sql :VILLIANS, "SELECT id FROM villian WHERE id = :PERSON_ID"
|
29
|
+
|
30
|
+
sql.sql(:SIDE_KICKS) {
|
31
|
+
|
32
|
+
FROM :HEROES, :good_guys do
|
33
|
+
SELECT :nick_name, :name
|
34
|
+
end
|
35
|
+
|
36
|
+
INNER :PEOPLE, :others do
|
37
|
+
ON '_.heroe_id == __.id'
|
38
|
+
SELECT :nick_name, :name
|
39
|
+
end
|
40
|
+
|
41
|
+
SELECT 'field' => 'a_field'
|
42
|
+
|
43
|
+
GROUP_BY 'id DESC', 'created_at ASC'
|
44
|
+
|
45
|
+
}
|
46
|
+
|
47
|
+
sql.sql :SQL, %^
|
30
48
|
SELECT *
|
31
49
|
FROM people
|
32
50
|
WHERE
|
33
|
-
id IN ( << HEROES >> AND status = :ALIVE)
|
34
|
-
OR
|
35
51
|
id IN (SELECT ID FROM {{ HEROES }} AND status = :ALIVE)
|
36
52
|
OR
|
37
|
-
id IN (
|
53
|
+
id IN ( {{ HEROES * }} )
|
38
54
|
OR
|
39
|
-
id IN (
|
55
|
+
id IN ( {{ VILLIANS patron_id }} )
|
40
56
|
OR
|
41
|
-
id IN (
|
57
|
+
id IN ( {{ VILLIANS * }} )
|
42
58
|
^
|
43
59
|
|
44
|
-
sql.
|
60
|
+
puts sql.pair
|
45
61
|
|
46
62
|
```
|
47
63
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4.0.0
|
data/bin/i_dig_sql
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
# -*- bash -*-
|
3
|
+
#
|
4
|
+
#
|
5
|
+
|
6
|
+
action="$1"
|
7
|
+
shift
|
8
|
+
|
9
|
+
if [[ -z "$action" ]]; then
|
10
|
+
action="test"
|
11
|
+
fi
|
12
|
+
# ===============================================================
|
13
|
+
|
14
|
+
set -u -e -o pipefail
|
15
|
+
|
16
|
+
case "$action" in
|
17
|
+
|
18
|
+
"help")
|
19
|
+
echo " ====================================================="
|
20
|
+
echo ""
|
21
|
+
echo " $ i_dig_sql watch"
|
22
|
+
echo ""
|
23
|
+
echo " $ i_dig_sql test"
|
24
|
+
echo " $ i_dig_sql test name"
|
25
|
+
echo ""
|
26
|
+
echo " ====================================================="
|
27
|
+
echo ""
|
28
|
+
exit 0
|
29
|
+
;; # === start
|
30
|
+
|
31
|
+
"watch")
|
32
|
+
echo ""
|
33
|
+
echo "=== Watching: $@"
|
34
|
+
|
35
|
+
echo -e "\n=== Running test:"
|
36
|
+
bin/i_dig_sql test "$@" || echo ""
|
37
|
+
|
38
|
+
inotifywait -q -m -e close_write,close --exclude .git/ -r . | while read CHANGE
|
39
|
+
do
|
40
|
+
|
41
|
+
dir=$(echo "$CHANGE" | cut -d' ' -f 1)
|
42
|
+
op=$(echo "$CHANGE" | cut -d' ' -f 2)
|
43
|
+
file=$(echo "$CHANGE" | cut -d' ' -f 3)
|
44
|
+
path="${dir}$file"
|
45
|
+
|
46
|
+
if [[ "$op" == *CLOSE_WRITE* && ( $file == *.rb* || $file == *.md* ) ]]; then
|
47
|
+
echo -e "\n=== Running test:"
|
48
|
+
bin/i_dig_sql test "$@" || echo ""
|
49
|
+
fi
|
50
|
+
|
51
|
+
done # === do
|
52
|
+
|
53
|
+
echo ""
|
54
|
+
exit 0
|
55
|
+
;;
|
56
|
+
|
57
|
+
|
58
|
+
"test")
|
59
|
+
files="$(echo specs/*-$@.rb)"
|
60
|
+
if [[ -f "$files" ]]; then
|
61
|
+
shift
|
62
|
+
else
|
63
|
+
files="$(echo specs/*-*.rb)"
|
64
|
+
fi
|
65
|
+
|
66
|
+
bundle exec bacon -rpry -ri_dig_sql specs/helpers.rb $files "$@"
|
67
|
+
;; # === test
|
68
|
+
|
69
|
+
|
70
|
+
*)
|
71
|
+
echo "=== Unknown action: $action" 1>&2
|
72
|
+
exit 1
|
73
|
+
;;
|
74
|
+
|
75
|
+
esac # =========================================================
|
76
|
+
|
data/i_dig_sql.gemspec
CHANGED
@@ -21,12 +21,13 @@ 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_dependency "boxomojo" , "> 1.0.1"
|
25
|
+
|
24
26
|
spec.add_development_dependency "bundler" , "> 1.5"
|
25
27
|
spec.add_development_dependency "bacon" , '> 1.0'
|
26
28
|
spec.add_development_dependency "Bacon_Colored" , '> 0'
|
27
29
|
spec.add_development_dependency "pry" , '> 0'
|
28
30
|
spec.add_development_dependency "awesome_print" , '> 0'
|
29
|
-
spec.add_development_dependency "anbt-sql-formatter" , '> 0'
|
30
31
|
spec.add_development_dependency "rouge" , '> 0.0.0'
|
31
32
|
spec.add_development_dependency "unindent" , '> 0.0.0'
|
32
33
|
end
|
data/lib/i_dig_sql.rb
CHANGED
@@ -1,448 +1,193 @@
|
|
1
1
|
|
2
|
-
require "i_dig_sql/H"
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
include Enumerable
|
3
|
+
require 'i_dig_sql/H'
|
4
|
+
require 'boxomojo'
|
7
5
|
|
8
|
-
|
9
|
-
SELECT_FROM_REG = /SELECT.+FROM.+/
|
6
|
+
class I_Dig_Sql
|
10
7
|
|
8
|
+
Box = Boxomojo.new(
|
9
|
+
:SELECT,
|
10
|
+
:FROM, :LEFT, :RIGHT, :INNER,
|
11
|
+
:AS, :ON,
|
12
|
+
:GROUP_BY, :ORDER_BY
|
13
|
+
)
|
11
14
|
|
15
|
+
HAS_VAR = /(\{\{)[^\}\>]+(\}\})/
|
16
|
+
SELECT_FROM_REG = /SELECT.+FROM.+/
|
17
|
+
COMMAS_OR_COLONS = /(\,|\:)+/
|
12
18
|
ALL_UNDERSCORE = /\A[_]+\Z/
|
13
|
-
|
14
|
-
COMBO_OUT_IN = [:out, :in, :out, :in]
|
15
|
-
|
16
|
-
Duplicate = Class.new RuntimeError
|
19
|
+
NOTHING = "".freeze
|
17
20
|
|
18
21
|
class << self
|
19
|
-
end # === class self ===
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def box_to_string arr
|
24
|
+
h = {:SELECT=>[], :FROM=>[], :GROUP_BY=>[], :ORDER_BY=>[]}
|
25
|
+
table_name_stack = []
|
26
|
+
arr.each { |raw|
|
27
|
+
name, args, blok = raw
|
28
|
+
|
29
|
+
case name
|
30
|
+
when :SELECT
|
31
|
+
h[:SELECT] << args.join(' AS ')
|
32
|
+
|
33
|
+
when :FROM, :LEFT, :RIGHT, :INNER
|
34
|
+
table_name_stack.push args.last
|
35
|
+
str = if name == :FROM
|
36
|
+
args.join(' ')
|
37
|
+
else
|
38
|
+
"#{name} JOIN #{args.join ' '}"
|
39
|
+
end
|
40
|
+
|
41
|
+
table_name = args.last
|
42
|
+
|
43
|
+
if blok
|
44
|
+
on = []
|
45
|
+
blok.each { |raw|
|
46
|
+
args = raw.dup
|
47
|
+
name = args.shift
|
48
|
+
blok = args.pop
|
49
|
+
case name
|
50
|
+
when :ON
|
51
|
+
on << args
|
52
|
+
|
53
|
+
when :SELECT
|
54
|
+
h[:SELECT] << "#{table_name}.#{args.join ' AS '}"
|
27
55
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
:raw => nil,
|
33
|
-
:vars => H.new,
|
34
|
-
:procs => H.new
|
35
|
-
)
|
36
|
-
|
37
|
-
args.each { |a|
|
56
|
+
else
|
57
|
+
fail ArgumentError, "Unknown name: #{name.inspect}"
|
58
|
+
end
|
59
|
+
}
|
38
60
|
|
39
|
-
|
61
|
+
( str << "\nON " << on.join(' AND ') ) unless on.empty?
|
62
|
+
end
|
40
63
|
|
41
|
-
|
42
|
-
|
64
|
+
str.gsub!(/\b([_]+)(?=\.)/) { |match|
|
65
|
+
t_name = table_name_stack[match.size * -1]
|
66
|
+
fail ArgumentError, "Name not found for: #{match}" if !t_name
|
67
|
+
t_name
|
68
|
+
}
|
43
69
|
|
44
|
-
|
45
|
-
@digs << a
|
70
|
+
h[:FROM] << str
|
46
71
|
|
47
|
-
|
48
|
-
|
72
|
+
when :GROUP_BY, :ORDER_BY
|
73
|
+
h[name].concat args
|
49
74
|
|
50
|
-
when Hash, H
|
51
|
-
if a.has_key?(:raw)
|
52
|
-
@data.merge! a
|
53
75
|
else
|
54
|
-
|
76
|
+
fail ArgumentError, "Unknown: #{name.inspect}"
|
55
77
|
end
|
78
|
+
}
|
56
79
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
80
|
+
<<-EOF
|
81
|
+
SELECT
|
82
|
+
#{h[:SELECT].empty? ? '*' : h[:SELECT].join(",\n")}
|
83
|
+
FROM
|
84
|
+
#{h[:FROM].join "\n"}
|
85
|
+
#{ h[:GROUP_BY].empty? ? '' : 'GROUP BY ' + h[:GROUP_BY].join(', ')}
|
86
|
+
#{ h[:ORDER_BY].empty? ? '' : 'ORDER BY ' + h[:ORDER_BY].join(', ')}
|
87
|
+
EOF
|
88
|
+
end # === def box_to_string
|
89
|
+
|
90
|
+
#
|
91
|
+
# Examples:
|
92
|
+
# string( "...", dig)
|
93
|
+
# string( dig ) { FROM ... }
|
94
|
+
#
|
95
|
+
def string *args, &blok
|
96
|
+
dig = args.pop
|
97
|
+
str = args.shift || box_to_string(Box.new &blok)
|
98
|
+
s = str.dup
|
99
|
+
withs = []
|
100
|
+
|
101
|
+
while s[HAS_VAR]
|
102
|
+
s.gsub!(/\{\{\s?([^\}]+)\s?\}\}/) do |match|
|
103
|
+
pieces = $1.split
|
104
|
+
name = pieces.shift
|
105
|
+
key = name.to_sym
|
106
|
+
args = pieces
|
107
|
+
withs << key
|
108
|
+
withs.concat(dig.sql(key)[:withs]) if dig.sqls.has_key?(key)
|
109
|
+
case args.size
|
110
|
+
when 0
|
111
|
+
name
|
112
|
+
else
|
113
|
+
"SELECT #{args.join ', '} FROM #{name}"
|
114
|
+
end # === case
|
115
|
+
end
|
116
|
+
end # === while s HAS_VAR
|
117
|
+
|
118
|
+
with = if withs.empty?
|
119
|
+
""
|
120
|
+
else
|
121
|
+
maps = []
|
122
|
+
done = {}
|
123
|
+
withs.uniq!
|
124
|
+
withs.each { |name|
|
125
|
+
next if done[name]
|
126
|
+
fragment = dig.sql(name)[:base]
|
127
|
+
(fragment = fragment.gsub(/^/, " ")) if ENV['IS_DEV']
|
128
|
+
maps << "#{name} AS (\n#{fragment}\n )"
|
129
|
+
done[name] = true
|
130
|
+
} # === each withs
|
131
|
+
|
132
|
+
%^WITH\n #{maps.join ",\n "}\n\n^
|
133
|
+
end
|
134
|
+
|
135
|
+
[with + s, s, withs]
|
136
|
+
end # === def extract_withs
|
61
137
|
|
62
|
-
|
138
|
+
end # === class self ===
|
63
139
|
|
140
|
+
attr_reader :vars, :sqls
|
141
|
+
def initialize
|
142
|
+
@stack = []
|
143
|
+
@sqls = H.new
|
144
|
+
@vars = H.new
|
64
145
|
end # === def initialize
|
65
146
|
|
66
|
-
|
67
|
-
|
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
|
88
|
-
|
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
|
96
|
-
|
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
|
111
|
-
end
|
112
|
-
|
113
|
-
def [] name
|
114
|
-
found = search(name)
|
115
|
-
fail ArgumentError, "SQL not found for: #{name.inspect}" unless found
|
116
|
-
found
|
117
|
-
end
|
118
|
-
|
119
|
-
def []= name, val
|
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
|
147
|
+
def var name, *args
|
148
|
+
case args.size
|
141
149
|
|
142
|
-
|
143
|
-
|
150
|
+
when 0
|
151
|
+
@vars[name]
|
144
152
|
|
145
|
-
|
146
|
-
|
153
|
+
when 1
|
154
|
+
@vars[name] = args.first
|
147
155
|
|
148
|
-
def each
|
149
|
-
digs = @digs.reverse
|
150
|
-
digs.unshift self
|
151
|
-
if block_given?
|
152
|
-
digs.each { |d| yield d.name, d }
|
153
156
|
else
|
154
|
-
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
|
159
|
-
def << str
|
160
|
-
(@data[:raw] ||= "") << str
|
161
|
-
end
|
162
|
-
|
163
|
-
def has_raw?
|
164
|
-
!!(@data[:raw] && !@data[:raw].strip.empty?)
|
165
|
-
end
|
166
|
-
|
167
|
-
def to_pair
|
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
|
192
|
-
end
|
193
|
-
|
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
|
-
)
|
245
|
-
|
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]
|
262
|
-
s.gsub!(/\{\{\s?([a-zA-Z0-9\_]+)\s?\}\}/) do |match|
|
263
|
-
key = $1.to_sym
|
264
|
-
@WITHS << key
|
265
|
-
key
|
266
|
-
end
|
267
|
-
|
268
|
-
s.gsub!(/\<\<\s?([a-zA-Z0-9\_\-\ \*]+)\s?\>\>/) do |match|
|
269
|
-
tokens = $1.split
|
270
|
-
|
271
|
-
key = tokens.last.to_sym
|
157
|
+
fail ArgumentError, "Unknown args: #{args.inspect}"
|
272
158
|
|
273
|
-
|
159
|
+
end # === case
|
160
|
+
end # === def var
|
274
161
|
|
275
|
-
|
276
|
-
|
162
|
+
# Example:
|
163
|
+
# sql(:name)
|
164
|
+
# sql(:name, 'string')
|
165
|
+
# sql(:name) { FROM ... }
|
166
|
+
#
|
167
|
+
def sql name, *args, &blok
|
168
|
+
case
|
277
169
|
|
278
|
-
|
279
|
-
|
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
|
170
|
+
when args.size == 0 && !block_given?
|
171
|
+
@sqls[name]
|
291
172
|
|
292
|
-
|
293
|
-
|
173
|
+
when (args.size == 0 && block_given?) || args.size == 1
|
174
|
+
@sqls[name] = H.new
|
175
|
+
@sqls[name][:complete], @sqls[name][:base], @sqls[name][:withs] = I_Dig_Sql.string(*(args), self, &blok)
|
294
176
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
end # === if has_key?
|
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}"
|
410
|
-
end
|
411
|
-
|
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
|
-
}
|
177
|
+
else
|
178
|
+
fail ArgumentError, "Unknown args: #{args.inspect}"
|
433
179
|
|
434
|
-
|
435
|
-
|
436
|
-
end
|
180
|
+
end # === case
|
181
|
+
end # === def sql
|
437
182
|
|
183
|
+
def pair name = :SQL, vars = {}
|
184
|
+
@vars.freeze unless @vars.frozen?
|
185
|
+
[sql(name)[:complete], @vars.merge(vars)]
|
186
|
+
end # === def to_sql
|
438
187
|
|
439
|
-
|
440
|
-
wheres.join " AND "
|
441
|
-
end
|
188
|
+
end # === class I_Dig_Sql ===
|
442
189
|
|
443
|
-
# === END: Rendering DSL ==========================================
|
444
190
|
|
445
|
-
end # === class I_Dig_Sql ===
|
446
191
|
|
447
192
|
|
448
193
|
|
data/specs/0000-I_Dig_Sql.rb
CHANGED
@@ -2,39 +2,36 @@
|
|
2
2
|
|
3
3
|
describe :I_Dig_Sql do
|
4
4
|
|
5
|
+
it "runs" do
|
6
|
+
dig = I_Dig_Sql.new
|
7
|
+
dig.sql :heroes do
|
8
|
+
FROM(:tbl, :heroes) {
|
9
|
+
SELECT(:nickname, :name)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
sql(dig.sql(:heroes)).should == sql("SELECT heroes.nickname AS name FROM tbl heroes")
|
14
|
+
end # === it
|
15
|
+
|
5
16
|
it "runs the code from README.md" do
|
6
17
|
readme = File.read(File.expand_path(File.dirname(__FILE__) + '/../README.md'))
|
7
|
-
code = readme[/```ruby([^`]+)```/] && $1
|
18
|
+
code = (readme[/```ruby([^`]+)```/] && $1).split("\n").map { |l| l.sub('puts ', '') }.join("\n")
|
8
19
|
line = 0
|
9
20
|
readme.split("\n").detect { |l| line = line + 1; l['```ruby'] }
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
HEROES AS ( SELECT id FROM hero WHERE id = :PERSON_ID ),
|
14
|
-
VILLIANS AS ( SELECT id FROM villian WHERE id = :PERSON_ID )
|
15
|
-
SELECT * FROM people
|
16
|
-
WHERE
|
17
|
-
id IN ( SELECT id FROM hero WHERE id = :PERSON_ID AND status = :ALIVE)
|
18
|
-
OR
|
19
|
-
id IN (SELECT ID FROM HEROES AND status = :ALIVE)
|
20
|
-
OR
|
21
|
-
id IN ( SELECT * FROM HEROES )
|
22
|
-
OR
|
23
|
-
id IN ( SELECT patron_id FROM VILLIANS )
|
24
|
-
OR
|
25
|
-
id IN ( SELECT id FROM villian WHERE id = :PERSON_ID )
|
26
|
-
^)
|
21
|
+
should.not.raise {
|
22
|
+
eval(code, nil, 'README.md', line)
|
23
|
+
}
|
27
24
|
end # === it
|
28
25
|
|
29
26
|
it "adds WITH: {{MY_NAME}}" do
|
30
27
|
sql = I_Dig_Sql.new
|
31
|
-
sql
|
32
|
-
sql
|
33
|
-
sql
|
28
|
+
sql.sql :MY_HERO, "SELECT * FROM hero"
|
29
|
+
sql.sql :MY_NAME, "SELECT * FROM name"
|
30
|
+
sql.sql :SQL, %^
|
34
31
|
{{MY_HERO}}
|
35
32
|
{{MY_NAME}}
|
36
33
|
^
|
37
|
-
sql(sql).should == sql(%^
|
34
|
+
sql(sql.sql :SQL).should == sql(%^
|
38
35
|
WITH
|
39
36
|
MY_HERO AS (
|
40
37
|
SELECT * FROM hero
|
@@ -47,25 +44,16 @@ describe :I_Dig_Sql do
|
|
47
44
|
^)
|
48
45
|
end
|
49
46
|
|
50
|
-
it "replaces text with content: << MY_NAME >>" do
|
51
|
-
sql = I_Dig_Sql.new
|
52
|
-
sql[:MY_HERO] = "SELECT * FROM hero"
|
53
|
-
sql << %^
|
54
|
-
<< MY_HERO >>
|
55
|
-
^
|
56
|
-
sql(sql).should == "SELECT * FROM hero"
|
57
|
-
end # === it
|
58
|
-
|
59
47
|
%w{ * id }.each { |s|
|
60
|
-
it "adds WITH:
|
48
|
+
it "adds WITH: {{ MY_NAME #{s} }}" do
|
61
49
|
sql = I_Dig_Sql.new
|
62
|
-
sql
|
63
|
-
sql
|
64
|
-
sql
|
65
|
-
|
66
|
-
|
50
|
+
sql.sql :MY_HERO, "SELECT id, p_id FROM hero"
|
51
|
+
sql.sql :MY_NAME, "SELECT id, n_id FROM name"
|
52
|
+
sql.sql :SQL, %^
|
53
|
+
{{ MY_NAME #{s} }}
|
54
|
+
{{ MY_HERO #{s} }}
|
67
55
|
^
|
68
|
-
sql(sql).should == sql(%^
|
56
|
+
sql(sql.sql :SQL).should == sql(%^
|
69
57
|
WITH
|
70
58
|
MY_NAME AS (
|
71
59
|
SELECT id, n_id FROM name
|
@@ -77,8 +65,105 @@ describe :I_Dig_Sql do
|
|
77
65
|
SELECT #{s} FROM MY_HERO
|
78
66
|
^)
|
79
67
|
end # === it
|
80
|
-
|
68
|
+
|
69
|
+
it "replaces text with content: {{ MY_NAME #{s} }}" do
|
70
|
+
sql = I_Dig_Sql.new
|
71
|
+
sql.sql :MY_HERO, "SELECT * FROM hero"
|
72
|
+
sql.sql :SQL, " {{ MY_HERO #{s} }} "
|
73
|
+
sql(sql.sql :SQL).should == "WITH MY_HERO AS ( SELECT * FROM hero ) SELECT #{s} FROM MY_HERO"
|
74
|
+
end # === it
|
75
|
+
} # === %w{}
|
76
|
+
|
77
|
+
it "renders nested replacements" do
|
78
|
+
i = I_Dig_Sql.new
|
79
|
+
i.sql :THIRD, "SELECT id FROM phantom"
|
80
|
+
i.sql :SECOND, " {{ THIRD }} "
|
81
|
+
i.sql :FIRST, " {{ SECOND }} "
|
82
|
+
i.sql :SQL, " {{ FIRST }} "
|
83
|
+
sql(i.sql :SQL).should == sql(
|
84
|
+
<<-EOF
|
85
|
+
WITH
|
86
|
+
FIRST AS ( SECOND ),
|
87
|
+
SECOND AS ( THIRD ),
|
88
|
+
THIRD AS ( SELECT id FROM phantom )
|
89
|
+
FIRST
|
90
|
+
EOF
|
91
|
+
)
|
92
|
+
end # === it
|
93
|
+
|
94
|
+
it "prints CTE definitions once, if used multiple times" do
|
95
|
+
i = I_Dig_Sql.new
|
96
|
+
i.sql :my_cte, "SELECT * FROM my"
|
97
|
+
i.sql :SQL, <<-EOF
|
98
|
+
{{my_cte}}
|
99
|
+
{{my_cte}}
|
100
|
+
EOF
|
101
|
+
sql(i.sql :SQL).should == sql(%^
|
102
|
+
WITH
|
103
|
+
my_cte AS (
|
104
|
+
SELECT * FROM my
|
105
|
+
)
|
106
|
+
my_cte
|
107
|
+
my_cte
|
108
|
+
^)
|
109
|
+
end # === it
|
81
110
|
|
82
111
|
end # === describe :I_Dig_Sql
|
83
112
|
|
84
113
|
|
114
|
+
describe ":pair" do
|
115
|
+
|
116
|
+
it "returns an array of: [string, hash]" do
|
117
|
+
s = "select * from THE_WORLD"
|
118
|
+
i = I_Dig_Sql.new
|
119
|
+
i.sql :SQL, s
|
120
|
+
i.pair(:SQL).should == [s, {}]
|
121
|
+
end # === it
|
122
|
+
|
123
|
+
it "merges the hash passed to it" do
|
124
|
+
s = "select * from THE_UNI"
|
125
|
+
i = I_Dig_Sql.new
|
126
|
+
i.sql :SQL, s
|
127
|
+
i.pair(:SQL, {:a=>:b}).should == [s, {:a=>:b}]
|
128
|
+
end # === it
|
129
|
+
|
130
|
+
it "does not save :vars passed to it" do
|
131
|
+
s = "select * from THE_UNI"
|
132
|
+
i = I_Dig_Sql.new
|
133
|
+
i.sql :SQL, s
|
134
|
+
i.pair(:SQL, {:a=>:b})
|
135
|
+
i.vars.should == {}
|
136
|
+
end # === it
|
137
|
+
|
138
|
+
end # === describe pair
|
139
|
+
|
140
|
+
|
141
|
+
describe ":box" do
|
142
|
+
|
143
|
+
it "turns a box into a String" do
|
144
|
+
sql = I_Dig_Sql.new
|
145
|
+
sql.sql :joins do
|
146
|
+
|
147
|
+
FROM(:n, :notes) {
|
148
|
+
SELECT(:long_name, :name)
|
149
|
+
}
|
150
|
+
|
151
|
+
LEFT(:f, :fails) {
|
152
|
+
ON('_.n = __.n')
|
153
|
+
SELECT(:long_name, :name)
|
154
|
+
}
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
sql(sql.sql :joins).should == sql(%^
|
159
|
+
SELECT
|
160
|
+
notes.long_name AS name,
|
161
|
+
fails.long_name AS name
|
162
|
+
FROM
|
163
|
+
n notes
|
164
|
+
LEFT JOIN f fails
|
165
|
+
ON fails.n = notes.n
|
166
|
+
^)
|
167
|
+
end # === it
|
168
|
+
|
169
|
+
end # === describe ":box"
|
data/specs/helpers.rb
CHANGED
@@ -41,11 +41,20 @@ module Kernel
|
|
41
41
|
end # === module Kernel
|
42
42
|
|
43
43
|
def sql o
|
44
|
-
|
45
|
-
|
44
|
+
case o
|
45
|
+
when String
|
46
|
+
o.split.join(" ")
|
47
|
+
|
48
|
+
when I_Dig_Sql::H
|
49
|
+
sql o[:complete]
|
50
|
+
|
51
|
+
when Array
|
52
|
+
sql o.first
|
53
|
+
|
46
54
|
else
|
47
55
|
sql(o.to_sql)
|
48
|
-
|
49
|
-
end
|
56
|
+
|
57
|
+
end # === case
|
58
|
+
end # === def sql
|
50
59
|
|
51
60
|
|
metadata
CHANGED
@@ -1,59 +1,59 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i_dig_sql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- da99
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: boxomojo
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
type: :
|
19
|
+
version: 1.0.1
|
20
|
+
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.0.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.5'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: bacon
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
47
|
+
version: '1.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
54
|
+
version: '1.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: Bacon_Colored
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">"
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">"
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: awesome_print
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">"
|
@@ -127,7 +127,8 @@ description: "\n You probably want another gem: arel. Use that\n to generate S
|
|
127
127
|
\ "
|
128
128
|
email:
|
129
129
|
- i-hate-spam-1234567@mailinator.com
|
130
|
-
executables:
|
130
|
+
executables:
|
131
|
+
- i_dig_sql
|
131
132
|
extensions: []
|
132
133
|
extra_rdoc_files: []
|
133
134
|
files:
|
@@ -137,17 +138,12 @@ files:
|
|
137
138
|
- README.md
|
138
139
|
- Rakefile
|
139
140
|
- VERSION
|
140
|
-
- bin/
|
141
|
+
- bin/i_dig_sql
|
141
142
|
- i_dig_sql.gemspec
|
142
143
|
- lib/i_dig_sql.rb
|
143
144
|
- lib/i_dig_sql/H.rb
|
144
|
-
- lib/i_dig_sql/
|
145
|
+
- lib/i_dig_sql/string.rb
|
145
146
|
- specs/0000-I_Dig_Sql.rb
|
146
|
-
- specs/0001-new.rb
|
147
|
-
- specs/0010-vars.rb
|
148
|
-
- specs/0011-to_pair.rb
|
149
|
-
- specs/0020-to_sql.rb
|
150
|
-
- specs/0030-funcs.rb
|
151
147
|
- specs/helpers.rb
|
152
148
|
homepage: https://github.com/da99/i_dig_sql
|
153
149
|
licenses:
|
@@ -169,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
165
|
version: '0'
|
170
166
|
requirements: []
|
171
167
|
rubyforge_project:
|
172
|
-
rubygems_version: 2.4.
|
168
|
+
rubygems_version: 2.4.6
|
173
169
|
signing_key:
|
174
170
|
specification_version: 4
|
175
171
|
summary: Yet another way of generating Postgresql 9.2+ in Ruby.
|
data/bin/test
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
# -*- bash -*-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
x="$1"
|
6
|
-
set -u -e -o pipefail
|
7
|
-
|
8
|
-
if [[ "$x" == "watch" ]]; then
|
9
|
-
shift
|
10
|
-
|
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 "$@"
|
46
|
-
|
47
|
-
|
data/lib/i_dig_sql/String.rb
DELETED
data/specs/0001-new.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe '.new' do
|
4
|
-
|
5
|
-
it "merges sql values: .new(i_dig_sql)" do
|
6
|
-
first = I_Dig_Sql.new
|
7
|
-
first[:hero] = "SELECT * FROM hero"
|
8
|
-
second = I_Dig_Sql.new(first)
|
9
|
-
second[:name] = "SELECT * FROM name"
|
10
|
-
second << %^
|
11
|
-
<< hero >>
|
12
|
-
<< name >>
|
13
|
-
^
|
14
|
-
sql(second).should == sql(%^
|
15
|
-
SELECT * FROM hero
|
16
|
-
SELECT * FROM name
|
17
|
-
^)
|
18
|
-
end # === it
|
19
|
-
|
20
|
-
end # === describe '.new'
|
data/specs/0010-vars.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
|
2
|
-
describe :vars do
|
3
|
-
|
4
|
-
it "combines vars from other digs" do
|
5
|
-
one = I_Dig_Sql.new
|
6
|
-
one.vars[:one] = 1
|
7
|
-
|
8
|
-
two = I_Dig_Sql.new
|
9
|
-
one.vars[:two] = 2
|
10
|
-
|
11
|
-
three = I_Dig_Sql.new
|
12
|
-
one.vars[:three] = 3
|
13
|
-
|
14
|
-
dig = I_Dig_Sql.new one, two, three
|
15
|
-
dig.vars[:four] = 4
|
16
|
-
|
17
|
-
dig.vars!.should == {
|
18
|
-
four: 4,
|
19
|
-
three: 3,
|
20
|
-
two: 2,
|
21
|
-
one: 1
|
22
|
-
}
|
23
|
-
end # === it
|
24
|
-
|
25
|
-
it "fails w/Duplicate if other digs have the same var name" do
|
26
|
-
should.raise(ArgumentError) {
|
27
|
-
one = I_Dig_Sql.new
|
28
|
-
one.vars[:two] = 2
|
29
|
-
|
30
|
-
i = I_Dig_Sql.new one
|
31
|
-
i.vars[:two] = 3
|
32
|
-
i.vars!
|
33
|
-
}.message.should.match /Key already set: :two/
|
34
|
-
end # === it
|
35
|
-
|
36
|
-
end # === describe :vars
|
37
|
-
|
38
|
-
|
data/specs/0011-to_pair.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
|
2
|
-
describe :to_pair do
|
3
|
-
|
4
|
-
it "returns an Array: [String, Hash]" do
|
5
|
-
i = I_Dig_Sql.new <<-EOF
|
6
|
-
SELECT * FROM new
|
7
|
-
EOF
|
8
|
-
i.vars[:one] = 2
|
9
|
-
sql, vars = i.to_pair
|
10
|
-
sql(sql).should == sql("SELECT * FROM new")
|
11
|
-
vars.should == {one: 2}
|
12
|
-
end # === it
|
13
|
-
|
14
|
-
end # === describe :to_pair
|
15
|
-
|
data/specs/0020-to_sql.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe :to_sql do
|
4
|
-
|
5
|
-
it "renders nested replacements" do
|
6
|
-
i = I_Dig_Sql.new <<-EOF
|
7
|
-
<< FIRST >>
|
8
|
-
EOF
|
9
|
-
i[:FIRST] = " << SECOND >> "
|
10
|
-
i[:SECOND] = " << THIRD >> "
|
11
|
-
i[:THIRD] = "SELECT id FROM phantom"
|
12
|
-
sql(i).should == "SELECT id FROM phantom"
|
13
|
-
end # === it
|
14
|
-
|
15
|
-
it "prints CTE definitions once, if used multiple times" do
|
16
|
-
i = I_Dig_Sql.new <<-EOF
|
17
|
-
{{my_cte}}
|
18
|
-
{{my_cte}}
|
19
|
-
EOF
|
20
|
-
i[:my_cte] = "SELECT * FROM my"
|
21
|
-
sql(i).should == sql(%^
|
22
|
-
WITH
|
23
|
-
my_cte AS (
|
24
|
-
SELECT * FROM my
|
25
|
-
)
|
26
|
-
my_cte
|
27
|
-
my_cte
|
28
|
-
^)
|
29
|
-
end # === it
|
30
|
-
|
31
|
-
end # === describe :to_sql
|
data/specs/0030-funcs.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
|
2
|
-
describe :funcs do
|
3
|
-
|
4
|
-
it "let's you use a lambda in a SQL fragment" do
|
5
|
-
sql = I_Dig_Sql.new :q, <<-EOF
|
6
|
-
SELECT name
|
7
|
-
FROM screen_name
|
8
|
-
WHERE
|
9
|
-
<< id >>
|
10
|
-
EOF
|
11
|
-
|
12
|
-
sql[:id] = lambda { |dig| "id = :id" }
|
13
|
-
|
14
|
-
sql(sql).should == sql(%^
|
15
|
-
SELECT name
|
16
|
-
FROM screen_name
|
17
|
-
WHERE
|
18
|
-
id = :id
|
19
|
-
^)
|
20
|
-
end # === it
|
21
|
-
|
22
|
-
it "passes args to function" do
|
23
|
-
sql = I_Dig_Sql.new :q, <<-EOF
|
24
|
-
SELECT name
|
25
|
-
FROM screen_name
|
26
|
-
WHERE
|
27
|
-
<< names Hans Hoppe >>
|
28
|
-
EOF
|
29
|
-
|
30
|
-
sql[:names] = lambda { |dig, *args| "name IN [#{args.join ', '}]" }
|
31
|
-
|
32
|
-
sql(sql).should == sql(%^
|
33
|
-
SELECT name
|
34
|
-
FROM screen_name
|
35
|
-
WHERE
|
36
|
-
name IN [Hans, Hoppe]
|
37
|
-
^)
|
38
|
-
end # === it
|
39
|
-
|
40
|
-
end # === describe :funcs
|