case_insensitive_arel 0.1.2 → 0.2.0
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/Gemfile +3 -2
- data/Gemfile.lock +19 -4
- data/README.rdoc +15 -1
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/case_insensitive_arel.gemspec +17 -14
- data/lib/case_insensitive_arel.rb +18 -2
- data/test/helper.rb +1 -1
- data/test/support/fake_record.rb +10 -11
- data/test/test_comparisons.rb +5 -0
- data/test/test_joins.rb +2 -2
- metadata +38 -24
data/Gemfile
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
2
|
|
3
|
-
gem "arel", "
|
4
|
-
gem 'activesupport', '
|
3
|
+
gem "arel", "~> 2.2.1"
|
4
|
+
gem 'activesupport', '~> 3.1.0'
|
5
5
|
|
6
6
|
group :development do
|
7
7
|
gem "shoulda", ">= 0"
|
8
8
|
gem "bundler", "~> 1.0.0"
|
9
9
|
gem "jeweler", "~> 1.5.2"
|
10
10
|
gem "rcov", ">= 0"
|
11
|
+
gem "pry"
|
11
12
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,24 +1,39 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activesupport (3.0
|
5
|
-
|
4
|
+
activesupport (3.1.0)
|
5
|
+
multi_json (~> 1.0)
|
6
|
+
arel (2.2.1)
|
7
|
+
coderay (0.9.8)
|
6
8
|
git (1.2.5)
|
7
9
|
jeweler (1.5.2)
|
8
10
|
bundler (~> 1.0.0)
|
9
11
|
git (>= 1.2.5)
|
10
12
|
rake
|
13
|
+
method_source (0.6.5)
|
14
|
+
ruby_parser (>= 2.0.5)
|
15
|
+
multi_json (1.0.3)
|
16
|
+
pry (0.9.5)
|
17
|
+
coderay (>= 0.9.8)
|
18
|
+
method_source (>= 0.6.5)
|
19
|
+
ruby_parser (>= 2.0.5)
|
20
|
+
slop (~> 2.1.0)
|
11
21
|
rake (0.8.7)
|
12
22
|
rcov (0.9.9)
|
23
|
+
ruby_parser (2.3.0)
|
24
|
+
sexp_processor (~> 3.0)
|
25
|
+
sexp_processor (3.0.6)
|
13
26
|
shoulda (2.11.3)
|
27
|
+
slop (2.1.0)
|
14
28
|
|
15
29
|
PLATFORMS
|
16
30
|
ruby
|
17
31
|
|
18
32
|
DEPENDENCIES
|
19
|
-
activesupport (
|
20
|
-
arel (
|
33
|
+
activesupport (~> 3.1.0)
|
34
|
+
arel (~> 2.2.1)
|
21
35
|
bundler (~> 1.0.0)
|
22
36
|
jeweler (~> 1.5.2)
|
37
|
+
pry
|
23
38
|
rcov
|
24
39
|
shoulda
|
data/README.rdoc
CHANGED
@@ -66,7 +66,7 @@ As an example, you could add this code to your app if you wanted to use lowercas
|
|
66
66
|
|
67
67
|
Due to the wrapping of column names with function calls, certain DBMS' optimizers may ignore indexes on those columns
|
68
68
|
that might otherwise be used for a query. If supported by your DBMS, you may be able to create a special index on
|
69
|
-
these columns to help out wih your query. As an example, Oracle supports
|
69
|
+
these columns to help out wih your query. As an example, Oracle supports function-based indexes.
|
70
70
|
|
71
71
|
For more information, please refer to your DBMS's documentation.
|
72
72
|
|
@@ -80,6 +80,20 @@ database adapters.
|
|
80
80
|
Rather than risk madness, I didn't even bother trying to make this work with custom SQL. Stick with Arel and there
|
81
81
|
won't be any issues.
|
82
82
|
|
83
|
+
=== Converting Numeric Values?
|
84
|
+
|
85
|
+
If Arel encounters a string value, it will convert it using the conversion_proc even if it contains a numeric
|
86
|
+
value being compared to a numeric column. In the typical case of looking up Rails' values that originate from the params
|
87
|
+
hash (e.g. <tt>params[:id]</tt> ) this could result in SQL like:
|
88
|
+
|
89
|
+
select * from "table" where "table"."id" = UPPER(3)
|
90
|
+
|
91
|
+
Since most DBMSes will implicitly convert the result of the function to a numeric, there should be no impact on the
|
92
|
+
query optimizer. If you absolutely must inhibit this function call from being generated, convert the string to a numeric
|
93
|
+
value before Arel sees it. e.g.:
|
94
|
+
|
95
|
+
Something.find(params[:id].to_i)
|
96
|
+
|
83
97
|
== Contributing
|
84
98
|
|
85
99
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
data/Rakefile
CHANGED
@@ -21,8 +21,8 @@ Jeweler::Tasks.new do |gem|
|
|
21
21
|
gem.authors = ["Steve Lamotte"]
|
22
22
|
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
23
|
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
-
gem.add_runtime_dependency 'arel', '>= 2.
|
25
|
-
gem.add_runtime_dependency 'activesupport', '>=
|
24
|
+
gem.add_runtime_dependency 'arel', '>= 2.2.1'
|
25
|
+
gem.add_runtime_dependency 'activesupport', '>= 3.1.0'
|
26
26
|
end
|
27
27
|
Jeweler::RubygemsDotOrgTasks.new
|
28
28
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{case_insensitive_arel}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Steve Lamotte"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-09-16}
|
13
13
|
s.description = %q{If you're using Oracle or another DBMS that has case-insensitive collation sequences, and you don't want to litter your database access code with case conversions, this gem is for you.}
|
14
14
|
s.email = %q{steve@lexor.ca}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -52,33 +52,36 @@ Gem::Specification.new do |s|
|
|
52
52
|
s.specification_version = 3
|
53
53
|
|
54
54
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
|
-
s.add_runtime_dependency(%q<arel>, ["
|
56
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
55
|
+
s.add_runtime_dependency(%q<arel>, ["~> 2.2.1"])
|
56
|
+
s.add_runtime_dependency(%q<activesupport>, ["~> 3.1.0"])
|
57
57
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
58
58
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
59
59
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
60
60
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
61
|
-
s.
|
62
|
-
s.add_runtime_dependency(%q<
|
61
|
+
s.add_development_dependency(%q<pry>, [">= 0"])
|
62
|
+
s.add_runtime_dependency(%q<arel>, [">= 2.2.1"])
|
63
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 3.1.0"])
|
63
64
|
else
|
64
|
-
s.add_dependency(%q<arel>, ["
|
65
|
-
s.add_dependency(%q<activesupport>, ["
|
65
|
+
s.add_dependency(%q<arel>, ["~> 2.2.1"])
|
66
|
+
s.add_dependency(%q<activesupport>, ["~> 3.1.0"])
|
66
67
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
67
68
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
68
69
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
69
70
|
s.add_dependency(%q<rcov>, [">= 0"])
|
70
|
-
s.add_dependency(%q<
|
71
|
-
s.add_dependency(%q<
|
71
|
+
s.add_dependency(%q<pry>, [">= 0"])
|
72
|
+
s.add_dependency(%q<arel>, [">= 2.2.1"])
|
73
|
+
s.add_dependency(%q<activesupport>, [">= 3.1.0"])
|
72
74
|
end
|
73
75
|
else
|
74
|
-
s.add_dependency(%q<arel>, ["
|
75
|
-
s.add_dependency(%q<activesupport>, ["
|
76
|
+
s.add_dependency(%q<arel>, ["~> 2.2.1"])
|
77
|
+
s.add_dependency(%q<activesupport>, ["~> 3.1.0"])
|
76
78
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
77
79
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
78
80
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
79
81
|
s.add_dependency(%q<rcov>, [">= 0"])
|
80
|
-
s.add_dependency(%q<
|
81
|
-
s.add_dependency(%q<
|
82
|
+
s.add_dependency(%q<pry>, [">= 0"])
|
83
|
+
s.add_dependency(%q<arel>, [">= 2.2.1"])
|
84
|
+
s.add_dependency(%q<activesupport>, [">= 3.1.0"])
|
82
85
|
end
|
83
86
|
end
|
84
87
|
|
@@ -7,6 +7,7 @@ module Arel #:nodoc:
|
|
7
7
|
# List of Arel types that should be converted to make them comparable in a case-insensitive fashion
|
8
8
|
%w(Arel_Attributes_Attribute Arel_Attributes_String String).each do |arel_type_name|
|
9
9
|
define_method "visit_#{arel_type_name}_with_case_insensitive" do |obj|
|
10
|
+
# Get original value
|
10
11
|
value = send("visit_#{arel_type_name}_without_case_insensitive", obj)
|
11
12
|
|
12
13
|
# Return either the original case-sensitive value or a converted version
|
@@ -31,8 +32,23 @@ module Arel #:nodoc:
|
|
31
32
|
|
32
33
|
# Determines whether an object should be converted to case-insensitive form or not
|
33
34
|
def self.leave_case_sensitive?(obj)
|
34
|
-
|
35
|
-
|
35
|
+
if obj.is_a?(Arel::Attributes::Attribute) and obj.relation.is_a?(Arel::Table)
|
36
|
+
# Determine the attribute's type
|
37
|
+
cn = obj.relation.engine.connection_pool.connection
|
38
|
+
column = if cn.is_a?(Hash)
|
39
|
+
# This works for FakeRecord
|
40
|
+
cn.columns[obj.relation.name][obj.name.to_s]
|
41
|
+
else
|
42
|
+
# This works for Oracle Enhanced
|
43
|
+
cn.columns(obj.relation.name).find{|col|col.name.eql?(obj.name.to_s)}
|
44
|
+
end
|
45
|
+
column_type = column ? column.type : nil
|
46
|
+
return true unless column_type == :string
|
47
|
+
end
|
48
|
+
|
49
|
+
# Last checks
|
50
|
+
obj.respond_to?(:do_not_make_case_insensitive?) or
|
51
|
+
(obj.respond_to?(:name) && obj.name.eql?('*'))
|
36
52
|
end
|
37
53
|
|
38
54
|
private
|
data/test/helper.rb
CHANGED
data/test/support/fake_record.rb
CHANGED
@@ -3,37 +3,36 @@ module FakeRecord
|
|
3
3
|
end
|
4
4
|
|
5
5
|
class Connection
|
6
|
-
attr_reader :tables, :columns_hash
|
6
|
+
attr_reader :tables, :columns_hash, :visitor
|
7
7
|
|
8
|
-
def initialize
|
8
|
+
def initialize(visitor)
|
9
9
|
@tables = %w{ users photos developers products}
|
10
10
|
@columns = {
|
11
11
|
'users' => [
|
12
|
-
Column.new('id', :
|
12
|
+
Column.new('id', :number),
|
13
13
|
Column.new('name', :string),
|
14
14
|
Column.new('bool', :boolean),
|
15
15
|
Column.new('created_at', :date)
|
16
16
|
],
|
17
|
-
'photos' => [
|
18
|
-
Column.new('id', :integer),
|
19
|
-
Column.new('user_name', :string),
|
20
|
-
Column.new('price', :decimal)
|
21
|
-
],
|
22
17
|
'products' => [
|
23
18
|
Column.new('id', :integer),
|
19
|
+
Column.new('name', :string),
|
24
20
|
Column.new('price', :decimal)
|
25
21
|
]
|
26
22
|
}
|
27
23
|
@columns_hash = {
|
28
24
|
'users' => Hash[@columns['users'].map { |x| [x.name, x] }],
|
29
|
-
'photos' => Hash[@columns['photos'].map { |x| [x.name, x] }],
|
30
25
|
'products' => Hash[@columns['products'].map { |x| [x.name, x] }]
|
31
26
|
}
|
32
27
|
@primary_keys = {
|
33
28
|
'users' => 'id',
|
34
|
-
'photos' => 'id',
|
35
29
|
'products' => 'id'
|
36
30
|
}
|
31
|
+
@visitor = visitor
|
32
|
+
end
|
33
|
+
|
34
|
+
def columns(table_name)
|
35
|
+
@columns[table_name]
|
37
36
|
end
|
38
37
|
|
39
38
|
def primary_key name
|
@@ -85,7 +84,7 @@ module FakeRecord
|
|
85
84
|
|
86
85
|
def initialize
|
87
86
|
@spec = Spec.new(:adapter => 'america')
|
88
|
-
@connection = Connection.new
|
87
|
+
@connection = Connection.new(Arel::Visitors::ToSql.new(self))
|
89
88
|
end
|
90
89
|
|
91
90
|
def with_connection
|
data/test/test_comparisons.rb
CHANGED
@@ -12,6 +12,8 @@ class TestComparisons < Test::Unit::TestCase
|
|
12
12
|
should_be_like @users.where(@users[:name].in(%w(Steve Barb))).to_sql, "SELECT FROM \"users\" WHERE UPPER(\"users\".\"name\") IN (UPPER('Steve'), UPPER('Barb'))"
|
13
13
|
should_be_like @users.where(@users[:name].not_in(%w(Steve Barb))).to_sql, "SELECT FROM \"users\" WHERE UPPER(\"users\".\"name\") NOT IN (UPPER('Steve'), UPPER('Barb'))"
|
14
14
|
should_be_like @users.where(@users[:name].matches_any(%w(Steve Barb))).to_sql, "SELECT FROM \"users\" WHERE (UPPER(\"users\".\"name\") LIKE UPPER('Steve') OR UPPER(\"users\".\"name\") LIKE UPPER('Barb'))"
|
15
|
+
should_be_like @users.where(@users[:id].eq(1)).to_sql, "SELECT FROM \"users\" WHERE \"users\".\"id\" = 1"
|
16
|
+
should_be_like @users.where(@users[:bool].eq(true)).to_sql, "SELECT FROM \"users\" WHERE \"users\".\"bool\" = 't'"
|
15
17
|
end
|
16
18
|
|
17
19
|
should "work correctly in case-sensitive mode" do
|
@@ -25,5 +27,8 @@ class TestComparisons < Test::Unit::TestCase
|
|
25
27
|
should_be_like @users.where(@users[:name].in(%w(Steve Barb))).to_sql, "SELECT FROM \"users\" WHERE \"users\".\"name\" IN ('Steve', 'Barb')"
|
26
28
|
should_be_like @users.where(@users[:name].not_in(%w(Steve Barb))).to_sql, "SELECT FROM \"users\" WHERE \"users\".\"name\" NOT IN ('Steve', 'Barb')"
|
27
29
|
should_be_like @users.where(@users[:name].matches_any(%w(Steve Barb))).to_sql, "SELECT FROM \"users\" WHERE (\"users\".\"name\" LIKE 'Steve' OR \"users\".\"name\" LIKE 'Barb')"
|
30
|
+
should_be_like @users.where(@users[:id].eq(1)).to_sql, "SELECT FROM \"users\" WHERE \"users\".\"id\" = 1"
|
31
|
+
should_be_like @users.where(@users[:id].eq(1)).to_sql, "SELECT FROM \"users\" WHERE \"users\".\"id\" = 1"
|
32
|
+
should_be_like @users.where(@users[:bool].eq(true)).to_sql, "SELECT FROM \"users\" WHERE \"users\".\"bool\" = 't'"
|
28
33
|
end
|
29
34
|
end
|
data/test/test_joins.rb
CHANGED
@@ -3,13 +3,13 @@ require "helper"
|
|
3
3
|
class TestJoins < Test::Unit::TestCase
|
4
4
|
should "work correctly in case-insensitive mode" do
|
5
5
|
Arel::CaseInsensitive.case_insensitive = true
|
6
|
-
should_be_like @users.join(@
|
6
|
+
should_be_like @users.join(@products).on(@users[:name].eq(@products[:name])).to_sql, "SELECT FROM \"users\" INNER JOIN \"products\" ON UPPER(\"users\".\"name\") = UPPER(\"products\".\"name\")"
|
7
7
|
should_be_like @users.join(@users2).on(@users[:name].eq(@users2[:name])).to_sql, "SELECT FROM \"users\" INNER JOIN \"users\" \"u2\" ON UPPER(\"users\".\"name\") = UPPER(\"u2\".\"name\")"
|
8
8
|
end
|
9
9
|
|
10
10
|
should "work correctly in case-sensitive mode" do
|
11
11
|
Arel::CaseInsensitive.case_insensitive = false
|
12
|
-
should_be_like @users.join(@
|
12
|
+
should_be_like @users.join(@products).on(@users[:name].eq(@products[:name])).to_sql, "SELECT FROM \"users\" INNER JOIN \"products\" ON \"users\".\"name\" = \"products\".\"name\""
|
13
13
|
should_be_like @users.join(@users2).on(@users[:name].eq(@users2[:name])).to_sql, "SELECT FROM \"users\" INNER JOIN \"users\" \"u2\" ON \"users\".\"name\" = \"u2\".\"name\""
|
14
14
|
end
|
15
15
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: case_insensitive_arel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 1
|
9
8
|
- 2
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Steve Lamotte
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-09-16 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -24,14 +24,14 @@ dependencies:
|
|
24
24
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 5
|
30
30
|
segments:
|
31
31
|
- 2
|
32
|
-
-
|
33
|
-
-
|
34
|
-
version: 2.
|
32
|
+
- 2
|
33
|
+
- 1
|
34
|
+
version: 2.2.1
|
35
35
|
requirement: *id001
|
36
36
|
type: :runtime
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -40,14 +40,14 @@ dependencies:
|
|
40
40
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
45
|
+
hash: 3
|
46
46
|
segments:
|
47
47
|
- 3
|
48
|
+
- 1
|
48
49
|
- 0
|
49
|
-
|
50
|
-
version: 3.0.0
|
50
|
+
version: 3.1.0
|
51
51
|
requirement: *id002
|
52
52
|
type: :runtime
|
53
53
|
- !ruby/object:Gem::Dependency
|
@@ -112,36 +112,50 @@ dependencies:
|
|
112
112
|
type: :development
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
prerelease: false
|
115
|
-
name:
|
115
|
+
name: pry
|
116
116
|
version_requirements: &id007 !ruby/object:Gem::Requirement
|
117
117
|
none: false
|
118
118
|
requirements:
|
119
119
|
- - ">="
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
hash:
|
121
|
+
hash: 3
|
122
122
|
segments:
|
123
|
-
- 2
|
124
123
|
- 0
|
125
|
-
|
126
|
-
version: 2.0.9
|
124
|
+
version: "0"
|
127
125
|
requirement: *id007
|
128
|
-
type: :
|
126
|
+
type: :development
|
129
127
|
- !ruby/object:Gem::Dependency
|
130
128
|
prerelease: false
|
131
|
-
name:
|
129
|
+
name: arel
|
132
130
|
version_requirements: &id008 !ruby/object:Gem::Requirement
|
133
131
|
none: false
|
134
132
|
requirements:
|
135
133
|
- - ">="
|
136
134
|
- !ruby/object:Gem::Version
|
137
|
-
hash:
|
135
|
+
hash: 5
|
138
136
|
segments:
|
139
137
|
- 2
|
140
|
-
-
|
141
|
-
-
|
142
|
-
version: 2.
|
138
|
+
- 2
|
139
|
+
- 1
|
140
|
+
version: 2.2.1
|
143
141
|
requirement: *id008
|
144
142
|
type: :runtime
|
143
|
+
- !ruby/object:Gem::Dependency
|
144
|
+
prerelease: false
|
145
|
+
name: activesupport
|
146
|
+
version_requirements: &id009 !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
hash: 3
|
152
|
+
segments:
|
153
|
+
- 3
|
154
|
+
- 1
|
155
|
+
- 0
|
156
|
+
version: 3.1.0
|
157
|
+
requirement: *id009
|
158
|
+
type: :runtime
|
145
159
|
description: If you're using Oracle or another DBMS that has case-insensitive collation sequences, and you don't want to litter your database access code with case conversions, this gem is for you.
|
146
160
|
email: steve@lexor.ca
|
147
161
|
executables: []
|