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.
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: