squeel 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
- # v1.0.2
2
- ## 2012-05-30
1
+ ## 1.0.3 (2012-06-07)
2
+
3
+ * Port fix for Rails CVE-2012-2661 to Squeel.
4
+ * Reduce risk of a potential memory leak through overzealous
5
+ calling to to_sym.
6
+ * Allow right-hand relation conditions to prevail in Relation#merge.
7
+
8
+ ## 1.0.2 (2012-05-30)
3
9
 
4
10
  * Add groupings to DSL. Allows control of matched sets of
5
11
  parentheses in the absence of not/and/etc. Accessed via
@@ -9,12 +15,10 @@
9
15
  * Work around issue with Relation#count when where_values
10
16
  contains InfixOperations. Fixes #122.
11
17
 
12
- # v1.0.1
13
- ## 2012-05-02
18
+ ## 1.0.1 (2012-05-02)
14
19
 
15
20
  * Undefine `type` method on Stubs/KeyPaths for 1.8.x compat.
16
21
 
17
- # v1.0.0
18
- ## 2012-04-22
22
+ ## 1.0.0 (2012-04-22)
19
23
 
20
24
  * Official 1.0.0 release.
@@ -17,11 +17,11 @@ module Squeel
17
17
 
18
18
  def find(object, parent = @base)
19
19
  if JoinBase === parent
20
- object = object.to_sym if String === object
21
20
  case object
22
- when Symbol, Nodes::Stub
21
+ when String, Symbol, Nodes::Stub
22
+ assoc_name = object.to_s
23
23
  @object.join_associations.detect { |j|
24
- j.reflection.name == object.to_sym && j.parent == parent
24
+ j.reflection.name.to_s == assoc_name && j.parent == parent
25
25
  }
26
26
  when Nodes::Join
27
27
  @object.join_associations.detect { |j|
@@ -50,7 +50,7 @@ module Squeel
50
50
 
51
51
  def get_table(object)
52
52
  if [Symbol, String, Nodes::Stub].include?(object.class)
53
- Arel::Table.new(object.to_sym, :engine => @engine)
53
+ Arel::Table.new(object.to_s, :engine => @engine)
54
54
  elsif Nodes::Join === object
55
55
  object._klass ? object._klass.arel_table : Arel::Table.new(object._name, :engine => @engine)
56
56
  elsif object.respond_to?(:aliased_table_name)
@@ -32,38 +32,19 @@ module Squeel
32
32
  )
33
33
  end
34
34
 
35
- # We need to be able to support merging two relations that have a different
36
- # base class. Stock ActiveRecord doesn't have to do anything too special, because
37
- # it's already created predicates out of the where_values by now, and they're
38
- # already bound to the proper table.
39
- #
40
- # Squeel, on the other hand, needs to do its best to ensure the predicates are still
41
- # winding up against the proper table. The most "correct" way I can think of to do
42
- # this is to try to emulate the default AR behavior -- that is, de-squeelifying
43
- # the *_values, erm... values by visiting them and converting them to ARel nodes
44
- # before merging. Merging relations is a nifty little trick, but it's another
45
- # little corner of ActiveRecord where the magic quickly fades. :(
46
- def merge(r)
47
- if relation_with_different_base?(r)
48
- r = r.clone.visit!
35
+ # We need to be able to support merging two relations without having
36
+ # to get our hooks too deeply into ActiveRecord. AR's relation
37
+ # merge functionality is very cool, but relatively complex, to
38
+ # handle the various edge cases. Our best shot at avoiding strange
39
+ # behavior with Squeel loaded is to visit the *_values arrays in
40
+ # the relations we're merging, and then use the default AR merge
41
+ # code on the result.
42
+ def merge(r, relations_visited = false)
43
+ if relations_visited
44
+ super(r)
45
+ else
46
+ clone.visit!.merge(r.clone.visit!, true)
49
47
  end
