epoxy 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/README.rdoc +1 -1
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/lib/epoxy.rb +49 -12
  5. data/test/test_epoxy.rb +27 -3
  6. metadata +5 -5
@@ -22,7 +22,7 @@
22
22
 
23
23
  Epoxy handles:
24
24
 
25
- * ?<name> for named binds
25
+ * ?<name> for named binds
26
26
  * ? for numbered binds
27
27
  * ?? for a *real* question mark
28
28
  * '?' for a *real* question mark
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/erikh/epoxy"
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.0
1
+ 0.3.1
@@ -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
- a = query.scan(%r{
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
- \?[a-zA-Z]+ (?# match a named bind )
53
+ \?#{LEGAL_NAMED_BIND} (?# match a named bind )
51
54
  |
52
55
  \?\?? (?# match one or two question marks )
53
56
  |
54
- [^-/'"?:]+ (?# match all characters except ' " ? - : and / )
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
- unless binds.empty?
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
@@ -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='test'",
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: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 0
10
- version: 0.3.0
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-12 00:00:00 -04:00
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/erikh/epoxy
69
+ homepage: http://github.com/RDBI/epoxy
70
70
  licenses: []
71
71
 
72
72
  post_install_message: