searchlogic 2.4.12 → 2.4.13
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/VERSION.yml +1 -1
- data/lib/searchlogic/core_ext/object.rb +4 -2
- data/lib/searchlogic/core_ext/proc.rb +7 -1
- data/lib/searchlogic/named_scopes/association_conditions.rb +1 -1
- data/lib/searchlogic/named_scopes/conditions.rb +18 -17
- data/lib/searchlogic/named_scopes/or_conditions.rb +1 -1
- data/lib/searchlogic/search.rb +21 -6
- data/searchlogic.gemspec +2 -2
- data/spec/core_ext/object_spec.rb +4 -2
- data/spec/core_ext/proc_spec.rb +2 -3
- data/spec/named_scopes/conditions_spec.rb +3 -3
- data/spec/search_spec.rb +6 -0
- data/spec/spec_helper.rb +3 -0
- metadata +3 -3
data/VERSION.yml
CHANGED
@@ -31,9 +31,11 @@ module Searchlogic
|
|
31
31
|
# If you want something else, you need to specify it as I did in the above example. Comments are appreciated
|
32
32
|
# on this, if you know of a better solution please let me know. But this is the best I could come up with,
|
33
33
|
# without being intrusive and altering default behavior.
|
34
|
-
def searchlogic_lambda(type = :string, &block)
|
34
|
+
def searchlogic_lambda(type = :string, options = {}, &block)
|
35
35
|
proc = lambda(&block)
|
36
|
-
proc.
|
36
|
+
proc.searchlogic_options ||= {}
|
37
|
+
proc.searchlogic_options[:type] = type
|
38
|
+
proc.searchlogic_options.merge!(options)
|
37
39
|
proc
|
38
40
|
end
|
39
41
|
end
|
@@ -3,7 +3,13 @@ module Searchlogic
|
|
3
3
|
module Proc # :nodoc:
|
4
4
|
def self.included(klass)
|
5
5
|
klass.class_eval do
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :searchlogic_options
|
7
|
+
|
8
|
+
def searchlogic_options
|
9
|
+
@searchlogic_options ||= {}
|
10
|
+
@searchlogic_options[:type] ||= :string
|
11
|
+
@searchlogic_options
|
12
|
+
end
|
7
13
|
end
|
8
14
|
end
|
9
15
|
end
|
@@ -71,7 +71,7 @@ module Searchlogic
|
|
71
71
|
options
|
72
72
|
else
|
73
73
|
proc_args = arity_args(arity)
|
74
|
-
arg_type = (scope_options.respond_to?(:
|
74
|
+
arg_type = (scope_options.respond_to?(:searchlogic_options) && scope_options.searchlogic_options[:type]) || :string
|
75
75
|
|
76
76
|
eval <<-"end_eval"
|
77
77
|
searchlogic_lambda(:#{arg_type}) { |#{proc_args.join(",")}|
|
@@ -108,33 +108,34 @@ module Searchlogic
|
|
108
108
|
|
109
109
|
def create_primary_condition(column, condition)
|
110
110
|
column_type = columns_hash[column.to_s].type
|
111
|
+
skip_conversion = skip_time_zone_conversion_for_attributes.include?(columns_hash[column.to_s].name.to_sym)
|
111
112
|
match_keyword = ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? "ILIKE" : "LIKE"
|
112
113
|
|
113
114
|
scope_options = case condition.to_s
|
114
115
|
when /^equals/
|
115
|
-
scope_options(condition, column_type, lambda { |a| attribute_condition("#{table_name}.#{column}", a) })
|
116
|
+
scope_options(condition, column_type, lambda { |a| attribute_condition("#{table_name}.#{column}", a) }, :skip_conversion => skip_conversion)
|
116
117
|
when /^does_not_equal/
|
117
|
-
scope_options(condition, column_type, "#{table_name}.#{column} != ?")
|
118
|
+
scope_options(condition, column_type, "#{table_name}.#{column} != ?", :skip_conversion => skip_conversion)
|
118
119
|
when /^less_than_or_equal_to/
|
119
|
-
scope_options(condition, column_type, "#{table_name}.#{column} <= ?")
|
120
|
+
scope_options(condition, column_type, "#{table_name}.#{column} <= ?", :skip_conversion => skip_conversion)
|
120
121
|
when /^less_than/
|
121
|
-
scope_options(condition, column_type, "#{table_name}.#{column} < ?")
|
122
|
+
scope_options(condition, column_type, "#{table_name}.#{column} < ?", :skip_conversion => skip_conversion)
|
122
123
|
when /^greater_than_or_equal_to/
|
123
|
-
scope_options(condition, column_type, "#{table_name}.#{column} >= ?")
|
124
|
+
scope_options(condition, column_type, "#{table_name}.#{column} >= ?", :skip_conversion => skip_conversion)
|
124
125
|
when /^greater_than/
|
125
|
-
scope_options(condition, column_type, "#{table_name}.#{column} > ?")
|
126
|
+
scope_options(condition, column_type, "#{table_name}.#{column} > ?", :skip_conversion => skip_conversion)
|
126
127
|
when /^like/
|
127
|
-
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :like)
|
128
|
+
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :like)
|
128
129
|
when /^not_like/
|
129
|
-
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :like)
|
130
|
+
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :like)
|
130
131
|
when /^begins_with/
|
131
|
-
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :begins_with)
|
132
|
+
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :begins_with)
|
132
133
|
when /^not_begin_with/
|
133
|
-
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :begins_with)
|
134
|
+
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :begins_with)
|
134
135
|
when /^ends_with/
|
135
|
-
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :ends_with)
|
136
|
+
scope_options(condition, column_type, "#{table_name}.#{column} #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :ends_with)
|
136
137
|
when /^not_end_with/
|
137
|
-
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :ends_with)
|
138
|
+
scope_options(condition, column_type, "#{table_name}.#{column} NOT #{match_keyword} ?", :skip_conversion => skip_conversion, :value_modifier => :ends_with)
|
138
139
|
when "null"
|
139
140
|
{:conditions => "#{table_name}.#{column} IS NULL"}
|
140
141
|
when "not_null"
|
@@ -153,13 +154,13 @@ module Searchlogic
|
|
153
154
|
# This method helps cut down on defining scope options for conditions that allow *_any or *_all conditions.
|
154
155
|
# Kepp in mind that the lambdas get cached in a method, so you want to keep the contents of the lambdas as
|
155
156
|
# fast as possible, which is why I didn't do the case statement inside of the lambda.
|
156
|
-
def scope_options(condition, column_type, sql,
|
157
|
+
def scope_options(condition, column_type, sql, options = {})
|
157
158
|
case condition.to_s
|
158
159
|
when /_(any|all)$/
|
159
|
-
searchlogic_lambda(column_type) { |*values|
|
160
|
+
searchlogic_lambda(column_type, :skip_conversion => options[:skip_conversion]) { |*values|
|
160
161
|
return {} if values.empty?
|
161
162
|
values.flatten!
|
162
|
-
values.collect! { |value| value_with_modifier(value, value_modifier) }
|
163
|
+
values.collect! { |value| value_with_modifier(value, options[:value_modifier]) }
|
163
164
|
|
164
165
|
join = $1 == "any" ? " OR " : " AND "
|
165
166
|
scope_sql = values.collect { |value| sql.is_a?(Proc) ? sql.call(value) : sql }.join(join)
|
@@ -167,8 +168,8 @@ module Searchlogic
|
|
167
168
|
{:conditions => [scope_sql, *expand_range_bind_variables(values)]}
|
168
169
|
}
|
169
170
|
else
|
170
|
-
searchlogic_lambda(column_type) { |*values|
|
171
|
-
values.collect! { |value| value_with_modifier(value, value_modifier) }
|
171
|
+
searchlogic_lambda(column_type, :skip_conversion => options[:skip_conversion]) { |*values|
|
172
|
+
values.collect! { |value| value_with_modifier(value, options[:value_modifier]) }
|
172
173
|
|
173
174
|
scope_sql = sql.is_a?(Proc) ? sql.call(*values) : sql
|
174
175
|
|
@@ -121,7 +121,7 @@ module Searchlogic
|
|
121
121
|
scopes_options = scopes.collect { |scope, *args| send(scope, *args).proxy_options }
|
122
122
|
# We're using first scope to determine column's type
|
123
123
|
scope = named_scope_options(scopes.first)
|
124
|
-
column_type = scope.respond_to?(:
|
124
|
+
column_type = scope.respond_to?(:searchlogic_options) ? scope.searchlogic_options[:type] : :string
|
125
125
|
named_scope scopes.join("_or_"), searchlogic_lambda(column_type) { |*args|
|
126
126
|
merge_scopes_with_or(scopes.collect { |scope| clone.send(scope, *args) })
|
127
127
|
}
|
data/lib/searchlogic/search.rb
CHANGED
@@ -90,7 +90,14 @@ module Searchlogic
|
|
90
90
|
if setter?(name)
|
91
91
|
if scope?(scope_name)
|
92
92
|
if args.size == 1
|
93
|
-
write_condition(
|
93
|
+
write_condition(
|
94
|
+
condition_name,
|
95
|
+
type_cast(
|
96
|
+
args.first,
|
97
|
+
cast_type(scope_name),
|
98
|
+
scope_options(scope_name).respond_to?(:searchlogic_options) ? scope_options(scope_name).searchlogic_options : {}
|
99
|
+
)
|
100
|
+
)
|
94
101
|
else
|
95
102
|
write_condition(condition_name, args)
|
96
103
|
end
|
@@ -169,18 +176,22 @@ module Searchlogic
|
|
169
176
|
klass.scopes.key?(scope_name) || klass.condition?(scope_name)
|
170
177
|
end
|
171
178
|
|
172
|
-
def
|
179
|
+
def scope_options(name)
|
173
180
|
klass.send(name, nil) if !klass.respond_to?(name) # We need to set up the named scope if it doesn't exist, so we can get a value for named_scope_options
|
174
|
-
|
181
|
+
klass.named_scope_options(name)
|
182
|
+
end
|
183
|
+
|
184
|
+
def cast_type(name)
|
185
|
+
named_scope_options = scope_options(name)
|
175
186
|
arity = klass.named_scope_arity(name)
|
176
187
|
if !arity || arity == 0
|
177
188
|
:boolean
|
178
189
|
else
|
179
|
-
named_scope_options.respond_to?(:
|
190
|
+
named_scope_options.respond_to?(:searchlogic_options) ? named_scope_options.searchlogic_options[:type] : :string
|
180
191
|
end
|
181
192
|
end
|
182
193
|
|
183
|
-
def type_cast(value, type)
|
194
|
+
def type_cast(value, type, options = {})
|
184
195
|
case value
|
185
196
|
when Array
|
186
197
|
value.collect { |v| type_cast(v, type) }
|
@@ -195,7 +206,11 @@ module Searchlogic
|
|
195
206
|
|
196
207
|
if Time.zone && casted_value.is_a?(Time)
|
197
208
|
if value.is_a?(String)
|
198
|
-
|
209
|
+
if options[:skip_conversion]
|
210
|
+
casted_value.utc
|
211
|
+
else
|
212
|
+
(casted_value + (Time.zone.utc_offset * -1)).in_time_zone
|
213
|
+
end
|
199
214
|
else
|
200
215
|
casted_value.in_time_zone
|
201
216
|
end
|
data/searchlogic.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{searchlogic}
|
8
|
-
s.version = "2.4.
|
8
|
+
s.version = "2.4.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ben Johnson of Binary Logic"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-04-04}
|
13
13
|
s.description = %q{Searchlogic makes using ActiveRecord named scopes easier and less repetitive.}
|
14
14
|
s.email = %q{bjohnson@binarylogic.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
2
|
|
3
3
|
describe "Object" do
|
4
|
-
it "should accept and pass the argument to the
|
5
|
-
searchlogic_lambda(:integer) {}
|
4
|
+
it "should accept and pass the argument to the searchlogic_options" do
|
5
|
+
proc = searchlogic_lambda(:integer, :test => :value) {}
|
6
|
+
proc.searchlogic_options[:type].should == :integer
|
7
|
+
proc.searchlogic_options[:test].should == :value
|
6
8
|
end
|
7
9
|
end
|
data/spec/core_ext/proc_spec.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
2
|
|
3
3
|
describe "Proc" do
|
4
|
-
it "should have a
|
4
|
+
it "should have a searchlogic_options accessor" do
|
5
5
|
p = Proc.new {}
|
6
|
-
p.
|
7
|
-
p.searchlogic_arg_type.should == :integer
|
6
|
+
p.searchlogic_options[:type] = :integer
|
8
7
|
end
|
9
8
|
end
|
@@ -290,17 +290,17 @@ describe "Conditions" do
|
|
290
290
|
context "searchlogic lambda" do
|
291
291
|
it "should be a string" do
|
292
292
|
User.username_like("test")
|
293
|
-
User.named_scope_options(:username_like).
|
293
|
+
User.named_scope_options(:username_like).searchlogic_options[:type].should == :string
|
294
294
|
end
|
295
295
|
|
296
296
|
it "should be an integer" do
|
297
297
|
User.id_gt(10)
|
298
|
-
User.named_scope_options(:id_gt).
|
298
|
+
User.named_scope_options(:id_gt).searchlogic_options[:type].should == :integer
|
299
299
|
end
|
300
300
|
|
301
301
|
it "should be a float" do
|
302
302
|
Order.total_gt(10)
|
303
|
-
Order.named_scope_options(:total_gt).
|
303
|
+
Order.named_scope_options(:total_gt).searchlogic_options[:type].should == :float
|
304
304
|
end
|
305
305
|
end
|
306
306
|
|
data/spec/search_spec.rb
CHANGED
@@ -290,6 +290,12 @@ describe "Search" do
|
|
290
290
|
search.created_at_after.should == Time.zone.parse("Jan 1, 2009 9:33AM")
|
291
291
|
end
|
292
292
|
|
293
|
+
it "should skip time zone conversion for attributes skipped" do
|
294
|
+
search = User.search
|
295
|
+
search.whatever_at_after = "Jan 1, 2009 9:33AM"
|
296
|
+
search.whatever_at_after.should == Time.parse("Jan 1, 2009 9:33AM").utc
|
297
|
+
end
|
298
|
+
|
293
299
|
it "should convert the time to the current zone" do
|
294
300
|
search = Order.search
|
295
301
|
now = Time.now
|
data/spec/spec_helper.rb
CHANGED
@@ -42,6 +42,7 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
42
42
|
t.integer :age
|
43
43
|
t.boolean :male
|
44
44
|
t.string :some_type_id
|
45
|
+
t.datetime :whatever_at
|
45
46
|
end
|
46
47
|
|
47
48
|
create_table :carts do |t|
|
@@ -99,6 +100,8 @@ Spec::Runner.configure do |config|
|
|
99
100
|
has_many :orders, :dependent => :destroy
|
100
101
|
has_many :orders_big, :class_name => 'Order', :conditions => 'total > 100'
|
101
102
|
has_and_belongs_to_many :user_groups
|
103
|
+
|
104
|
+
self.skip_time_zone_conversion_for_attributes = [:whatever_at]
|
102
105
|
end
|
103
106
|
|
104
107
|
class Order < ActiveRecord::Base
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 2
|
7
7
|
- 4
|
8
|
-
-
|
9
|
-
version: 2.4.
|
8
|
+
- 13
|
9
|
+
version: 2.4.13
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ben Johnson of Binary Logic
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-04-04 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|