50
-
51
- super(r)
52
- end
53
-
54
- def relation_with_different_base?(r)
55
- ::ActiveRecord::Relation === r &&
56
- base_class.name != r.klass.base_class.name
57
- end
58
-
59
- def prepare_relation_for_association_merge!(r, association_name)
60
- r.where_values.map! {|w| Squeel::Visitors::PredicateVisitor.can_visit?(w) ? {association_name => w} : w}
61
- r.having_values.map! {|h| Squeel::Visitors::PredicateVisitor.can_visit?(h) ? {association_name => h} : h}
62
- r.group_values.map! {|g| Squeel::Visitors::AttributeVisitor.can_visit?(g) ? {association_name => g} : g}
63
- r.order_values.map! {|o| Squeel::Visitors::AttributeVisitor.can_visit?(o) ? {association_name => o} : o}
64
- r.select_values.map! {|s| Squeel::Visitors::AttributeVisitor.can_visit?(s) ? {association_name => s} : s}
65
- r.joins_values.map! {|j| [Symbol, Hash, Nodes::Stub, Nodes::Join, Nodes::KeyPath].include?(j.class) ? {association_name => j} : j}
66
- r.includes_values.map! {|i| [Symbol, Hash, Nodes::Stub, Nodes::Join, Nodes::KeyPath].include?(i.class) ? {association_name => i} : i}
67
48
  end
68
49
 
69
50
  def visit!
@@ -17,11 +17,11 @@ module Squeel
17
17
 
18
18
  def find(object, parent = @base)
19
19
  if JoinPart === parent
20
- object = object.to_sym if String === object
21
20
  case object
22
- when Symbol, Nodes::Stub
21
+ when String, Symbol, Nodes::Stub
22
+ assoc_name = object.to_s
23
23
  @object.join_associations.detect { |j|
24
- j.reflection.name == object.to_sym && j.parent == parent
24
+ j.reflection.name.to_s == assoc_name && j.parent == parent
25
25
  }
26
26
  when Nodes::Join
27
27
  @object.join_associations.detect { |j|
@@ -50,7 +50,7 @@ module Squeel
50
50
 
51
51
  def get_table(object)
52
52
  if [Symbol, String, Nodes::Stub].include?(object.class)
53
- Arel::Table.new(object.to_sym, :engine => @engine)
53
+ Arel::Table.new(object.to_s, :engine => @engine)
54
54
  elsif Nodes::Join === object
55
55
  object._klass ? object._klass.arel_table : Arel::Table.new(object._name, :engine => @engine)
56
56
  elsif object.respond_to?(:aliased_table_name)
@@ -32,28 +32,19 @@ module Squeel
32
32
  )
33
33
  end
34
34
 
35
- # We need to be able to support merging two relations that have a different
36
- # base class. Stock ActiveRecord doesn't have to do anything too special, because
37
- # it's already created predicates out of the where_values by now, and they're
38
- # already bound to the proper table.
39
- #
40
- # Squeel, on the other hand, needs to do its best to ensure the predicates are still
41
- # winding up against the proper table. The most "correct" way I can think of to do
42
- # this is to try to emulate the default AR behavior -- that is, de-squeelifying
43
- # the *_values, erm... values by visiting them and converting them to ARel nodes
44
- # before merging. Merging relations is a nifty little trick, but it's another
45
- # little corner of ActiveRecord where the magic quickly fades. :(
46
- def merge(r)
47
- if relation_with_different_base?(r)
48
- r = r.clone.visit!
35
+ # We need to be able to support merging two relations without having
36
+ # to get our hooks too deeply into ActiveRecord. AR's relation
37
+ # merge functionality is very cool, but relatively complex, to
38
+ # handle the various edge cases. Our best shot at avoiding strange
39
+ # behavior with Squeel loaded is to visit the *_values arrays in
40
+ # the relations we're merging, and then use the default AR merge
41
+ # code on the result.
42
+ def merge(r, relations_visited = false)
43
+ if relations_visited
44
+ super(r)
45
+ else
46
+ clone.visit!.merge(r.clone.visit!, true)
49
47
  end
50
-
51
- super(r)
52
- end
53
-
54
- def relation_with_different_base?(r)
55
- ::ActiveRecord::Relation === r &&
56
- base_class.name != r.klass.base_class.name
57
48
  end
58
49
 
59
50
  def prepare_relation_for_association_merge!(r, association_name)
