squeel 0.8.4 → 0.8.5
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/.travis.yml +8 -0
- data/Gemfile +2 -0
- data/README.md +1 -1
- data/lib/squeel/adapters/active_record/3.0/join_dependency.rb +0 -4
- data/lib/squeel/adapters/active_record/3.0/relation.rb +2 -2
- data/lib/squeel/adapters/active_record/join_dependency.rb +0 -4
- data/lib/squeel/adapters/active_record/relation.rb +5 -5
- data/lib/squeel/dsl.rb +9 -1
- data/lib/squeel/nodes.rb +1 -0
- data/lib/squeel/nodes/literal.rb +70 -0
- data/lib/squeel/version.rb +1 -1
- data/lib/squeel/visitors/attribute_visitor.rb +21 -12
- data/lib/squeel/visitors/base.rb +8 -9
- data/lib/squeel/visitors/predicate_visitor.rb +72 -41
- data/lib/squeel/visitors/symbol_visitor.rb +2 -2
- data/spec/squeel/adapters/active_record/join_association_spec.rb +2 -0
- data/spec/squeel/adapters/active_record/join_dependency_spec.rb +2 -0
- data/spec/squeel/adapters/active_record/relation_spec.rb +11 -8
- data/spec/squeel/dsl_spec.rb +8 -0
- data/spec/squeel/nodes/function_spec.rb +2 -0
- data/spec/squeel/nodes/key_path_spec.rb +2 -0
- data/spec/squeel/nodes/literal_spec.rb +155 -0
- data/spec/squeel/nodes/operation_spec.rb +2 -0
- data/spec/squeel/visitors/attribute_visitor_spec.rb +2 -0
- data/spec/squeel/visitors/predicate_visitor_spec.rb +30 -0
- data/squeel.gemspec +1 -1
- metadata +117 -74
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Squeel
|
1
|
+
# Squeel [](http://travis-ci.org/ernie/squeel)
|
2
2
|
|
3
3
|
Squeel lets you write your ActiveRecord queries with with fewer strings, and more Ruby,
|
4
4
|
by making the ARel awesomeness that lies beneath ActiveRecord more accessible.
|
@@ -5,10 +5,6 @@ module Squeel
|
|
5
5
|
module ActiveRecord
|
6
6
|
module JoinDependency
|
7
7
|
|
8
|
-
# Yes, I'm using alias_method_chain here. No, I don't feel too
|
9
|
-
# bad about it. JoinDependency, or, to call it by its full proper
|
10
|
-
# name, ::ActiveRecord::Associations::JoinDependency, is one of the
|
11
|
-
# most "for internal use only" chunks of ActiveRecord.
|
12
8
|
def self.included(base)
|
13
9
|
base.class_eval do
|
14
10
|
alias_method_chain :build, :squeel
|
@@ -62,8 +62,8 @@ module Squeel
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def prepare_relation_for_association_merge!(r, association_name)
|
65
|
-
r.where_values.map! {|w| Squeel::Visitors::PredicateVisitor.
|
66
|
-
r.having_values.map! {|h| Squeel::Visitors::PredicateVisitor.
|
65
|
+
r.where_values.map! {|w| Squeel::Visitors::PredicateVisitor.can_visit?(w) ? {association_name => w} : w}
|
66
|
+
r.having_values.map! {|h| Squeel::Visitors::PredicateVisitor.can_visit?(h) ? {association_name => h} : h}
|
67
67
|
r.joins_values.map! {|j| [Symbol, Hash, Nodes::Stub, Nodes::Join].include?(j.class) ? {association_name => j} : j}
|
68
68
|
end
|
69
69
|
|
@@ -5,10 +5,6 @@ module Squeel
|
|
5
5
|
module ActiveRecord
|
6
6
|
module JoinDependency
|
7
7
|
|
8
|
-
# Yes, I'm using alias_method_chain here. No, I don't feel too
|
9
|
-
# bad about it. JoinDependency, or, to call it by its full proper
|
10
|
-
# name, ::ActiveRecord::Associations::JoinDependency, is one of the
|
11
|
-
# most "for internal use only" chunks of ActiveRecord.
|
12
8
|
def self.included(base)
|
13
9
|
base.class_eval do
|
14
10
|
alias_method_chain :build, :squeel
|
@@ -61,11 +61,11 @@ module Squeel
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def prepare_relation_for_association_merge!(r, association_name)
|
64
|
-
r.where_values.map! {|w| Squeel::Visitors::PredicateVisitor.
|
65
|
-
r.having_values.map! {|h| Squeel::Visitors::PredicateVisitor.
|
66
|
-
r.group_values.map! {|g| Squeel::Visitors::AttributeVisitor.
|
67
|
-
r.order_values.map! {|o| Squeel::Visitors::AttributeVisitor.
|
68
|
-
r.select_values.map! {|s| Squeel::Visitors::AttributeVisitor.
|
64
|
+
r.where_values.map! {|w| Squeel::Visitors::PredicateVisitor.can_visit?(w) ? {association_name => w} : w}
|
65
|
+
r.having_values.map! {|h| Squeel::Visitors::PredicateVisitor.can_visit?(h) ? {association_name => h} : h}
|
66
|
+
r.group_values.map! {|g| Squeel::Visitors::AttributeVisitor.can_visit?(g) ? {association_name => g} : g}
|
67
|
+
r.order_values.map! {|o| Squeel::Visitors::AttributeVisitor.can_visit?(o) ? {association_name => o} : o}
|
68
|
+
r.select_values.map! {|s| Squeel::Visitors::AttributeVisitor.can_visit?(s) ? {association_name => s} : s}
|
69
69
|
r.joins_values.map! {|j| [Symbol, Hash, Nodes::Stub, Nodes::Join, Nodes::KeyPath].include?(j.class) ? {association_name => j} : j}
|
70
70
|
r.includes_values.map! {|i| [Symbol, Hash, Nodes::Stub, Nodes::Join, Nodes::KeyPath].include?(i.class) ? {association_name => i} : i}
|
71
71
|
end
|
data/lib/squeel/dsl.rb
CHANGED
@@ -50,11 +50,19 @@ module Squeel
|
|
50
50
|
# programmer hell.
|
51
51
|
#
|
52
52
|
# @param &block A block to instance_eval against the DSL's caller.
|
53
|
-
# @return
|
53
|
+
# @return The results of evaluating the block in the instance of the DSL's caller.
|
54
54
|
def my(&block)
|
55
55
|
@caller.instance_eval &block
|
56
56
|
end
|
57
57
|
|
58
|
+
# Shorthand for creating ARel SqlLiteral nodes.
|
59
|
+
#
|
60
|
+
# @param [String] string The string to convert to an SQL literal.
|
61
|
+
# @return [Arel::Nodes::SqlLiteral] The SQL literal.
|
62
|
+
def `(string)
|
63
|
+
Nodes::Literal.new(string)
|
64
|
+
end
|
65
|
+
|
58
66
|
# Node generation inside DSL blocks.
|
59
67
|
#
|
60
68
|
# @overload node_name
|
data/lib/squeel/nodes.rb
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'squeel/predicate_methods'
|
2
|
+
require 'squeel/nodes/operators'
|
3
|
+
require 'squeel/nodes/aliasing'
|
4
|
+
|
5
|
+
module Squeel
|
6
|
+
module Nodes
|
7
|
+
# Literal nodes are a container for raw SQL.
|
8
|
+
class Literal
|
9
|
+
include PredicateMethods
|
10
|
+
include Operators
|
11
|
+
include Aliasing
|
12
|
+
|
13
|
+
attr_reader :expr
|
14
|
+
|
15
|
+
def initialize(expr)
|
16
|
+
@expr = expr
|
17
|
+
end
|
18
|
+
|
19
|
+
alias :== :eq
|
20
|
+
alias :'^' :not_eq
|
21
|
+
alias :'!=' :not_eq if respond_to?(:'!=')
|
22
|
+
alias :>> :in
|
23
|
+
alias :<< :not_in
|
24
|
+
alias :=~ :matches
|
25
|
+
alias :'!~' :does_not_match if respond_to?(:'!~')
|
26
|
+
alias :> :gt
|
27
|
+
alias :>= :gteq
|
28
|
+
alias :< :lt
|
29
|
+
alias :<= :lteq
|
30
|
+
|
31
|
+
# Create an ascending Order node with this Literal as its expression
|
32
|
+
# @return [Order] The new Order node
|
33
|
+
def asc
|
34
|
+
Order.new self, 1
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create a descending Order node with this Literal as its expression
|
38
|
+
# @return [Order] The new Order node
|
39
|
+
def desc
|
40
|
+
Order.new self, -1
|
41
|
+
end
|
42
|
+
|
43
|
+
# Object comparison
|
44
|
+
def eql?(other)
|
45
|
+
self.class == other.class &&
|
46
|
+
self.expr == other.expr
|
47
|
+
end
|
48
|
+
|
49
|
+
# To support object equality tests
|
50
|
+
def hash
|
51
|
+
expr.hash
|
52
|
+
end
|
53
|
+
|
54
|
+
# expand_hash_conditions_for_aggregates assumes our hash keys can be
|
55
|
+
# converted to symbols, so this has to be implemented, but it doesn't
|
56
|
+
# really have to do anything useful.
|
57
|
+
# @return [NilClass] Just to avoid bombing out on expand_hash_conditions_for_aggregates
|
58
|
+
def to_sym
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [String] The Literal's String equivalent.
|
63
|
+
def to_s
|
64
|
+
expr.to_s
|
65
|
+
end
|
66
|
+
alias :to_str :to_s
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/squeel/version.rb
CHANGED
@@ -31,7 +31,7 @@ module Squeel
|
|
31
31
|
# @param parent The array's parent within the context
|
32
32
|
# @return [Array] The flattened array with elements visited
|
33
33
|
def visit_Array(o, parent)
|
34
|
-
o.map { |v|
|
34
|
+
o.map { |v| can_visit?(v) ? visit(v, parent) : v }.flatten
|
35
35
|
end
|
36
36
|
|
37
37
|
# Visit a symbol. This will return an attribute named after the symbol against
|
@@ -54,6 +54,15 @@ module Squeel
|
|
54
54
|
contextualize(parent)[o.symbol]
|
55
55
|
end
|
56
56
|
|
57
|
+
# Visit a Literal by converting it to an ARel SqlLiteral
|
58
|
+
#
|
59
|
+
# @param [Nodes::Literal] o The Literal to visit
|
60
|
+
# @param parent The parent object in the context (unused)
|
61
|
+
# @return [Arel::Nodes::SqlLiteral] An SqlLiteral
|
62
|
+
def visit_Squeel_Nodes_Literal(o, parent)
|
63
|
+
Arel.sql(o.expr)
|
64
|
+
end
|
65
|
+
|
57
66
|
# Visit a keypath. This will traverse the keypath's "path", setting a new
|
58
67
|
# parent as though the keypath's endpoint was in a deeply-nested hash,
|
59
68
|
# then visit the endpoint with the new parent.
|
@@ -64,7 +73,7 @@ module Squeel
|
|
64
73
|
def visit_Squeel_Nodes_KeyPath(o, parent)
|
65
74
|
parent = traverse(o, parent)
|
66
75
|
|
67
|
-
|
76
|
+
visit(o.endpoint, parent)
|
68
77
|
end
|
69
78
|
|
70
79
|
# Visit an Order node.
|
@@ -73,10 +82,10 @@ module Squeel
|
|
73
82
|
# @param parent The node's parent within the context
|
74
83
|
# @return [Arel::Nodes::Ordering] An ascending or desending ordering
|
75
84
|
def visit_Squeel_Nodes_Order(o, parent)
|
76
|
-
|
85
|
+
visit(o.expr, parent).send(o.descending? ? :desc : :asc)
|
77
86
|
end
|
78
87
|
|
79
|
-
# Visit a Function node. Each function argument will be
|
88
|
+
# Visit a Function node. Each function argument will be visiteded or
|
80
89
|
# contextualized if appropriate. Keep in mind that this occurs with
|
81
90
|
# the current parent within the context.
|
82
91
|
#
|
@@ -92,8 +101,8 @@ module Squeel
|
|
92
101
|
def visit_Squeel_Nodes_Function(o, parent)
|
93
102
|
args = o.args.map do |arg|
|
94
103
|
case arg
|
95
|
-
when Nodes::Function, Nodes::KeyPath
|
96
|
-
|
104
|
+
when Nodes::Function, Nodes::KeyPath, Nodes::As, Nodes::Literal
|
105
|
+
visit(arg, parent)
|
97
106
|
when Symbol, Nodes::Stub
|
98
107
|
Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
|
99
108
|
else
|
@@ -114,8 +123,8 @@ module Squeel
|
|
114
123
|
def visit_Squeel_Nodes_Operation(o, parent)
|
115
124
|
args = o.args.map do |arg|
|
116
125
|
case arg
|
117
|
-
when Nodes::Function
|
118
|
-
|
126
|
+
when Nodes::Function, Nodes::KeyPath, Nodes::As, Nodes::Literal
|
127
|
+
visit(arg, parent)
|
119
128
|
when Symbol, Nodes::Stub
|
120
129
|
Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
|
121
130
|
else
|
@@ -144,7 +153,7 @@ module Squeel
|
|
144
153
|
# @param parent The parent object in the context
|
145
154
|
# @return [Arel::Nodes::As] The resulting as node.
|
146
155
|
def visit_Squeel_Nodes_As(o, parent)
|
147
|
-
|
156
|
+
visit(o.left, parent).as(o.right)
|
148
157
|
end
|
149
158
|
|
150
159
|
# Visit an ActiveRecord Relation, returning an Arel::SelectManager
|
@@ -159,7 +168,7 @@ module Squeel
|
|
159
168
|
# @return [Boolean] Whether the given value implies a context change
|
160
169
|
# @param v The value to consider
|
161
170
|
def implies_context_change?(v)
|
162
|
-
|
171
|
+
can_visit?(v)
|
163
172
|
end
|
164
173
|
|
165
174
|
# Change context (by setting the new parent to the result of a #find or
|
@@ -178,9 +187,9 @@ module Squeel
|
|
178
187
|
end
|
179
188
|
|
180
189
|
if Array === v
|
181
|
-
v.map {|val|
|
190
|
+
v.map {|val| visit(val, parent || k)}
|
182
191
|
else
|
183
|
-
|
192
|
+
can_visit?(v) ? visit(v, parent || k) : v
|
184
193
|
end
|
185
194
|
end
|
186
195
|
|
data/lib/squeel/visitors/base.rb
CHANGED
@@ -27,20 +27,20 @@ module Squeel
|
|
27
27
|
end
|
28
28
|
|
29
29
|
# @param object The object to check
|
30
|
-
# @return [Boolean] Whether or not the visitor can
|
31
|
-
def
|
32
|
-
self.class.
|
30
|
+
# @return [Boolean] Whether or not the visitor can visit the given object
|
31
|
+
def can_visit?(object)
|
32
|
+
self.class.can_visit? object
|
33
33
|
end
|
34
34
|
|
35
35
|
# @param object The object to check
|
36
|
-
# @return [Boolean] Whether or not visitors of this class can
|
37
|
-
def self.
|
38
|
-
@
|
36
|
+
# @return [Boolean] Whether or not visitors of this class can visit the given object
|
37
|
+
def self.can_visit?(object)
|
38
|
+
@can_visit ||= Hash.new do |hash, klass|
|
39
39
|
hash[klass] = klass.ancestors.detect { |ancestor|
|
40
40
|
private_method_defined? DISPATCH[ancestor]
|
41
41
|
} ? true : false
|
42
42
|
end
|
43
|
-
@
|
43
|
+
@can_visit[object.class]
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
@@ -89,8 +89,7 @@ module Squeel
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
# Visit the object.
|
93
|
-
# #accept method.
|
92
|
+
# Visit the object.
|
94
93
|
#
|
95
94
|
# @param object The object to visit
|
96
95
|
# @param parent The object's parent within the context
|
@@ -40,7 +40,7 @@ module Squeel
|
|
40
40
|
# @param parent The current parent object in the context
|
41
41
|
# @return [Array] The visited array
|
42
42
|
def visit_Array(o, parent)
|
43
|
-
o.map { |v|
|
43
|
+
o.map { |v| can_visit?(v) ? visit(v, parent) : v }.flatten
|
44
44
|
end
|
45
45
|
|
46
46
|
# Visit ActiveRecord::Base objects. These should be converted to their
|
@@ -61,7 +61,7 @@ module Squeel
|
|
61
61
|
def visit_Squeel_Nodes_KeyPath(o, parent)
|
62
62
|
parent = traverse(o, parent)
|
63
63
|
|
64
|
-
|
64
|
+
visit(o.endpoint, parent)
|
65
65
|
end
|
66
66
|
|
67
67
|
# Visit a Stub by converting it to an ARel attribute
|
@@ -74,6 +74,15 @@ module Squeel
|
|
74
74
|
contextualize(parent)[o.symbol]
|
75
75
|
end
|
76
76
|
|
77
|
+
# Visit a Literal by converting it to an ARel SqlLiteral
|
78
|
+
#
|
79
|
+
# @param [Nodes::Literal] o The Literal to visit
|
80
|
+
# @param parent The parent object in the context (unused)
|
81
|
+
# @return [Arel::Nodes::SqlLiteral] An SqlLiteral
|
82
|
+
def visit_Squeel_Nodes_Literal(o, parent)
|
83
|
+
Arel.sql(o.expr)
|
84
|
+
end
|
85
|
+
|
77
86
|
# Visit a Squeel predicate, converting it into an ARel predicate
|
78
87
|
#
|
79
88
|
# @param [Nodes::Predicate] o The predicate to visit
|
@@ -83,24 +92,25 @@ module Squeel
|
|
83
92
|
def visit_Squeel_Nodes_Predicate(o, parent)
|
84
93
|
value = o.value
|
85
94
|
|
86
|
-
if
|
87
|
-
|
88
|
-
|
95
|
+
if Nodes::KeyPath === value
|
96
|
+
value = can_visit?(value.endpoint) ? visit(value, parent) : contextualize(traverse(value, parent))[value.endpoint.to_sym]
|
97
|
+
else
|
98
|
+
value = visit(value, parent) if can_visit?(value)
|
89
99
|
end
|
90
100
|
|
91
|
-
|
92
|
-
|
101
|
+
value = quote_for_node(o.expr, value)
|
102
|
+
|
103
|
+
attribute = case o.expr
|
104
|
+
when Nodes::Stub, Nodes::Function, Nodes::Literal
|
105
|
+
visit(o.expr, parent)
|
93
106
|
else
|
94
|
-
|
107
|
+
contextualize(parent)[o.expr]
|
95
108
|
end
|
96
109
|
|
97
|
-
|
98
|
-
|
99
|
-
accept(o.expr, parent).send(o.method_name, value)
|
100
|
-
when Nodes::Function
|
101
|
-
accept(o.expr, parent).send(o.method_name, quote(value))
|
110
|
+
if Array === value && [:in, :not_in].include?(o.method_name)
|
111
|
+
o.method_name == :in ? attribute_in_array(attribute, value) : attribute_not_in_array(attribute, value)
|
102
112
|
else
|
103
|
-
|
113
|
+
attribute.send(o.method_name, value)
|
104
114
|
end
|
105
115
|
end
|
106
116
|
|
@@ -113,12 +123,12 @@ module Squeel
|
|
113
123
|
def visit_Squeel_Nodes_Function(o, parent)
|
114
124
|
args = o.args.map do |arg|
|
115
125
|
case arg
|
116
|
-
when Nodes::Function
|
117
|
-
|
126
|
+
when Nodes::Function, Nodes::As, Nodes::Literal
|
127
|
+
visit(arg, parent)
|
118
128
|
when ActiveRecord::Relation
|
119
129
|
arg.arel.ast
|
120
130
|
when Nodes::KeyPath
|
121
|
-
|
131
|
+
can_visit?(arg.endpoint) ? visit(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_sym]
|
122
132
|
when Symbol, Nodes::Stub
|
123
133
|
Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
|
124
134
|
else
|
@@ -149,10 +159,10 @@ module Squeel
|
|
149
159
|
def visit_Squeel_Nodes_Operation(o, parent)
|
150
160
|
args = o.args.map do |arg|
|
151
161
|
case arg
|
152
|
-
when Nodes::Function
|
153
|
-
|
162
|
+
when Nodes::Function, Nodes::As, Nodes::Literal
|
163
|
+
visit(arg, parent)
|
154
164
|
when Nodes::KeyPath
|
155
|
-
|
165
|
+
can_visit?(arg.endpoint) ? visit(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_sym]
|
156
166
|
when Symbol, Nodes::Stub
|
157
167
|
Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym])
|
158
168
|
else
|
@@ -184,7 +194,7 @@ module Squeel
|
|
184
194
|
# And node as its expression. All children will be visited before
|
185
195
|
# being passed to the And.
|
186
196
|
def visit_Squeel_Nodes_And(o, parent)
|
187
|
-
Arel::Nodes::Grouping.new(Arel::Nodes::And.new(
|
197
|
+
Arel::Nodes::Grouping.new(Arel::Nodes::And.new(visit(o.children, parent)))
|
188
198
|
end
|
189
199
|
|
190
200
|
# Visit a Squeel Or node, returning an ARel Or node.
|
@@ -193,11 +203,11 @@ module Squeel
|
|
193
203
|
# @param parent The parent object in the context
|
194
204
|
# @return [Arel::Nodes::Or] An ARel Or node, with left and right sides visited
|
195
205
|
def visit_Squeel_Nodes_Or(o, parent)
|
196
|
-
|
206
|
+
visit(o.left, parent).or(visit(o.right, parent))
|
197
207
|
end
|
198
208
|
|
199
209
|
def visit_Squeel_Nodes_Not(o, parent)
|
200
|
-
|
210
|
+
visit(o.expr, parent).not
|
201
211
|
end
|
202
212
|
|
203
213
|
# @return [Boolean] Whether the given value implies a context change
|
@@ -207,7 +217,7 @@ module Squeel
|
|
207
217
|
when Hash, Nodes::Predicate, Nodes::Unary, Nodes::Binary, Nodes::Nary
|
208
218
|
true
|
209
219
|
when Nodes::KeyPath
|
210
|
-
|
220
|
+
can_visit?(v.endpoint) && !(Nodes::Stub === v.endpoint)
|
211
221
|
else
|
212
222
|
false
|
213
223
|
end
|
@@ -230,9 +240,9 @@ module Squeel
|
|
230
240
|
|
231
241
|
case v
|
232
242
|
when Hash, Nodes::KeyPath, Nodes::Predicate, Nodes::Unary, Nodes::Binary, Nodes::Nary
|
233
|
-
|
243
|
+
visit(v, parent || k)
|
234
244
|
when Array
|
235
|
-
v.map {|val|
|
245
|
+
v.map {|val| visit(val, parent || k)}
|
236
246
|
else
|
237
247
|
raise ArgumentError, <<-END
|
238
248
|
Hashes, Predicates, and arrays of visitables as values imply that their
|
@@ -254,17 +264,17 @@ module Squeel
|
|
254
264
|
case v
|
255
265
|
when Nodes::Stub, Symbol
|
256
266
|
v = contextualize(parent)[v.to_sym]
|
257
|
-
when Nodes::KeyPath # If we could
|
267
|
+
when Nodes::KeyPath # If we could visit the endpoint, we wouldn't be here
|
258
268
|
v = contextualize(traverse(v, parent))[v.endpoint.to_sym]
|
259
269
|
end
|
260
270
|
|
261
271
|
case k
|
262
272
|
when Nodes::Predicate
|
263
|
-
|
264
|
-
when Nodes::Function
|
265
|
-
arel_predicate_for(
|
273
|
+
visit(k % quote_for_node(k.expr, v), parent)
|
274
|
+
when Nodes::Function, Nodes::Literal
|
275
|
+
arel_predicate_for(visit(k, parent), quote(v), parent)
|
266
276
|
when Nodes::KeyPath
|
267
|
-
|
277
|
+
visit(k % quote_for_node(k.endpoint, v), parent)
|
268
278
|
else
|
269
279
|
attr_name = k.to_s
|
270
280
|
attribute = if attr_name.include?('.')
|
@@ -285,19 +295,40 @@ module Squeel
|
|
285
295
|
# @param value The value to be compared against
|
286
296
|
# @return [Arel::Nodes::Node] An ARel predicate node
|
287
297
|
def arel_predicate_for(attribute, value, parent)
|
288
|
-
value =
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
end
|
298
|
+
value = can_visit?(value) ? visit(value, parent) : value
|
299
|
+
case value
|
300
|
+
when Array
|
301
|
+
attribute_in_array(attribute, value)
|
302
|
+
when Range, Arel::SelectManager
|
303
|
+
attribute.in(value)
|
295
304
|
else
|
296
305
|
attribute.eq(value)
|
297
306
|
end
|
298
307
|
end
|
299
308
|
|
300
|
-
|
309
|
+
def attribute_in_array(attribute, array)
|
310
|
+
if array.empty?
|
311
|
+
FALSE_SQL
|
312
|
+
elsif array.include? nil
|
313
|
+
array = array.compact
|
314
|
+
array.empty? ? attribute.eq(nil) : attribute.in(array).or(attribute.eq nil)
|
315
|
+
else
|
316
|
+
attribute.in array
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def attribute_not_in_array(attribute, array)
|
321
|
+
if array.empty?
|
322
|
+
TRUE_SQL
|
323
|
+
elsif array.include? nil
|
324
|
+
array = array.compact
|
325
|
+
array.empty? ? attribute.not_eq(nil) : attribute.not_in(array).and(attribute.not_eq nil)
|
326
|
+
else
|
327
|
+
attribute.not_in array
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
# Certain nodes require us to do the quoting before the ARel
|
301
332
|
# visitor gets a chance to try, because we want to avoid having our
|
302
333
|
# values quoted as a type of the last visited column. Otherwise, we
|
303
334
|
# can end up with annoyances like having "joe" quoted to 0, if the
|
@@ -307,10 +338,10 @@ module Squeel
|
|
307
338
|
# @param v The value to (possibly) quote
|
308
339
|
def quote_for_node(node, v)
|
309
340
|
case node
|
310
|
-
when Nodes::Function
|
341
|
+
when Nodes::Function, Nodes::Literal
|
311
342
|
quote(v)
|
312
343
|
when Nodes::Predicate
|
313
|
-
|
344
|
+
quote_for_node(node.expr, v)
|
314
345
|
else
|
315
346
|
v
|
316
347
|
end
|
@@ -14,13 +14,13 @@ module Squeel
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def visit_Array(o, parent)
|
17
|
-
o.map {|e|
|
17
|
+
o.map {|e| visit(e, parent)}.flatten
|
18
18
|
end
|
19
19
|
|
20
20
|
def visit_Hash(o, parent)
|
21
21
|
{}.tap do |hash|
|
22
22
|
o.each do |key, value|
|
23
|
-
hash[
|
23
|
+
hash[visit(key, parent)] = visit(value, parent)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
1
3
|
module Squeel
|
2
4
|
module Adapters
|
3
5
|
module ActiveRecord
|
@@ -335,9 +337,9 @@ module Squeel
|
|
335
337
|
end
|
336
338
|
|
337
339
|
it 'falls back to Array#select behavior with a block that has an arity' do
|
338
|
-
people = Person.select{|p| p.
|
340
|
+
people = Person.select{|p| p.id == 1}
|
339
341
|
people.should have(1).person
|
340
|
-
people.first.
|
342
|
+
people.first.id.should eq 1
|
341
343
|
end
|
342
344
|
|
343
345
|
it 'behaves as normal with standard parameters' do
|
@@ -363,7 +365,7 @@ module Squeel
|
|
363
365
|
|
364
366
|
it 'allows custom operators in the select values via block' do
|
365
367
|
relation = Person.select{name.op('||', '-diddly').as(flanderized_name)}
|
366
|
-
relation.first.flanderized_name.should eq '
|
368
|
+
relation.first.flanderized_name.should eq Person.first.name + '-diddly'
|
367
369
|
end
|
368
370
|
|
369
371
|
it 'allows a subquery in the select values' do
|
@@ -429,8 +431,9 @@ module Squeel
|
|
429
431
|
end
|
430
432
|
|
431
433
|
it 'allows a subquery on the value side of a predicate' do
|
432
|
-
|
433
|
-
|
434
|
+
names = [Person.first.name, Person.last.name]
|
435
|
+
old_and_busted = Person.where(:name => names)
|
436
|
+
new_hotness = Person.where{name.in(Person.select{name}.where{name.in(names)})}
|
434
437
|
new_hotness.should have(2).items
|
435
438
|
old_and_busted.to_a.should eq new_hotness.to_a
|
436
439
|
end
|
@@ -489,7 +492,7 @@ module Squeel
|
|
489
492
|
|
490
493
|
it 'allows complex conditions on aggregate columns' do
|
491
494
|
relation = Person.group(:parent_id).having{salary == max(salary)}
|
492
|
-
relation.first.name.should eq
|
495
|
+
relation.first.name.should eq Person.last.name
|
493
496
|
end
|
494
497
|
|
495
498
|
it 'allows a condition on a function via block' do
|
@@ -613,7 +616,7 @@ module Squeel
|
|
613
616
|
end
|
614
617
|
|
615
618
|
it 'merges relations with a different base' do
|
616
|
-
relation = Person.where{name == 'bob'}.joins(:articles).merge(Article.where{title == 'Hello world!'})
|
619
|
+
relation = Person.where{name == 'bob'}.joins(:articles).merge(Article.where{title == 'Hello world!'}, :articles)
|
617
620
|
sql = relation.to_sql
|
618
621
|
sql.should match /INNER JOIN "articles" ON "articles"."person_id" = "people"."id"/
|
619
622
|
sql.should match /"people"."name" = 'bob'/
|
@@ -635,7 +638,7 @@ module Squeel
|
|
635
638
|
where{{comments => {body => 'First post!'}}}
|
636
639
|
relation.size.should be 1
|
637
640
|
person = relation.first
|
638
|
-
person.
|
641
|
+
person.should eq Person.last
|
639
642
|
person.comments.loaded?.should be true
|
640
643
|
end
|
641
644
|
|
data/spec/squeel/dsl_spec.rb
CHANGED
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Squeel
|
4
|
+
module Nodes
|
5
|
+
describe Literal do
|
6
|
+
before do
|
7
|
+
@l = Literal.new 'string'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'hashes like its expr' do
|
11
|
+
@l.hash.should eq 'string'.hash
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'returns nil when sent to_sym' do
|
15
|
+
@l.to_sym.should be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns a string matching its expr when sent to_s' do
|
19
|
+
@l.to_s.should eq 'string'
|
20
|
+
end
|
21
|
+
|
22
|
+
Squeel::Constants::PREDICATES.each do |method_name|
|
23
|
+
it "creates #{method_name} predicates with no value" do
|
24
|
+
predicate = @l.send(method_name)
|
25
|
+
predicate.expr.should eq @l
|
26
|
+
predicate.method_name.should eq method_name
|
27
|
+
predicate.value?.should be_false
|
28
|
+
end
|
29
|
+
|
30
|
+
it "creates #{method_name} predicates with a value" do
|
31
|
+
predicate = @l.send(method_name, 'value')
|
32
|
+
predicate.expr.should eq @l
|
33
|
+
predicate.method_name.should eq method_name
|
34
|
+
predicate.value.should eq 'value'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Squeel::Constants::PREDICATE_ALIASES.each do |method_name, aliases|
|
39
|
+
aliases.each do |aliaz|
|
40
|
+
['', '_any', '_all'].each do |suffix|
|
41
|
+
it "creates #{method_name.to_s + suffix} predicates with no value using the alias #{aliaz.to_s + suffix}" do
|
42
|
+
predicate = @l.send(aliaz.to_s + suffix)
|
43
|
+
predicate.expr.should eq @l
|
44
|
+
predicate.method_name.should eq "#{method_name}#{suffix}".to_sym
|
45
|
+
predicate.value?.should be_false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "creates #{method_name.to_s + suffix} predicates with a value using the alias #{aliaz.to_s + suffix}" do
|
49
|
+
predicate = @l.send((aliaz.to_s + suffix), 'value')
|
50
|
+
predicate.expr.should eq @l
|
51
|
+
predicate.method_name.should eq "#{method_name}#{suffix}".to_sym
|
52
|
+
predicate.value.should eq 'value'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'creates eq predicates with ==' do
|
59
|
+
predicate = @l == 1
|
60
|
+
predicate.expr.should eq @l
|
61
|
+
predicate.method_name.should eq :eq
|
62
|
+
predicate.value.should eq 1
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'creates not_eq predicates with ^' do
|
66
|
+
predicate = @l ^ 1
|
67
|
+
predicate.expr.should eq @l
|
68
|
+
predicate.method_name.should eq :not_eq
|
69
|
+
predicate.value.should eq 1
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'creates not_eq predicates with !=' do
|
73
|
+
predicate = @l != 1
|
74
|
+
predicate.expr.should eq @l
|
75
|
+
predicate.method_name.should eq :not_eq
|
76
|
+
predicate.value.should eq 1
|
77
|
+
end if respond_to?('!=')
|
78
|
+
|
79
|
+
it 'creates in predicates with >>' do
|
80
|
+
predicate = @l >> [1,2,3]
|
81
|
+
predicate.expr.should eq @l
|
82
|
+
predicate.method_name.should eq :in
|
83
|
+
predicate.value.should eq [1,2,3]
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'creates not_in predicates with <<' do
|
87
|
+
predicate = @l << [1,2,3]
|
88
|
+
predicate.expr.should eq @l
|
89
|
+
predicate.method_name.should eq :not_in
|
90
|
+
predicate.value.should eq [1,2,3]
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'creates matches predicates with =~' do
|
94
|
+
predicate = @l =~ '%bob%'
|
95
|
+
predicate.expr.should eq @l
|
96
|
+
predicate.method_name.should eq :matches
|
97
|
+
predicate.value.should eq '%bob%'
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'creates does_not_match predicates with !~' do
|
101
|
+
predicate = @l !~ '%bob%'
|
102
|
+
predicate.expr.should eq @l
|
103
|
+
predicate.method_name.should eq :does_not_match
|
104
|
+
predicate.value.should eq '%bob%'
|
105
|
+
end if respond_to?('!~')
|
106
|
+
|
107
|
+
it 'creates gt predicates with >' do
|
108
|
+
predicate = @l > 1
|
109
|
+
predicate.expr.should eq @l
|
110
|
+
predicate.method_name.should eq :gt
|
111
|
+
predicate.value.should eq 1
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'creates gteq predicates with >=' do
|
115
|
+
predicate = @l >= 1
|
116
|
+
predicate.expr.should eq @l
|
117
|
+
predicate.method_name.should eq :gteq
|
118
|
+
predicate.value.should eq 1
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'creates lt predicates with <' do
|
122
|
+
predicate = @l < 1
|
123
|
+
predicate.expr.should eq @l
|
124
|
+
predicate.method_name.should eq :lt
|
125
|
+
predicate.value.should eq 1
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'creates lteq predicates with <=' do
|
129
|
+
predicate = @l <= 1
|
130
|
+
predicate.expr.should eq @l
|
131
|
+
predicate.method_name.should eq :lteq
|
132
|
+
predicate.value.should eq 1
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'creates ascending orders' do
|
136
|
+
order = @l.asc
|
137
|
+
order.should be_ascending
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'creates descending orders' do
|
141
|
+
order = @l.desc
|
142
|
+
order.should be_descending
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'creates as nodes with #as' do
|
146
|
+
as = @l.as('other_name')
|
147
|
+
as.should be_a Squeel::Nodes::As
|
148
|
+
as.left.should eq @l
|
149
|
+
as.right.should be_a Arel::Nodes::SqlLiteral
|
150
|
+
as.right.should eq 'other_name'
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -55,6 +55,36 @@ module Squeel
|
|
55
55
|
predicate.should eq '1=1'
|
56
56
|
end
|
57
57
|
|
58
|
+
it 'generates IS NULL for hash keys with a value of [nil]' do
|
59
|
+
predicate = @v.accept(:id => [nil])
|
60
|
+
predicate.to_sql.should be_like '"people"."id" IS NULL'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'generates IS NULL for in predicates with a value of [nil]' do
|
64
|
+
predicate = @v.accept(:id.in => [nil])
|
65
|
+
predicate.to_sql.should be_like '"people"."id" IS NULL'
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'generates IS NOT NULL for not_in predicates with a value of [nil]' do
|
69
|
+
predicate = @v.accept(:id.not_in => [nil])
|
70
|
+
predicate.to_sql.should be_like '"people"."id" IS NOT NULL'
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'generates IN OR IS NULL for hash keys with a value of [1, 2, 3, nil]' do
|
74
|
+
predicate = @v.accept(:id => [1, 2, 3, nil])
|
75
|
+
predicate.to_sql.should be_like '("people"."id" IN (1, 2, 3) OR "people"."id" IS NULL)'
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'generates IN OR IS NULL for in predicates with a value of [1, 2, 3, nil]' do
|
79
|
+
predicate = @v.accept(:id.in => [1, 2, 3, nil])
|
80
|
+
predicate.to_sql.should be_like '("people"."id" IN (1, 2, 3) OR "people"."id" IS NULL)'
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'generates IN AND IS NOT NULL for not_in predicates with a value of [1, 2, 3, nil]' do
|
84
|
+
predicate = @v.accept(:id.not_in => [1, 2, 3, nil])
|
85
|
+
predicate.to_sql.should be_like '"people"."id" NOT IN (1, 2, 3) AND "people"."id" IS NOT NULL'
|
86
|
+
end
|
87
|
+
|
58
88
|
it 'allows a subquery on the value side of an explicit predicate' do
|
59
89
|
predicate = @v.accept dsl{name.in(Person.select{name}.where{name.in(['Aric Smith', 'Gladyce Kulas'])})}
|
60
90
|
predicate.should be_a Arel::Nodes::In
|
data/squeel.gemspec
CHANGED
@@ -29,7 +29,7 @@ you're feeling especially appreciative. It'd help me justify this
|
|
29
29
|
|
30
30
|
s.add_dependency 'activerecord', '~> 3.0'
|
31
31
|
s.add_dependency 'activesupport', '~> 3.0'
|
32
|
-
s.add_development_dependency 'rspec', '~> 2.
|
32
|
+
s.add_development_dependency 'rspec', '~> 2.6.0'
|
33
33
|
s.add_development_dependency 'machinist', '~> 1.0.6'
|
34
34
|
s.add_development_dependency 'faker', '~> 0.9.5'
|
35
35
|
s.add_development_dependency 'sqlite3', '~> 1.3.3'
|
metadata
CHANGED
@@ -1,93 +1,129 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: squeel
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 53
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 8
|
9
|
+
- 5
|
10
|
+
version: 0.8.5
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Ernie Miller
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2011-07-02 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
15
22
|
name: activerecord
|
16
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
25
|
none: false
|
18
|
-
requirements:
|
26
|
+
requirements:
|
19
27
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 3
|
32
|
+
- 0
|
33
|
+
version: "3.0"
|
22
34
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
26
37
|
name: activesupport
|
27
|
-
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
40
|
none: false
|
29
|
-
requirements:
|
41
|
+
requirements:
|
30
42
|
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 7
|
45
|
+
segments:
|
46
|
+
- 3
|
47
|
+
- 0
|
48
|
+
version: "3.0"
|
33
49
|
type: :runtime
|
34
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
37
52
|
name: rspec
|
38
|
-
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
55
|
none: false
|
40
|
-
requirements:
|
56
|
+
requirements:
|
41
57
|
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 23
|
60
|
+
segments:
|
61
|
+
- 2
|
62
|
+
- 6
|
63
|
+
- 0
|
64
|
+
version: 2.6.0
|
44
65
|
type: :development
|
45
|
-
|
46
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
66
|
+
version_requirements: *id003
|
67
|
+
- !ruby/object:Gem::Dependency
|
48
68
|
name: machinist
|
49
|
-
|
69
|
+
prerelease: false
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
71
|
none: false
|
51
|
-
requirements:
|
72
|
+
requirements:
|
52
73
|
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 27
|
76
|
+
segments:
|
77
|
+
- 1
|
78
|
+
- 0
|
79
|
+
- 6
|
54
80
|
version: 1.0.6
|
55
81
|
type: :development
|
56
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
82
|
+
version_requirements: *id004
|
83
|
+
- !ruby/object:Gem::Dependency
|
59
84
|
name: faker
|
60
|
-
|
85
|
+
prerelease: false
|
86
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
61
87
|
none: false
|
62
|
-
requirements:
|
88
|
+
requirements:
|
63
89
|
- - ~>
|
64
|
-
- !ruby/object:Gem::Version
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 49
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
- 9
|
95
|
+
- 5
|
65
96
|
version: 0.9.5
|
66
97
|
type: :development
|
67
|
-
|
68
|
-
|
69
|
-
- !ruby/object:Gem::Dependency
|
98
|
+
version_requirements: *id005
|
99
|
+
- !ruby/object:Gem::Dependency
|
70
100
|
name: sqlite3
|
71
|
-
|
101
|
+
prerelease: false
|
102
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
72
103
|
none: false
|
73
|
-
requirements:
|
104
|
+
requirements:
|
74
105
|
- - ~>
|
75
|
-
- !ruby/object:Gem::Version
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
hash: 29
|
108
|
+
segments:
|
109
|
+
- 1
|
110
|
+
- 3
|
111
|
+
- 3
|
76
112
|
version: 1.3.3
|
77
113
|
type: :development
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
with\n a handy block-based syntax. You can write subqueries, access named\n
|
82
|
-
\ functions provided by your RDBMS, and more, all without writing\n SQL
|
83
|
-
strings.\n "
|
84
|
-
email:
|
114
|
+
version_requirements: *id006
|
115
|
+
description: "\n Squeel unlocks the power of ARel in your Rails 3 application with\n a handy block-based syntax. You can write subqueries, access named\n functions provided by your RDBMS, and more, all without writing\n SQL strings.\n "
|
116
|
+
email:
|
85
117
|
- ernie@metautonomo.us
|
86
118
|
executables: []
|
119
|
+
|
87
120
|
extensions: []
|
121
|
+
|
88
122
|
extra_rdoc_files: []
|
89
|
-
|
123
|
+
|
124
|
+
files:
|
90
125
|
- .gitignore
|
126
|
+
- .travis.yml
|
91
127
|
- .yardopts
|
92
128
|
- Gemfile
|
93
129
|
- LICENSE
|
@@ -120,6 +156,7 @@ files:
|
|
120
156
|
- lib/squeel/nodes/function.rb
|
121
157
|
- lib/squeel/nodes/join.rb
|
122
158
|
- lib/squeel/nodes/key_path.rb
|
159
|
+
- lib/squeel/nodes/literal.rb
|
123
160
|
- lib/squeel/nodes/nary.rb
|
124
161
|
- lib/squeel/nodes/not.rb
|
125
162
|
- lib/squeel/nodes/operation.rb
|
@@ -155,6 +192,7 @@ files:
|
|
155
192
|
- spec/squeel/nodes/function_spec.rb
|
156
193
|
- spec/squeel/nodes/join_spec.rb
|
157
194
|
- spec/squeel/nodes/key_path_spec.rb
|
195
|
+
- spec/squeel/nodes/literal_spec.rb
|
158
196
|
- spec/squeel/nodes/operation_spec.rb
|
159
197
|
- spec/squeel/nodes/operators_spec.rb
|
160
198
|
- spec/squeel/nodes/order_spec.rb
|
@@ -166,44 +204,48 @@ files:
|
|
166
204
|
- spec/squeel/visitors/symbol_visitor_spec.rb
|
167
205
|
- spec/support/schema.rb
|
168
206
|
- squeel.gemspec
|
207
|
+
has_rdoc: true
|
169
208
|
homepage: http://metautonomo.us/projects/squeel
|
170
209
|
licenses: []
|
171
|
-
post_install_message: ! '
|
172
210
|
|
211
|
+
post_install_message: |+
|
212
|
+
|
173
213
|
*** Thanks for installing Squeel! ***
|
174
|
-
|
175
214
|
Be sure to check out http://metautonomo.us/projects/squeel/ for a
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
you''re feeling especially appreciative. It''d help me justify this
|
180
|
-
|
215
|
+
walkthrough of Squeel's features, and click the donate link if
|
216
|
+
you're feeling especially appreciative. It'd help me justify this
|
181
217
|
"open source" stuff to my lovely wife. :)
|
182
|
-
|
183
|
-
|
184
|
-
'
|
218
|
+
|
185
219
|
rdoc_options: []
|
186
|
-
|
220
|
+
|
221
|
+
require_paths:
|
187
222
|
- lib
|
188
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
223
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
189
224
|
none: false
|
190
|
-
requirements:
|
191
|
-
- -
|
192
|
-
- !ruby/object:Gem::Version
|
193
|
-
|
194
|
-
|
225
|
+
requirements:
|
226
|
+
- - ">="
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
hash: 3
|
229
|
+
segments:
|
230
|
+
- 0
|
231
|
+
version: "0"
|
232
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
195
233
|
none: false
|
196
|
-
requirements:
|
197
|
-
- -
|
198
|
-
- !ruby/object:Gem::Version
|
199
|
-
|
234
|
+
requirements:
|
235
|
+
- - ">="
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
hash: 3
|
238
|
+
segments:
|
239
|
+
- 0
|
240
|
+
version: "0"
|
200
241
|
requirements: []
|
242
|
+
|
201
243
|
rubyforge_project: squeel
|
202
|
-
rubygems_version: 1.
|
244
|
+
rubygems_version: 1.5.2
|
203
245
|
signing_key:
|
204
246
|
specification_version: 3
|
205
247
|
summary: ActiveRecord 3, improved.
|
206
|
-
test_files:
|
248
|
+
test_files:
|
207
249
|
- spec/blueprints/articles.rb
|
208
250
|
- spec/blueprints/comments.rb
|
209
251
|
- spec/blueprints/notes.rb
|
@@ -222,6 +264,7 @@ test_files:
|
|
222
264
|
- spec/squeel/nodes/function_spec.rb
|
223
265
|
- spec/squeel/nodes/join_spec.rb
|
224
266
|
- spec/squeel/nodes/key_path_spec.rb
|
267
|
+
- spec/squeel/nodes/literal_spec.rb
|
225
268
|
- spec/squeel/nodes/operation_spec.rb
|
226
269
|
- spec/squeel/nodes/operators_spec.rb
|
227
270
|
- spec/squeel/nodes/order_spec.rb
|