epoxy 0.3.0 → 0.3.1
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.
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/epoxy.rb +49 -12
- data/test/test_epoxy.rb +27 -3
- metadata +5 -5
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ begin
|
|
8
8
|
gem.summary = %Q{A binding API for query languages that does not depend on any specific database.}
|
9
9
|
gem.description = %Q{Parse binds in SQL or any other data query language, quote, even configure for client-side binding. It all works!}
|
10
10
|
gem.email = "erik@hollensbe.org"
|
11
|
-
gem.homepage = "http://github.com/
|
11
|
+
gem.homepage = "http://github.com/RDBI/epoxy"
|
12
12
|
gem.authors = ["Erik Hollensbe"]
|
13
13
|
gem.add_development_dependency 'rdoc'
|
14
14
|
gem.add_development_dependency 'test-unit'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/lib/epoxy.rb
CHANGED
@@ -30,6 +30,9 @@
|
|
30
30
|
# * not telling you how to quote your data. This solution works for any query language and any database.
|
31
31
|
#
|
32
32
|
class Epoxy
|
33
|
+
|
34
|
+
LEGAL_NAMED_BIND = /[a-zA-Z]+/
|
35
|
+
|
33
36
|
#
|
34
37
|
# Token parser, isolates components of the query into parts to where they
|
35
38
|
# can be managed indepdently.
|
@@ -37,7 +40,7 @@ class Epoxy
|
|
37
40
|
# Probably not the easiest thing to deal with by itself. Use the standard
|
38
41
|
# methods plox.
|
39
42
|
def self.parse_tokens(query, comment_chars)
|
40
|
-
|
43
|
+
query.scan(%r{
|
41
44
|
(
|
42
45
|
#{comment_chars}.* (?# matches "--" style comments to the end of line or string )
|
43
46
|
|
|
@@ -47,11 +50,11 @@ class Epoxy
|
|
47
50
|
|
|
48
51
|
['"] (?# match a loose quote )
|
49
52
|
|
|
50
|
-
|
53
|
+
\?#{LEGAL_NAMED_BIND} (?# match a named bind )
|
51
54
|
|
|
52
55
|
\?\?? (?# match one or two question marks )
|
53
56
|
|
|
54
|
-
[
|
57
|
+
[^'"?]+ (?# match all characters except ' " ? - : and / )
|
55
58
|
)
|
56
59
|
}x).collect(&:first)
|
57
60
|
end
|
@@ -95,15 +98,7 @@ class Epoxy
|
|
95
98
|
result = ""
|
96
99
|
bind_pos = 0
|
97
100
|
|
98
|
-
|
99
|
-
tokens.each do |token|
|
100
|
-
binds.each do |key, rep|
|
101
|
-
if token == "?#{key}"
|
102
|
-
token.replace block.call(key.to_sym)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
101
|
+
binds = binds.keys.inject({}) { |x,y| x.merge({ y.kind_of?(String) ? y.to_sym : y => binds[y] }) }
|
107
102
|
|
108
103
|
tokens.each do |part|
|
109
104
|
case part
|
@@ -112,6 +107,14 @@ class Epoxy
|
|
112
107
|
bind_pos += 1
|
113
108
|
when '??'
|
114
109
|
result << "?"
|
110
|
+
when /^\?(#{LEGAL_NAMED_BIND})$/
|
111
|
+
key = $1.to_sym
|
112
|
+
if binds.has_key?(key)
|
113
|
+
result << block.call(key)
|
114
|
+
bind_pos += 1
|
115
|
+
else
|
116
|
+
result << part
|
117
|
+
end
|
115
118
|
else
|
116
119
|
result << part
|
117
120
|
end
|
@@ -119,6 +122,40 @@ class Epoxy
|
|
119
122
|
|
120
123
|
return result
|
121
124
|
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# Returns a hash of position => name (as Symbol), if any, which correspond to
|
128
|
+
# binds located in the query. nil is provided as a name if it is an indexed
|
129
|
+
# bind already. This is useful for sanitizing features Epoxy has before
|
130
|
+
# sending them to the SQL engine.
|
131
|
+
#
|
132
|
+
# Ex:
|
133
|
+
# ep = Epoxy.new("select * from foo where bar=?bar and quux=? and foomatic=?foo")
|
134
|
+
# ep.indexed_binds
|
135
|
+
#
|
136
|
+
# # yields...
|
137
|
+
# [ :bar, nil, :foo]
|
138
|
+
#
|
139
|
+
# *NOTE:* all syntax lookalikes are considered in this method; in
|
140
|
+
# the actual quote() routine, only named binds with a corresponding map are
|
141
|
+
# considered.
|
142
|
+
#
|
143
|
+
def indexed_binds
|
144
|
+
ary = []
|
145
|
+
|
146
|
+
tokens.each do |toke|
|
147
|
+
case toke
|
148
|
+
when '?'
|
149
|
+
ary.push(toke)
|
150
|
+
when /\?(#{LEGAL_NAMED_BIND})/
|
151
|
+
ary.push($1.to_sym)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
ary.map! { |x| x == '?' ? nil : x }
|
156
|
+
|
157
|
+
return ary
|
158
|
+
end
|
122
159
|
end
|
123
160
|
|
124
161
|
# vim: syntax=ruby ts=2 et sw=2 sts=2
|
data/test/test_epoxy.rb
CHANGED
@@ -151,7 +151,7 @@ class TestEpoxy < Test::Unit::TestCase
|
|
151
151
|
end
|
152
152
|
|
153
153
|
def test_06_named_binds
|
154
|
-
binds = { 0 => "test", :foo => 'bar', "bar" => 'baz', "void" => 'unused' }
|
154
|
+
binds = { 0 => "test", 1 => "test2", :foo => 'bar', "bar" => 'baz', "void" => 'unused' }
|
155
155
|
yarrr = proc { |x| "'#{binds[x] || binds[x.to_s]}'" }
|
156
156
|
|
157
157
|
ep = Epoxy.new("select * from 'foo' where bar=?foo and baz=?bar")
|
@@ -168,7 +168,7 @@ class TestEpoxy < Test::Unit::TestCase
|
|
168
168
|
|
169
169
|
ep = Epoxy.new("select * from 'foo' where bar=?foo and baz=?")
|
170
170
|
assert_equal(
|
171
|
-
"select * from 'foo' where bar='bar' and baz='
|
171
|
+
"select * from 'foo' where bar='bar' and baz='test2'",
|
172
172
|
ep.quote(binds, &yarrr)
|
173
173
|
)
|
174
174
|
|
@@ -201,8 +201,32 @@ class TestEpoxy < Test::Unit::TestCase
|
|
201
201
|
"select * from 'foo' where bar=?notfound",
|
202
202
|
ep.quote(binds, &yarrr)
|
203
203
|
)
|
204
|
-
end
|
205
204
|
|
205
|
+
ep = Epoxy.new("select * from 'foo' where bar=?foo and baz = ?")
|
206
|
+
assert_equal(
|
207
|
+
"select * from 'foo' where bar='bar' and baz = 'test2'",
|
208
|
+
ep.quote(binds, &yarrr)
|
209
|
+
)
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_07_indexed_binds
|
213
|
+
ep = Epoxy.new("select * from foo where bar=?bar and quux=? and foomatic=?foo")
|
214
|
+
assert_equal(
|
215
|
+
[ :bar, nil, :foo ],
|
216
|
+
ep.indexed_binds
|
217
|
+
)
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_08_meta_blackhole
|
221
|
+
str = "select 'some time'::TIMESTAMP"
|
222
|
+
|
223
|
+
ep = Epoxy.new "select 'some time'::TIMESTAMP"
|
224
|
+
|
225
|
+
assert_equal(
|
226
|
+
str,
|
227
|
+
ep.quote
|
228
|
+
)
|
229
|
+
end
|
206
230
|
end
|
207
231
|
|
208
232
|
# vim: syntax=ruby ts=2 et sw=2 sts=2
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: epoxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Erik Hollensbe
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-07-
|
18
|
+
date: 2010-07-15 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -66,7 +66,7 @@ files:
|
|
66
66
|
- test/helper.rb
|
67
67
|
- test/test_epoxy.rb
|
68
68
|
has_rdoc: true
|
69
|
-
homepage: http://github.com/
|
69
|
+
homepage: http://github.com/RDBI/epoxy
|
70
70
|
licenses: []
|
71
71
|
|
72
72
|
post_install_message:
|