@@ -4,7 +4,7 @@ module Squeel
4
4
  module Adapters
5
5
  module ActiveRecord
6
6
  module RelationExtensions
7
-
7
+
8
8
  def build_arel
9
9
  arel = table.from table
10
10
 
@@ -28,15 +28,15 @@ module Squeel
28
28
  arel.order(*order) unless order.empty?
29
29
 
30
30
  build_select(arel, attribute_viz.accept(@select_values.uniq))
31
-
31
+
32
32
  arel.distinct(@uniq_value)
33
33
  arel.from(@from_value) if @from_value
34
34
  arel.lock(@lock_value) if @lock_value
35
35
 
36
36
  arel
37
37
  end
38
-
38
+
39
39
  end
40
40
  end
41
41
  end
42
- end
42
+ end
data/lib/squeel/dsl.rb CHANGED
@@ -86,8 +86,7 @@ module Squeel
86
86
  # @param [Symbol, Nodes::Stub] name The name of the sifter defined in the model.
87
87
  # @return [Nodes::Sifter] The sifter node
88
88
  def sift(name, *args)
89
- name = name.to_sym if Nodes::Stub === name
90
- Nodes::Sifter.new name, args
89
+ Nodes::Sifter.new name.to_sym, args
91
90
  end
92
91
 
93
92
  # Node generation inside DSL blocks.
@@ -1,3 +1,3 @@
1
1
  module Squeel
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -16,10 +16,10 @@ module Squeel
16
16
  # @return [Array] An array of values for use in an ordering, grouping, etc.
17
17
  def visit_Hash(o, parent)
18
18
  o.map do |k, v|
19
- if implies_context_change?(v)
20
- visit_with_context_change(k, v, parent)
19
+ if implies_hash_context_shift?(v)
20
+ visit_with_hash_context_shift(k, v, parent)
21
21
  else
22
- visit_without_context_change(k, v, parent)
22
+ visit_without_hash_context_shift(k, v, parent)
23
23
  end
24
24
  end.flatten
25
25
  end
@@ -41,7 +41,7 @@ module Squeel
41
41
  # @param parent The stub's parent within the context
42
42
  # @return [Arel::Attribute] An attribute on the contextualized parent table
43
43
  def visit_Squeel_Nodes_Stub(o, parent)
44
- contextualize(parent)[o.symbol]
44
+ contextualize(parent)[o.to_s]
45
45
  end
46
46
 
47
47
  # Visit a Literal by converting it to an ARel SqlLiteral
@@ -94,7 +94,7 @@ module Squeel
94
94
  when Nodes::Function, Nodes::KeyPath, Nodes::As, Nodes::Literal, Nodes::Grouping
95
95
  visit(arg, parent)
96
96
  when Symbol, Nodes::Stub
97
- Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
97
+ Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_s])
98
98
  else
99
99
  quote arg
100
100
  end
@@ -116,7 +116,7 @@ module Squeel
116
116
  when Nodes::Function, Nodes::KeyPath, Nodes::As, Nodes::Literal, Nodes::Grouping
117
117
  visit(arg, parent)
118
118
  when Symbol, Nodes::Stub
119
- Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
119
+ Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_s])
120
120
  else
121
121
  quote arg
122
122
  end
@@ -166,7 +166,7 @@ module Squeel
166
166
 
167
167
  # @return [Boolean] Whether the given value implies a context change
168
168
  # @param v The value to consider
169
- def implies_context_change?(v)
169
+ def implies_hash_context_shift?(v)
170
170
  can_visit?(v)
171
171
  end
172
172
 
@@ -177,7 +177,9 @@ module Squeel
177
177
  # @param v The hash value
178
178
  # @param parent The current parent object in the context
179
179
  # @return The visited value
180
- def visit_with_context_change(k, v, parent)
180
+ def visit_with_hash_context_shift(k, v, parent)
181
+ @hash_context_depth += 1
182
+
181
183
  parent = case k
182
184
  when Nodes::KeyPath
183
185
  traverse(k, parent, true)
@@ -190,6 +192,8 @@ module Squeel
190
192
  else
