ryana-inequal_opportunity 0.1.1 → 0.1.2
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/README +12 -2
- data/lib/inequal_opportunity.rb +14 -3
- data/test/inequal_opportunity_test.rb +104 -25
- metadata +1 -1
data/README
CHANGED
@@ -21,9 +21,19 @@ With Inequal Opportunity, you can write:
|
|
21
21
|
Where Object#ne wraps 42 in a ActiveRecord::Inequality::NotEqual class,
|
22
22
|
which is then used to insert the proper operator into the generated SQL.
|
23
23
|
|
24
|
-
|
25
|
-
the way I overwrite ActiveRecord.expand_range_bind_variables, but it works for now.
|
24
|
+
Other supported inequalities are:
|
26
25
|
|
26
|
+
gte() => >=
|
27
|
+
gt() => >
|
28
|
+
lte() => <=
|
29
|
+
le() => <
|
30
|
+
ne() => <>
|
31
|
+
ne(nil) => IS NOT
|
32
|
+
|
33
|
+
|
34
|
+
Test coverage is real sparse right now. And it's only been tested
|
35
|
+
on MySQL. I also am not completely satisfied with the way I overwrite
|
36
|
+
ActiveRecord.expand_range_bind_variables, but it works.
|
27
37
|
|
28
38
|
== License
|
29
39
|
|
data/lib/inequal_opportunity.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Inequality
|
3
3
|
|
4
|
+
class InequalError < Exception
|
5
|
+
end
|
6
|
+
|
4
7
|
class Base
|
5
8
|
attr_accessor :value
|
6
9
|
|
@@ -67,8 +70,15 @@ module ActiveRecord
|
|
67
70
|
'LIKE'
|
68
71
|
end
|
69
72
|
|
70
|
-
|
71
|
-
|
73
|
+
# This method is why I love Ruby
|
74
|
+
def value(override = false)
|
75
|
+
v = super(*[])
|
76
|
+
|
77
|
+
if !override && !v.is_a?(Numeric) && !v.is_a?(String)
|
78
|
+
raise InequalError, "Passing #{v.class} to Like. You can't possibly want to do this"
|
79
|
+
end
|
80
|
+
|
81
|
+
"%#{v}%"
|
72
82
|
end
|
73
83
|
end
|
74
84
|
|
@@ -107,7 +117,8 @@ module ActiveRecord
|
|
107
117
|
alias attribute_condition_orig attribute_condition
|
108
118
|
def attribute_condition(quoted_column_name, argument)
|
109
119
|
if argument.is_a? ActiveRecord::Inequality::Base
|
110
|
-
|
120
|
+
question = argument.value.is_a?(Array) ? '(?)' : '?'
|
121
|
+
"#{quoted_column_name} #{argument.operator} #{question}"
|
111
122
|
else
|
112
123
|
attribute_condition_orig(quoted_column_name, argument)
|
113
124
|
end
|
@@ -1,36 +1,27 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
2
|
-
require '
|
3
|
-
|
4
|
-
DB = YAML::load(File.open(File.join(File.dirname(__FILE__), 'database.yml'))).symbolize_keys!
|
5
|
-
ActiveRecord::Base.establish_connection(DB[:source])
|
6
|
-
|
7
|
-
TABLES = %w(mains seconds)
|
8
|
-
|
9
|
-
class Main < ActiveRecord::Base
|
10
|
-
belongs_to :seconds
|
11
|
-
named_scope :newer_than, lambda {|time| {:conditions => {:created_at => gte(time) }} }
|
12
|
-
end
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), 'db_setup')
|
13
3
|
|
14
|
-
|
15
|
-
has_many :mains
|
16
|
-
end
|
4
|
+
require 'ruby-debug'
|
17
5
|
|
18
|
-
|
6
|
+
METHOD_SYMBOLS = [:gt, :gte, :lt, :lte, :ne, :like]
|
19
7
|
|
20
|
-
class
|
8
|
+
class Main < ActiveRecord::Base
|
9
|
+
belongs_to :seconds
|
10
|
+
named_scope :newer_than, lambda {|time| {:conditions => {:created_at => gte(time) }} }
|
21
11
|
|
22
|
-
|
23
|
-
|
24
|
-
ActiveRecord::Base.connection.execute("create table #{t} (id integer, val integer, seconds_id integer, mains_id integer, created_at datetime default null);")
|
12
|
+
METHOD_SYMBOLS.each do |s|
|
13
|
+
named_scope :"try_#{s}", lambda {|i| {:conditions => {:id => send(s, i)}} }
|
25
14
|
end
|
15
|
+
|
26
16
|
end
|
27
17
|
|
28
|
-
|
29
|
-
|
30
|
-
ActiveRecord::Base.connection.execute("drop table #{t};")
|
31
|
-
end
|
18
|
+
class Second < ActiveRecord::Base
|
19
|
+
has_many :mains
|
32
20
|
end
|
33
21
|
|
22
|
+
ActiveRecord::Base.logger = Logger.new(STDERR)
|
23
|
+
|
24
|
+
class InequalOpportunityTest < Test::Unit::TestCase
|
34
25
|
context "a model" do
|
35
26
|
setup do
|
36
27
|
@model = Main
|
@@ -41,7 +32,38 @@ class InequalOpportunityTest < Test::Unit::TestCase
|
|
41
32
|
end
|
42
33
|
|
43
34
|
should "should work with a named_scope" do
|
44
|
-
assert_equal Main.newer_than(2.days.
|
35
|
+
assert_equal Main.newer_than(2.days.from_now).all, []
|
36
|
+
end
|
37
|
+
|
38
|
+
should "generate proper sql for array" do
|
39
|
+
METHOD_SYMBOLS.each do |s|
|
40
|
+
|
41
|
+
if s == :ne
|
42
|
+
assert_equal Main.try_ne([1,2,3]).first, nil
|
43
|
+
elsif s == :like
|
44
|
+
assert_raises ActiveRecord::Inequality::InequalError do
|
45
|
+
assert_equal Main.try_like([1,2,3]).first, nil
|
46
|
+
end
|
47
|
+
else
|
48
|
+
assert_raises ActiveRecord::StatementInvalid do
|
49
|
+
assert_equal Main.send(:"try_#{s}", [1,2,3]).first, nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
assert_equal Main.try_ne([1,2,3]).first, nil
|
55
|
+
assert_equal Main.try_ne([1,2,3]).count, 0
|
56
|
+
end
|
57
|
+
|
58
|
+
should "generate proper sql for nil and not nil" do
|
59
|
+
METHOD_SYMBOLS.each do |s|
|
60
|
+
assert_equal Main.send(:"try_#{s}", 1).first, nil
|
61
|
+
assert_equal Main.send(:"try_#{s}", nil).first, nil unless s == :like
|
62
|
+
end
|
63
|
+
|
64
|
+
assert_raises ActiveRecord::Inequality::InequalError do
|
65
|
+
Main.try_like(nil).first
|
66
|
+
end
|
45
67
|
end
|
46
68
|
|
47
69
|
should "properly scope based on gte" do
|
@@ -76,4 +98,61 @@ class InequalOpportunityTest < Test::Unit::TestCase
|
|
76
98
|
end
|
77
99
|
end
|
78
100
|
|
101
|
+
context "Object" do
|
102
|
+
should "have gte" do
|
103
|
+
wrapped = gte(5)
|
104
|
+
assert_equal wrapped.operator, '>='
|
105
|
+
assert_equal wrapped, ActiveRecord::Inequality::GreaterThanEqual.new(5)
|
106
|
+
end
|
107
|
+
|
108
|
+
should "have gt" do
|
109
|
+
wrapped = gt(5)
|
110
|
+
assert_equal wrapped.operator, '>'
|
111
|
+
assert_equal wrapped, ActiveRecord::Inequality::GreaterThan.new(5)
|
112
|
+
end
|
113
|
+
|
114
|
+
should "have lte" do
|
115
|
+
wrapped = lte(5)
|
116
|
+
assert_equal wrapped.operator, '<='
|
117
|
+
assert_equal wrapped, ActiveRecord::Inequality::LessThanEqual.new(5)
|
118
|
+
end
|
119
|
+
|
120
|
+
should "have lt" do
|
121
|
+
wrapped = lt(5)
|
122
|
+
assert_equal wrapped.operator, '<'
|
123
|
+
assert_equal wrapped, ActiveRecord::Inequality::LessThan.new(5)
|
124
|
+
end
|
125
|
+
|
126
|
+
should "have ne" do
|
127
|
+
wrapped = ne(5)
|
128
|
+
assert_equal wrapped.operator, '<>'
|
129
|
+
assert_equal wrapped, ActiveRecord::Inequality::NotEqual.new(5)
|
130
|
+
end
|
131
|
+
|
132
|
+
should "have a different operator when calling ne w/ nil" do
|
133
|
+
wrapped = ne(nil)
|
134
|
+
assert_equal wrapped.operator, 'IS NOT'
|
135
|
+
assert_equal wrapped, ActiveRecord::Inequality::NotEqual.new(nil)
|
136
|
+
end
|
137
|
+
|
138
|
+
should "have like" do
|
139
|
+
wrapped = like('ryan')
|
140
|
+
assert_equal wrapped.operator, 'LIKE'
|
141
|
+
assert_equal wrapped, ActiveRecord::Inequality::Like.new('ryan')
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
context "expand_range_bind_variables_orig" do
|
147
|
+
should "return a proper array" do
|
148
|
+
range_start = 1
|
149
|
+
range_end = 9
|
150
|
+
|
151
|
+
input = [{:a => 1}, (range_start..range_end), "Yo", {:c => 'd'}, 23, [1,2,3]]
|
152
|
+
res = ActiveRecord::Base.send :expand_range_bind_variables_orig, input
|
153
|
+
|
154
|
+
assert_equal res, [range_start, range_end, "Yo", 23, [1,2,3]]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
79
158
|
end
|