sequel_core 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,20 +6,12 @@ context "Blockless Ruby Filters" do
6
6
  db.quote_identifiers = false
7
7
  @d = db[:items]
8
8
  def @d.l(*args, &block)
9
- if block_given?
10
- literal(filter_expr(Proc.new(&block)))
11
- else
12
- literal(filter_expr(*args))
13
- end
9
+ literal(filter_expr(*args, &block))
14
10
  end
15
11
  def @d.lit(*args)
16
12
  literal(*args)
17
13
  end
18
14
  end
19
-
20
- after do
21
- Sequel.use_parse_tree = true
22
- end
23
15
 
24
16
  it "should support boolean columns directly" do
25
17
  @d.l(:x).should == 'x'
@@ -300,7 +292,7 @@ context "Blockless Ruby Filters" do
300
292
  @d.lit([:x, :z].sql_string_join(' ') + :y).should == "((x || ' ' || z) || y)"
301
293
  end
302
294
 
303
- it "should be supported inside blocks if Sequel.use_parse_tree = false" do
295
+ it "should be supported inside blocks" do
304
296
  @d.l{[[:x, nil], [:y, [1,2,3]]].sql_or}.should == '((x IS NULL) OR (y IN (1, 2, 3)))'
305
297
  @d.l{~[[:x, nil], [:y, [1,2,3]]]}.should == '((x IS NOT NULL) OR (y NOT IN (1, 2, 3)))'
306
298
  @d.l{~(((('x'.lit - :y)/(:x + :y))*:z) <= 100)}.should == '((((x - y) / (x + y)) * z) > 100)'
@@ -71,6 +71,11 @@ describe Sequel::Dataset, " graphing" do
71
71
  ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON ((lines.x = points.id) AND (lines.y = points.id))'
72
72
  end
73
73
 
74
+ it "#graph should accept a block instead of conditions and pass it to join_table" do
75
+ ds = @ds1.graph(@ds2){|ja, lja, js| [[:x.qualify(ja), :id.qualify(lja)], [:y.qualify(ja), :id.qualify(lja)]]}
76
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON ((lines.x = points.id) AND (lines.y = points.id))'
77
+ end
78
+
74
79
  it "#graph should not add columns if graph is called after set_graph_aliases" do
75
80
  ds = @ds1.set_graph_aliases([[:x,[:points, :x]], [:y,[:lines, :y]]])
76
81
  ds.sql.should == 'SELECT points.x, lines.y FROM points'
data/spec/schema_spec.rb CHANGED
@@ -278,10 +278,10 @@ context "DB#create_table" do
278
278
  @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE UNIQUE INDEX cats_id_name_index ON cats (id, name)"]
279
279
  end
280
280
 
281
- pt_specify "should accept unnamed constraint definitions with blocks" do
281
+ specify "should accept unnamed constraint definitions with blocks" do
282
282
  @db.create_table(:cats) do
283
283
  integer :score
284
- check {:x > 0 && :y < 1}
284
+ check {(:x > 0) & (:y < 1)}
285
285
  end
286
286
  @db.sqls.should == ["CREATE TABLE cats (score integer, CHECK ((x > 0) AND (y < 1)))"]
287
287
  end
@@ -301,9 +301,9 @@ context "DB#create_table" do
301
301
  @db.sqls.should == ["CREATE TABLE cats (score integer, CONSTRAINT valid_score CHECK (score <= 100))"]
302
302
  end
303
303
 
304
- pt_specify "should accept named constraint definitions with block" do
304
+ specify "should accept named constraint definitions with block" do
305
305
  @db.create_table(:cats) do
306
- constraint(:blah_blah) {:x > 0 && :y < 1}
306
+ constraint(:blah_blah) {(:x > 0) & (:y < 1)}
307
307
  end
308
308
  @db.sqls.should == ["CREATE TABLE cats (CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1)))"]
309
309
  end
@@ -350,9 +350,9 @@ context "DB#alter_table" do
350
350
  @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT valid_score CHECK (score <= 100)"]