191
193
  can_visit?(v) ? visit(v, parent || k) : v
192
194
  end
195
+ ensure
196
+ @hash_context_depth -= 1
193
197
  end
194
198
 
195
199
  # If there is no context change, we'll just return the value unchanged,
@@ -201,7 +205,7 @@ module Squeel
201
205
  # @param parent The current parent object in the context
202
206
  # @return The same value we just received. Yeah, this method's pretty pointless,
203
207
  # for now, and only here for consistency's sake.
204
- def visit_without_context_change(k, v, parent)
208
+ def visit_without_hash_context_shift(k, v, parent)
205
209
  v
206
210
  end
207
211
 
@@ -17,10 +17,10 @@ module Squeel
17
17
  # @return [Array] An array of values for use in a where or having clause
18
18
  def visit_Hash(o, parent)
19
19
  predicates = o.map do |k, v|
20
- if implies_context_change?(v)
21
- visit_with_context_change(k, v, parent)
20
+ if implies_hash_context_shift?(v)
21
+ visit_with_hash_context_shift(k, v, parent)
22
22
  else
23
- visit_without_context_change(k, v, parent)
23
+ visit_without_hash_context_shift(k, v, parent)
24
24
  end
25
25
  end
26
26
 
@@ -71,7 +71,7 @@ module Squeel
71
71
  # @return [Arel::Attribute] An attribute of the parent table with the
72
72
  # Stub's column
73
73
  def visit_Squeel_Nodes_Stub(o, parent)
74
- contextualize(parent)[o.symbol]
74
+ contextualize(parent)[o.to_s]
75
75
  end
76
76
 
77
77
  # Visit a Literal by converting it to an ARel SqlLiteral
@@ -105,7 +105,7 @@ module Squeel
105
105
 
106
106
  case value
107
107
  when Nodes::KeyPath
108
- value = can_visit?(value.endpoint) ? visit(value, parent) : contextualize(traverse(value, parent))[value.endpoint.to_sym]
108
+ value = can_visit?(value.endpoint) ? visit(value, parent) : contextualize(traverse(value, parent))[value.endpoint.to_s]
109
109
  when ActiveRecord::Relation
110
110
  value = visit(
111
111
  value.select_values.empty? ? value.select(value.klass.arel_table[value.klass.primary_key]) : value,
@@ -145,9 +145,9 @@ module Squeel
145
145
  when ActiveRecord::Relation
146
146
  arg.arel.ast
147
147
  when Nodes::KeyPath
148
- can_visit?(arg.endpoint) ? visit(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_sym]
148
+ can_visit?(arg.endpoint) ? visit(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_s]
149
149
  when Symbol, Nodes::Stub
150
- Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
150
+ Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_s])
151
151
  else
152
152
  quote arg
153
153
  end
@@ -179,9 +179,9 @@ module Squeel
179
179
  when Nodes::Function, Nodes::As, Nodes::Literal, Nodes::Grouping
180
180
  visit(arg, parent)
181
181
  when Nodes::KeyPath
182
- can_visit?(arg.endpoint) ? visit(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_sym]
182
+ can_visit?(arg.endpoint) ? visit(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_s]
183
183
  when Symbol, Nodes::Stub
184
- Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
184
+ Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_s])
185
185
  else
186
186
  quote arg
187
187
  end
@@ -252,7 +252,7 @@ module Squeel
252
252
 
253
253
  # @return [Boolean] Whether the given value implies a context change
254
254
  # @param v The value to consider
255
- def implies_context_change?(v)
255
+ def implies_hash_context_shift?(v)
256
256
  case v
257
257
  when Hash, Nodes::Predicate, Nodes::Unary, Nodes::Binary, Nodes::Nary, Nodes::Sifter
258
258
  true
@@ -270,7 +270,9 @@ module Squeel
270
270
  # @param v The hash value
271
271
  # @param parent The current parent object in the context
272
272
  # @return The visited value
273
- def visit_with_context_change(k, v, parent)
273
+ def visit_with_hash_context_shift(k, v, parent)
274
+ @hash_context_depth += 1
275
+
274
276
  parent = case k
275
277
  when Nodes::KeyPath