351
351
  end
352
352
 
353
- pt_specify "should support add_constraint with block" do
353
+ specify "should support add_constraint with block" do
354
354
  @db.alter_table(:cats) do
355
- add_constraint(:blah_blah) {:x > 0 && :y < 1}
355
+ add_constraint(:blah_blah) {(:x > 0) & (:y < 1)}
356
356
  end
357
357
  @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1))"]
358
358
  end
@@ -1,6 +1,7 @@
1
1
  # database objects for running adapter specs
2
2
  # INFORMIX_DB = Sequel.connect('informix://localhost/mydb')
3
- # MYSQL_DB = Sequel.connect('mysql://root@localhost/sandbox')
3
+ # MYSQL_USER = 'root'
4
+ # MYSQL_DB = Sequel.connect("mysql://#{MYSQL_USER}@localhost/sandbox")
4
5
  # MYSQL_SOCKET_FILE = '/tmp/mysql.sock'
5
6
  # ORACLE_DB = Sequel.connect('oracle://hr:hr@localhost/XE')
6
7
  # POSTGRES_DB = Sequel.connect('postgres://postgres:postgres@localhost:5432/reality_spec')
data/spec/spec_helper.rb CHANGED
@@ -50,12 +50,6 @@ class SchemaDummyDatabase < Sequel::Database
50
50
  end
51
51
  end
52
52
 
53
- class Spec::Example::ExampleGroup
54
- def self.pt_specify(*args, &block)
55
- specify(*args, &block) if defined?(::ParseTree)
56
- end
57
- end
58
-
59
53
  if File.exists?(File.join(File.dirname(__FILE__), 'spec_config.rb'))
60
54
  require File.join(File.dirname(__FILE__), 'spec_config.rb')
61
55
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-06-17 00:00:00 -07:00
12
+ date: 2008-07-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -48,14 +48,13 @@ files:
48
48
  - spec/rcov.opts
49
49
  - spec/schema_generator_spec.rb
50
50
  - spec/spec_helper.rb
51
- - spec/sequelizer_spec.rb
52
51
  - spec/spec.opts
53
52
  - spec/spec_config.rb.example
54
53
  - spec/spec_config.rb
55
54
  - spec/worker_spec.rb
56
55
  - spec/connection_pool_spec.rb
57
56
  - spec/object_graph_spec.rb
58
- - spec/blockless_filters_spec.rb
57
+ - spec/expression_filters_spec.rb
59
58
  - lib/sequel_core.rb
60
59
  - lib/sequel_core
61
60
  - lib/sequel_core/adapters
@@ -80,10 +79,8 @@ files:
80
79
  - lib/sequel_core/dataset
81
80
  - lib/sequel_core/dataset/callback.rb
82
81
  - lib/sequel_core/dataset/convenience.rb
83
- - lib/sequel_core/dataset/sequelizer.rb
84
82
  - lib/sequel_core/dataset/sql.rb
85
83
  - lib/sequel_core/dataset/pagination.rb
86
- - lib/sequel_core/dataset/parse_tree_sequelizer.rb
87
84
  - lib/sequel_core/dataset/query.rb
88
85
  - lib/sequel_core/dataset/schema.rb
89
86
  - lib/sequel_core/object_graph.rb
@@ -1,310 +0,0 @@
1
- module Sequel
2
- class Dataset
3
- private
4
- # Formats an comparison expression involving a left value and a right
5
- # value. Comparison expressions differ according to the class of the right
6
- # value. The stock implementation supports Range (inclusive and exclusive),
7
- # Array (as a list of values to compare against), Dataset (as a subquery to
8
- # compare against), or a regular value.
9
- #
10
- # dataset.compare_expr('id', 1..20) #=>
11
- # "(id >= 1 AND id <= 20)"
12
- # dataset.compare_expr('id', [3,6,10]) #=>
13
- # "(id IN (3, 6, 10))"
14
- # dataset.compare_expr('id', DB[:items].select(:id)) #=>
15
- # "(id IN (SELECT id FROM items))"
16
- # dataset.compare_expr('id', nil) #=>
17
- # "(id IS NULL)"
18
- # dataset.compare_expr('id', 3) #=>
19
- # "(id = 3)"
20
- def compare_expr(l, r)
21
- case r
22
- when Range
23
- "(#{literal(l)} >= #{literal(r.begin)} AND #{literal(l)} <#{'=' unless r.exclude_end?} #{literal(r.end)})"
24
- when Array, Sequel::Dataset
25
- "(#{literal(l)} IN #{literal(r)})"
26
- when NilClass
27
- "(#{literal(l)} IS NULL)"
28
- when Regexp
29
- collate_match_expr(l, r)
30
- else
31
- "(#{literal(l)} = #{literal(r)})"
32
- end
33
- end
34
-
35
- # Formats a string matching expression with support for multiple choices.
36
- # For more information see #match_expr.
37
- def collate_match_expr(l, r)
38
- if r.is_a?(Array)
39
- "(#{r.map {|i| match_expr(l, i)}.join(' OR ')})"
40
- else
41
- match_expr(l, r)
42
- end
43
- end
44
-
45
- # Formats a string matching expression. The stock implementation supports
46
- # matching against strings only using the LIKE operator. Specific adapters
47
- # can override this method to provide support for regular expressions.
48
- def match_expr(l, r)
49
- case r
50
- when String
51
- "(#{literal(l)} LIKE #{literal(r)})"
52
- else
53
- raise Sequel::Error, "Unsupported match pattern class (#{r.class})."
54
- end
55
- end
56
-
57
- # Translates a method call parse-tree to SQL expression. The following
58
- # operators are recognized and translated to SQL expressions: >, <, >=, <=,
59
- # ==, =~, +, -, *, /, %:
60
- #
61
- # :x == 1 #=> "(x = 1)"
62
- # (:x + 100) < 200 #=> "((x + 100) < 200)"
63
- #
64
- # The in, in?, nil and nil? method calls are intercepted and passed to
65
- # #compare_expr.
66
- #
67
- # :x.in [1, 2, 3] #=> "(x IN (1, 2, 3))"
68
- # :x.in?(DB[:y].select(:z)) #=> "(x IN (SELECT z FROM y))"
69
- # :x.nil? #=> "(x IS NULL)"
70
- #
71
- # The like and like? method calls are intercepted and passed to #match_expr.
72
- #
73
- # :x.like? 'ABC%' #=> "(x LIKE 'ABC%')"
74
- #
75
- # The method also supports SQL functions by invoking Symbol#[]:
76
- #
77
- # :avg[:x] #=> "avg(x)"
78
- # :substring[:x, 5] #=> "substring(x, 5)"
79
- #
80
- # All other method calls are evaulated as normal Ruby code.
81
- def call_expr(e, b, opts)
82
- case op = e[2]
83
- when :>, :<, :>=, :<=
84
- l = eval_expr(e[1], b, opts)
85
- r = eval_expr(e[3][1], b, opts)
86
- if l.is_one_of?(Symbol, Sequel::LiteralString, Sequel::SQL::Expression) || \
87
- r.is_one_of?(Symbol, Sequel::LiteralString, Sequel::SQL::Expression)
88
- "(#{literal(l)} #{op} #{literal(r)})"
89
- else
90
- ext_expr(e, b, opts)
91
- end
92
- when :==
93
- l = eval_expr(e[1], b, opts)
94
- r = eval_expr(e[3][1], b, opts)
95
- compare_expr(l, r)
96
- when :=~
97
- l = eval_expr(e[1], b, opts)
98
- r = eval_expr(e[3][1], b, opts)
99
- collate_match_expr(l, r)
100
- when :+, :-, :*, :%, :/
101
- l = eval_expr(e[1], b, opts)
102
- r = eval_expr(e[3][1], b, opts)
103
- if l.is_one_of?(Symbol, Sequel::LiteralString, Sequel::SQL::Expression) || \
104
- r.is_one_of?(Symbol, Sequel::LiteralString, Sequel::SQL::Expression)
105
- "(#{literal(l)} #{op} #{literal(r)})".lit
106
- else
107
- ext_expr(e, b, opts)
108
- end
109
- when :<<
110
- l = eval_expr(e[1], b, opts)
111
- r = eval_expr(e[3][1], b, opts)
112
- "#{literal(l)} = #{literal(r)}".lit
113
- when :|
114
- l = eval_expr(e[1], b, opts)
115
- r = eval_expr(e[3][1], b, opts)
116
- if l.is_one_of?(Symbol, Sequel::SQL::Subscript)
117
- l|r
118
- else
119
- ext_expr(e, b, opts)
120
- end
121
- when :in, :in?
122
- # in/in? operators are supported using two forms:
123
- # :x.in([1, 2, 3])
124
- # :x.in(1, 2, 3) # variable arity
125
- l = eval_expr(e[1], b, opts)
126
- r = eval_expr((e[3].size == 2) ? e[3][1] : e[3], b, opts)
127
- compare_expr(l, r)
128
- when :nil, :nil?
129
- l = eval_expr(e[1], b, opts)
130
- compare_expr(l, nil)
131
- when :like, :like?
132
- l = eval_expr(e[1], b, opts)
133
- r = eval_expr(e[3][1], b, opts)
134
- collate_match_expr(l, r)
135
- else
136
- if (op == :[]) && (e[1][0] == :lit) && (Symbol === e[1][1])
137
- # SQL Functions, e.g.: :sum[:x]
138
- if e[3]
139
- e[1][1][*eval_expr(e[3], b, opts)]
140
- else
141
- e[1][1][]
142
- end
143
- else
144
- # external code
145
- ext_expr(e, b, opts)
146
- end
147
- end
148
- end
149
-
150
- def fcall_expr(e, b, opts) #:nodoc:
151
- ext_expr(e, b, opts)
152
- end
153
-
154
- def vcall_expr(e, b, opts) #:nodoc:
155
- eval(e[1].to_s, b)
156
- end
157
-
158
- def iter_expr(e, b, opts) #:nodoc:
159
- if e[1][0] == :call && e[1][2] == :each
160
- unfold_each_expr(e, b, opts)
161
- elsif e[1] == [:fcall, :proc]
162
- eval_expr(e[3], b, opts) # inline proc
163
- else
164
- ext_expr(e, b, opts) # method call with inline proc
165
- end
166
- end
167
-
168
- def replace_dvars(a, values)
169
- a.map do |i|
170
- if i.is_a?(Array) && (i[0] == :dvar)
171
- if v = values[i[1]]
172
- value_to_parse_tree(v)
173
- else
174
- i
175
- end
176
- elsif Array === i
177
- replace_dvars(i, values)
178
- else
179
- i
180
- end
181
- end
182
- end
183
-
184
- def value_to_parse_tree(value)
185
- c = Class.new
186
- c.class_eval("def m; #{value.inspect}; end")
187
- ParseTree.translate(c, :m)[2][1][2]
188
- end
189
-
190
- def unfold_each_expr(e, b, opts) #:nodoc:
191
- source = eval_expr(e[1][1], b, opts)
192
- block_dvars = []
193
- if e[2][0] == :dasgn_curr
194
- block_dvars << e[2][1]
195
- elsif e[2][0] == :masgn
196
- e[2][1].each do |i|
197
- if i.is_a?(Array) && i[0] == :dasgn_curr
198
- block_dvars << i[1]
199
- end
200
- end
201
- end
202
- new_block = [:block]
203
-
204
- source.each do |*dvars|
205
- iter_values = (Array === dvars[0]) ? dvars[0] : dvars
206
- values = block_dvars.inject({}) {|m, i| m[i] = iter_values.shift; m}
207
- iter = replace_dvars(e[3], values)
208
- new_block << iter
209
- end
210
-
211
- pt_expr(new_block, b, opts)
212
- end
213
-
214
- # Evaluates a parse-tree into an SQL expression.
215
- def eval_expr(e, b, opts)
216
- case e[0]
217
- when :call # method call
218
- call_expr(e, b, opts)
219
- when :fcall
220
- fcall_expr(e, b, opts)
221
- when :vcall
222
- vcall_expr(e, b, opts)
223
- when :ivar, :cvar, :dvar, :const, :gvar # local ref
224
- eval(e[1].to_s, b)
225
- when :nth_ref
226
- eval("$#{e[1]}", b)
227
- when :lvar # local context
228
- if e[1] == :block
229
- sub_proc = eval(e[1].to_s, b)
230
- sub_proc.to_sql(self)
231
- else
232
- eval(e[1].to_s, b)
233
- end
234
- when :lit, :str # literal
235
- e[1]
236
- when :dot2 # inclusive range
237
- eval_expr(e[1], b, opts)..eval_expr(e[2], b, opts)
238
- when :dot3 # exclusive range
239
- eval_expr(e[1], b, opts)...eval_expr(e[2], b, opts)
240
- when :colon2 # qualified constant ref
241
- eval_expr(e[1], b, opts).const_get(e[2])
242
- when :false
243
- false
244
- when :true
245
- true
246
- when :nil
247
- nil
248
- when :array
249
- # array
250
- e[1..-1].map {|i| eval_expr(i, b, opts)}
251
- when :match3
252
- # =~/!~ operator
253
- l = eval_expr(e[2], b, opts)
254
- r = eval_expr(e[1], b, opts)
255
- compare_expr(l, r)
256
- when :iter
257
- iter_expr(e, b, opts)
258
- when :dasgn, :dasgn_curr
259
- # assignment
260
- l = e[1]
261
- r = eval_expr(e[2], b, opts)
262
- raise Sequel::Error::InvalidExpression, "#{l} = #{r}. Did you mean :#{l} == #{r}?"
263
- when :if
264
- op, c, br1, br2 = *e
265
- if ext_expr(c, b, opts)
266
- eval_expr(br1, b, opts)
267
- elsif br2
268
- eval_expr(br2, b, opts)
269
- end
270
- when :dstr
271
- ext_expr(e, b, opts)
272
- else
273
- raise Sequel::Error::InvalidExpression, "Invalid expression tree: #{e.inspect}"
274
- end
275
- end
276
-
277
- JOIN_AND = " AND ".freeze
278
- JOIN_COMMA = ", ".freeze
279
-
280
- def pt_expr(e, b, opts = {}) #:nodoc:
281
- case e[0]
282
- when :not # negation: !x, (x != y), (x !~ y)
283
- if (e[1][0] == :lit) && (Symbol === e[1][1])
284
- # translate (!:x) into (x = 'f')
285
- compare_expr(e[1][1], false)
286
- else
287
- "(NOT #{pt_expr(e[1], b, opts)})"
288
- end
289
- when :and # x && y
290
- "(#{e[1..-1].map {|i| pt_expr(i, b, opts)}.join(JOIN_AND)})"
291
- when :or # x || y
292
- "(#{pt_expr(e[1], b, opts)} OR #{pt_expr(e[2], b, opts)})"
293
- when :call, :vcall, :iter, :match3, :if # method calls, blocks
294
- eval_expr(e, b, opts)
295
- when :block # block of statements
296
- if opts[:comma_separated]
297
- "#{e[1..-1].map {|i| pt_expr(i, b, opts)}.join(JOIN_COMMA)}"
298
- else
299
- "(#{e[1..-1].map {|i| pt_expr(i, b, opts)}.join(JOIN_AND)})"
300
- end
301
- else # literals
302
- if e == [:lvar, :block]
303
- eval_expr(e, b, opts)
304
- else
305
- literal(eval_expr(e, b, opts))
306
- end
307
- end
308
- end
309
- end
310
- end