276
278
  traverse(k, parent, true)
@@ -290,6 +292,8 @@ module Squeel
290
292
  of key = #{k} and value = #{v}"
291
293
  END
292
294
  end
295
+ ensure
296
+ @hash_context_depth -= 1
293
297
  end
294
298
 
295
299
  # Create a predicate for a given key/value pair. If the value is
@@ -300,12 +304,12 @@ module Squeel
300
304
  # @param v The hash value
301
305
  # @param parent The current parent object in the context
302
306
  # @return An ARel predicate
303
- def visit_without_context_change(k, v, parent)
307
+ def visit_without_hash_context_shift(k, v, parent)
304
308
  case v
305
309
  when Nodes::Stub, Symbol
306
- v = contextualize(parent)[v.to_sym]
310
+ v = contextualize(parent)[v.to_s]
307
311
  when Nodes::KeyPath # If we could visit the endpoint, we wouldn't be here
308
- v = contextualize(traverse(v, parent))[v.endpoint.to_sym]
312
+ v = contextualize(traverse(v, parent))[v.endpoint.to_s]
309
313
  end
310
314
 
311
315
  case k
@@ -317,11 +321,11 @@ module Squeel
317
321
  visit(k % quote_for_node(k.endpoint, v), parent)
318
322
  else
319
323
  attr_name = k.to_s
320
- attribute = if attr_name.include?('.')
324
+ attribute = if !hash_context_shifted? && attr_name.include?('.')
321
325
  table_name, attr_name = attr_name.split(/\./, 2)
322
- Arel::Table.new(table_name.to_sym, :engine => engine)[attr_name.to_sym]
326
+ Arel::Table.new(table_name.to_s, :engine => engine)[attr_name.to_s]
323
327
  else
324
- contextualize(parent)[k.to_sym]
328
+ contextualize(parent)[attr_name]
325
329
  end
326
330
  arel_predicate_for(attribute, v, parent)
327
331
  end
@@ -14,6 +14,7 @@ module Squeel
14
14
  # @param [Context] context The context to use for node visitation.
15
15
  def initialize(context = nil)
16
16
  @context = context
17
+ @hash_context_depth = 0
17
18
  end
18
19
 
19
20
  # Accept an object.
@@ -50,6 +51,16 @@ module Squeel
50
51
  hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
51
52
  end
52
53
 
54
+ # If we're visiting stuff in a hash, it's good to check whether or
55
+ # not we've shifted context already. If we have, we may want to use
56
+ # caution as it pertains to certain input, in case it's untrusted.
57
+ # See CVE-2012-2661 for info.
58
+ #
59
+ # @return [Boolean] Whether we're within a new context.
60
+ def hash_context_shifted?
61
+ @hash_context_depth > 0
62
+ end
63
+
53
64
  # Important to avoid accidentally allowing the default ARel visitor's
54
65
  # last_column quoting behavior (where a value is quoted as though it
55
66
  # is of the type of the last visited column). This can wreak havoc with
@@ -672,6 +672,15 @@ module Squeel
672
672
  sql.should match /"articles"."title" = 'Condition'/
673
673
  end
674
674
 
675
+ it 'uses the last condition in the case of a conflicting where' do
676
+ relation = Person.where{name == 'Ernie'}.merge(
677
+ Person.where{name == 'Bert'}
678
+ )
679
+ sql = relation.to_sql
680
+ sql.should_not match /Ernie/
681
+ sql.should match /Bert/
682
+ end
683
+
675
684
  end
676
685
 
677
686
  describe '#to_a' do
@@ -26,14 +26,14 @@ module Squeel
26
26
  it 'creates Equality nodes for simple hashes' do
27
27
  predicate = @v.accept(:name => 'Joe')
28
28
  predicate.should be_a Arel::Nodes::Equality
29
- predicate.left.name.should eq :name
29
+ predicate.left.name.to_s.should eq 'name'
30
30
  predicate.right.should eq 'Joe'
31
31
  end
32
32
 
33
33
  it 'creates In nodes for simple hashes with an array as a value' do
34
34
  predicate = @v.accept(:name => ['Joe', 'Bob'])
35
35
  predicate.should be_a Arel::Nodes::In
36
- predicate.left.name.should eq :name
36
+ predicate.left.name.to_s.should eq 'name'
37
37
  predicate.right.should eq ['Joe', 'Bob']
38
38
  end
39
39
 
@@ -112,14 +112,14 @@ module Squeel
112
112
  it 'allows a subquery on the value side of an explicit predicate' do
113
113
  predicate = @v.accept dsl{name.in(Person.select{name}.where{name.in(['Aric Smith', 'Gladyce Kulas'])})}
114
114
  predicate.should be_a Arel::Nodes::In
115
- predicate.left.name.should eq :name
115
+ predicate.left.name.to_s.should eq 'name'
116
116
  predicate.right.should be_a Arel::Nodes::SelectStatement
117
117
  end
118
118
 
119
119
  it 'allows a subquery on the value side of an implicit predicate' do
120
120
  predicate = @v.accept(:name => Person.select{name}.where{name.in(['Aric Smith', 'Gladyce Kulas'])})
121
121
  predicate.should be_a Arel::Nodes::In
122
- predicate.left.name.should eq :name
122
+ predicate.left.name.to_s.should eq 'name'
123
123
  predicate.right.should be_a Arel::Nodes::SelectStatement
124
124
  end
125
125
 
@@ -150,14 +150,14 @@ module Squeel
150
150
  it 'converts ActiveRecord::Base objects to their id' do
151
151
  predicate = @v.accept(:id => Person.first)
152
152
  predicate.should be_a Arel::Nodes::Equality
153
- predicate.left.name.should eq :id
153
+ predicate.left.name.to_s.should eq 'id'
154
154
  predicate.right.should eq 1
155
155
  end
156
156
 
157
157
  it 'converts arrays of ActiveRecord::Base objects to their ids' do
158
158
  predicate = @v.accept(:id => [Person.first, Person.last])
159
159
  predicate.should be_a Arel::Nodes::In
160
- predicate.left.name.should eq :id
160
+ predicate.left.name.to_s.should eq 'id'
161
161
  predicate.right.should eq [1, 332]
162
162
  end
163
163
 
@@ -305,6 +305,14 @@ module Squeel
305
305
  predicate.to_sql.should match /"things"."attribute" = 'retro'/
306
306
  end
307
307
 
308
+ it 'does not allow "table.column" keys after context change' do
309
+ result = @v.accept(:id => {'articles.person_id' => 1})
310
+ result.should be_a Arel::Nodes::Equality
311
+ result.left.should be_a Arel::Attributes::Attribute
312
+ result.left.relation.name.should eq 'id'
313
+ result.left.name.to_s.should eq 'articles.person_id'
314
+ end
315
+
308
316
  it 'visits ActiveRecord::Relation values in predicates' do
309
317
  predicate = @v.accept(dsl{id >> Person.select{id}.limit(3).order{id.desc}})
310
318
  predicate.should be_a Arel::Nodes::In
@@ -367,7 +375,7 @@ module Squeel
367
375
  predicate = @v.accept(:children => Nodes::Stub.new(:children).name.eq('Joe'))
368
376
  predicate.should be_a Arel::Nodes::Equality
369
377
  predicate.left.relation.table_alias.should eq 'children_people_2'
370
- predicate.left.name.should eq :name
378
+ predicate.left.name.to_s.should eq 'name'
371
379
  predicate.right.should eq 'Joe'
372
380
  end
373
381
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squeel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-30 00:00:00.000000000 Z
12
+ date: 2012-06-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -240,7 +240,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
240
240
  version: '0'
241
241
  segments:
242
242
  - 0
243
- hash: -3844391929361765236
243
+ hash: -3464922984987800394
244
244
  required_rubygems_version: !ruby/object:Gem::Requirement
245
245
  none: false
246
246
  requirements:
@@ -249,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
249
  version: '0'
250
250
  segments:
251
251
  - 0
252
- hash: -3844391929361765236
252
+ hash: -3464922984987800394
253
253
  requirements: []
254
254
  rubyforge_project: squeel
255
255
  rubygems_version: 1.8.24