searchlogic 1.5.6 → 1.5.7

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,4 +1,9 @@
1
- == 1.5.6 released 2008-11-17
1
+ == 1.5.7 released 2008-11-30
2
+
3
+ * Fixed how grouping works, you can now specify "and_group" and "or_group", just like you can with conditions.
4
+ * Specifying a join type will take priority. So "and_name_like" will ALWAYS join with AND, even is any = true for the search.
5
+
6
+ == 1.5.6 released 2008-11-29
2
7
 
3
8
  * The order conditions are set is now relevant and will be reflected in the SQL. Setting a condition first will make it first in the SQL, setting a condition last will make it last in the SQL.
4
9
  * The above allows for prefixing any condition with and_ or or_. Thus letting you create somewhat more complex queries, since the order matters.
data/README.rdoc CHANGED
@@ -1,6 +1,17 @@
1
1
  = Searchlogic
2
2
 
3
- Searchlogic is object based ActiveRecord searching, ordering, and pagination all in one. It's a simple, quick, all inclusive package for displaying data in your application.
3
+ Searchlogic's goal is to keep your application free of searching clutter. It's is an ActiveRecord extension that allows you to perform simple and complex searches with a hash. Why is this great? Because GET and POST parameters are a hash. This means if you can execute a search with a hash, you can execute a search using GET or POST parameters. This makes searching in your application dead simple and clutter free:
4
+
5
+ @search = User.new_search(params[:search])
6
+ @users = @search.all
7
+
8
+ Now think about it this way. How are resources / web services used? Through GET and POST. All of a sudden you have a resource that comes preloaded with a *very* flexible searching functionality, all with 2 lines of code.
9
+
10
+ What about your interface? What is an HTML form's sole purpose? It's to send GET or POST parameters to a URI. Now you can build a form that represents a search. Meaning adding a condition to your search is as easy as adding a field to your form. That's what the @search object above is all about. You can pass that right into your form builder and build a form just like you would for an ActiveRecord object. Now you can use that handy form builder that you like you use and get rid of even more searching clutter in your views.
11
+
12
+ Searching in your application has never been cleaner, more flexible, or easier.
13
+
14
+ These are just the basics of Searchlogic, it can do a lot more, including pagination, ordering data, etc. All of these things are just as simple, if not simpler. Keep reading to find out everything it can do.
4
15
 
5
16
  == Helpful links
6
17
 
@@ -238,16 +249,16 @@ Group with a block:
238
249
 
239
250
  Group with a hash:
240
251
 
241
- search = User.new_search(:conditions => {
242
- :id_gt => 2,
243
- :group => [
252
+ search = User.new_search(:conditions => [
253
+ {:id_gt => 2},
254
+ {:group => [
244
255
  {:first_name_like => "Ben"},
245
- {
246
- :last_name_like => "Johnson",
247
- :group => {:email_ends_with => "binarylogic.com"}
248
- }
249
- ]
250
- })
256
+ [
257
+ {:last_name_like => "Johnson"},
258
+ {:group => {:email_ends_with => "binarylogic.com"}}
259
+ ]
260
+ ]}
261
+ ])
251
262
  # => id > 2 AND (first_name like '%Ben%') AND (last_name like '%Johnson%' AND (email like '%binarylogic.com'))
252
263
 
253
264
  I want to end this by saying Searchlog was never meant to replace SQL, name_scopes, etc. If you need to perform complex searching there is nothing wrong with resorting to a named scope or using the traditional search methods. In fact, search logic plays nice with named_scopes anyways, so you can combine the 2 if needed:
@@ -7,7 +7,7 @@ module Searchlogic
7
7
  class Base
8
8
  include Shared::Utilities
9
9
 
10
- attr_accessor :any, :column, :column_for_type_cast, :column_sql, :column_sql_format, :klass, :object_name, :table_name
10
+ attr_accessor :column, :column_for_type_cast, :column_sql, :column_sql_format, :explicit_any, :klass, :object_name, :table_name
11
11
  class_inheritable_accessor :handle_array_value, :ignore_meaningless_value, :join_arrays_with_or, :value_type
12
12
  self.ignore_meaningless_value = true
13
13
 
@@ -61,8 +61,8 @@ module Searchlogic
61
61
  end
62
62
  end
63
63
 
64
- def any? # :nodoc:
65
- any == true
64
+ def explicit_any? # :nodoc:
65
+ explicit_any == true
66
66
  end
67
67
 
68
68
  # Substitutes string vars with table and column name. Allows us to switch the column and table on the fly and have the condition update appropriately.
@@ -2,7 +2,7 @@ module Searchlogic
2
2
  module Conditions
3
3
  # = Any or All
4
4
  #
5
- # Adds the ability to join all conditions wth "ANY" or "ALL".
5
+ # Adds the ability to join all conditions wth "AND" or "OR".
6
6
  module AnyOrAll
7
7
  # Determines if we should join the conditions with "AND" or "OR".
8
8
  #
@@ -11,7 +11,7 @@ module Searchlogic
11
11
  # search.conditions.any = true # will join all conditions with "or", you can also set this to "true", "1", or "yes"
12
12
  # search.conditions.any = false # will join all conditions with "and"
13
13
  def any=(value)
14
- objects.each { |object| object.any = value }
14
+ (association_objects + group_objects).each { |object| object.any = value }
15
15
  @any = value
16
16
  end
17
17
 
@@ -138,13 +138,19 @@ module Searchlogic
138
138
  def sanitize
139
139
  return @conditions if @conditions # return the conditions if the user set them with a string, aka sql conditions
140
140
  joined_conditions = nil
141
- objects.each { |object| joined_conditions = merge_conditions(joined_conditions, object.class == self.class ? scope_condition(object.sanitize) : object.sanitize, :any => object.any?, :scope => false) }
141
+ objects.each do |object|
142
+ any = !object.explicit_any.nil? && (condition?(object) || group?(object)) ? object.explicit_any? : any?
143
+ sanitized_conditions = group?(object) ? scope_condition(object.sanitize) : object.sanitize
144
+ joined_conditions = merge_conditions(joined_conditions, sanitized_conditions, :any => any)
145
+ end
142
146
  joined_conditions
143
147
  end
144
148
 
145
149
  # Allows you to set the conditions via a hash.
146
150
  def conditions=(value)
147
151
  case value
152
+ when Array
153
+ value.each { |v| self.conditions = v }
148
154
  when Hash
149
155
  remove_conditions_from_protected_assignement(value).each do |condition, condition_value|
150
156
  next if [:conditions].include?(condition.to_sym) # protect sensitive methods
@@ -198,11 +204,19 @@ module Searchlogic
198
204
 
199
205
  private
200
206
  def association_objects
201
- objects.select { |object| object.class < Base && object.class != self.class }
207
+ objects.select { |object| association?(object) }
208
+ end
209
+
210
+ def association?(object)
211
+ object.class < Base && object.class != self.class
202
212
  end
203
213
 
204
214
  def condition_objects
205
- objects.select { |object| object.class < Condition::Base }
215
+ objects.select { |object| condition?(object) }
216
+ end
217
+
218
+ def condition?(object)
219
+ object.class < Condition::Base
206
220
  end
207
221
 
208
222
  def objects
@@ -10,27 +10,62 @@ module Searchlogic
10
10
  end
11
11
 
12
12
  # Creates a new group object to set condition off of. See examples at top of class on how to use this.
13
- def group(&block)
14
- obj = self.class.new
15
- yield obj if block_given?
16
- objects << obj
17
- obj
13
+ def group(conditions = nil, forward_arrays = false, &block)
14
+ if conditions.is_a?(Array) && !forward_arrays
15
+ group_objects = []
16
+ conditions.each { |condition| group_objects << group(condition, true, &block) }
17
+ group_objects
18
+ else
19
+ obj = self.class.new
20
+ obj.conditions = conditions unless conditions.nil?
21
+ yield obj if block_given?
22
+ objects << obj
23
+ obj
24
+ end
25
+ end
26
+ alias_method :group=, :group
27
+
28
+ def and_group(*args, &block)
29
+ obj = group(*args, &block)
30
+ case obj
31
+ when Array
32
+ obj.each { |o| o.group_any = false }
33
+ else
34
+ obj
35
+ end
18
36
  end
37
+ alias_method :and_group=, :and_group
19
38
 
20
- # Lets you conditions to be groups or an array of conditions to be put in their own group. Each item in the array will create a new group. This is nice for using
21
- # groups in forms.
22
- def group=(value)
23
- case value
39
+ def or_group(*args, &block)
40
+ obj = group(*args, &block)
41
+ case obj
24
42
  when Array
25
- value.each { |v| group.conditions = v }
43
+ obj.each { |o| o.group_any = true }
26
44
  else
27
- group.conditions = value
45
+ obj
28
46
  end
29
47
  end
48
+ alias_method :or_group=, :or_group
49
+
50
+ def explicit_any=(value) # :nodoc:
51
+ @explicit_any = value
52
+ end
53
+
54
+ def explicit_any # :nodoc
55
+ @explicit_any
56
+ end
57
+
58
+ def explicit_any? # :nodoc:
59
+ ["true", "1", "yes"].include? explicit_any.to_s
60
+ end
30
61
 
31
62
  private
32
63
  def group_objects
33
- objects.select { |object| object.class == self.class }
64
+ objects.select { |object| group?(object) }
65
+ end
66
+
67
+ def group?(object)
68
+ object.class == self.class
34
69
  end
35
70
  end
36
71
  end
@@ -223,6 +223,8 @@ module Searchlogic
223
223
  def #{name}
224
224
  #{name}_object.value
225
225
  end
226
+ alias_method :and_#{name}, :#{name}
227
+ alias_method :or_#{name}, :#{name}
226
228
 
227
229
  def #{name}=(value)
228
230
  @conditions = nil
@@ -232,12 +234,12 @@ module Searchlogic
232
234
  end
233
235
 
234
236
  def and_#{name}=(value)
235
- #{name}_object.any = false
237
+ #{name}_object.explicit_any = false
236
238
  self.#{name} = value
237
239
  end
238
240
 
239
241
  def or_#{name}=(value)
240
- #{name}_object.any = true
242
+ #{name}_object.explicit_any = true
241
243
  self.#{name} = value
242
244
  end
243
245
 
@@ -7,7 +7,6 @@ module Searchlogic
7
7
  conditions.delete_if { |condition| condition.blank? }
8
8
  return if conditions.blank?
9
9
  return conditions.first if conditions.size == 1
10
- options[:scope] = true unless options.key?(:scope)
11
10
 
12
11
  conditions_strs = []
13
12
  conditions_subs = []
@@ -22,7 +21,7 @@ module Searchlogic
22
21
  return if conditions_strs.blank?
23
22
 
24
23
  join = options[:any] ? " OR " : " AND "
25
- conditions_str = options[:scope] ? "(#{conditions_strs.join(")#{join}(")})" : conditions_strs.join(join)
24
+ conditions_str = conditions_strs.join(join)
26
25
 
27
26
  return conditions_str if conditions_subs.blank?
28
27
 
@@ -67,7 +67,7 @@ module Searchlogic
67
67
 
68
68
  MAJOR = 1
69
69
  MINOR = 5
70
- TINY = 6
70
+ TINY = 7
71
71
 
72
72
  # The current version as a Version instance
73
73
  CURRENT = new(MAJOR, MINOR, TINY)
data/searchlogic.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{searchlogic}
5
- s.version = "1.5.6"
5
+ s.version = "1.5.7"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Ben Johnson of Binary Logic"]
9
- s.date = %q{2008-11-29}
9
+ s.date = %q{2008-11-30}
10
10
  s.description = %q{Object based ActiveRecord searching, ordering, pagination, and more!}
11
11
  s.email = %q{bjohnson@binarylogic.com}
12
12
  s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/searchlogic/active_record/associations.rb", "lib/searchlogic/active_record/base.rb", "lib/searchlogic/active_record/connection_adapters/mysql_adapter.rb", "lib/searchlogic/active_record/connection_adapters/postgresql_adapter.rb", "lib/searchlogic/active_record/connection_adapters/sqlite_adapter.rb", "lib/searchlogic/condition/base.rb", "lib/searchlogic/condition/begins_with.rb", "lib/searchlogic/condition/blank.rb", "lib/searchlogic/condition/child_of.rb", "lib/searchlogic/condition/descendant_of.rb", "lib/searchlogic/condition/ends_with.rb", "lib/searchlogic/condition/equals.rb", "lib/searchlogic/condition/greater_than.rb", "lib/searchlogic/condition/greater_than_or_equal_to.rb", "lib/searchlogic/condition/inclusive_descendant_of.rb", "lib/searchlogic/condition/keywords.rb", "lib/searchlogic/condition/less_than.rb", "lib/searchlogic/condition/less_than_or_equal_to.rb", "lib/searchlogic/condition/like.rb", "lib/searchlogic/condition/nil.rb", "lib/searchlogic/condition/not_begin_with.rb", "lib/searchlogic/condition/not_blank.rb", "lib/searchlogic/condition/not_end_with.rb", "lib/searchlogic/condition/not_equal.rb", "lib/searchlogic/condition/not_have_keywords.rb", "lib/searchlogic/condition/not_like.rb", "lib/searchlogic/condition/not_nil.rb", "lib/searchlogic/condition/sibling_of.rb", "lib/searchlogic/condition/tree.rb", "lib/searchlogic/conditions/any_or_all.rb", "lib/searchlogic/conditions/base.rb", "lib/searchlogic/conditions/groups.rb", "lib/searchlogic/conditions/magic_methods.rb", "lib/searchlogic/conditions/protection.rb", "lib/searchlogic/config/helpers.rb", "lib/searchlogic/config/search.rb", "lib/searchlogic/config.rb", "lib/searchlogic/core_ext/hash.rb", "lib/searchlogic/helpers/control_types/link.rb", "lib/searchlogic/helpers/control_types/links.rb", "lib/searchlogic/helpers/control_types/remote_link.rb", "lib/searchlogic/helpers/control_types/remote_links.rb", "lib/searchlogic/helpers/control_types/remote_select.rb", "lib/searchlogic/helpers/control_types/select.rb", "lib/searchlogic/helpers/form.rb", "lib/searchlogic/helpers/utilities.rb", "lib/searchlogic/modifiers/absolute.rb", "lib/searchlogic/modifiers/acos.rb", "lib/searchlogic/modifiers/asin.rb", "lib/searchlogic/modifiers/atan.rb", "lib/searchlogic/modifiers/base.rb", "lib/searchlogic/modifiers/ceil.rb", "lib/searchlogic/modifiers/char_length.rb", "lib/searchlogic/modifiers/cos.rb", "lib/searchlogic/modifiers/cot.rb", "lib/searchlogic/modifiers/day_of_month.rb", "lib/searchlogic/modifiers/day_of_week.rb", "lib/searchlogic/modifiers/day_of_year.rb", "lib/searchlogic/modifiers/degrees.rb", "lib/searchlogic/modifiers/exp.rb", "lib/searchlogic/modifiers/floor.rb", "lib/searchlogic/modifiers/hex.rb", "lib/searchlogic/modifiers/hour.rb", "lib/searchlogic/modifiers/log.rb", "lib/searchlogic/modifiers/log10.rb", "lib/searchlogic/modifiers/log2.rb", "lib/searchlogic/modifiers/lower.rb", "lib/searchlogic/modifiers/ltrim.rb", "lib/searchlogic/modifiers/md5.rb", "lib/searchlogic/modifiers/microseconds.rb", "lib/searchlogic/modifiers/milliseconds.rb", "lib/searchlogic/modifiers/minute.rb", "lib/searchlogic/modifiers/month.rb", "lib/searchlogic/modifiers/octal.rb", "lib/searchlogic/modifiers/radians.rb", "lib/searchlogic/modifiers/round.rb", "lib/searchlogic/modifiers/rtrim.rb", "lib/searchlogic/modifiers/second.rb", "lib/searchlogic/modifiers/sign.rb", "lib/searchlogic/modifiers/sin.rb", "lib/searchlogic/modifiers/square_root.rb", "lib/searchlogic/modifiers/tan.rb", "lib/searchlogic/modifiers/trim.rb", "lib/searchlogic/modifiers/upper.rb", "lib/searchlogic/modifiers/week.rb", "lib/searchlogic/modifiers/year.rb", "lib/searchlogic/search/base.rb", "lib/searchlogic/search/conditions.rb", "lib/searchlogic/search/ordering.rb", "lib/searchlogic/search/pagination.rb", "lib/searchlogic/search/protection.rb", "lib/searchlogic/search/searching.rb", "lib/searchlogic/shared/utilities.rb", "lib/searchlogic/shared/virtual_classes.rb", "lib/searchlogic/version.rb", "lib/searchlogic.rb", "README.rdoc", "TODO.rdoc"]
@@ -10,7 +10,7 @@ module ConditionTests
10
10
 
11
11
  condition = Searchlogic::Condition::InclusiveDescendantOf.new(User)
12
12
  condition.value = ben
13
- assert_equal ["(\"users\".\"id\" = ?) OR (\"users\".\"id\" = ? OR \"users\".\"id\" = ? OR \"users\".\"id\" = ?)", ben.id, drew.id, tren.id, jennifer.id], condition.sanitize
13
+ assert_equal ["\"users\".\"id\" = ? OR \"users\".\"id\" = ? OR \"users\".\"id\" = ? OR \"users\".\"id\" = ?", ben.id, drew.id, tren.id, jennifer.id], condition.sanitize
14
14
  end
15
15
  end
16
16
  end
@@ -9,7 +9,7 @@ module ConditionTests
9
9
 
10
10
  condition = Searchlogic::Condition::SiblingOf.new(User)
11
11
  condition.value = drew
12
- assert_equal ["(\"users\".\"id\" != ?) AND (\"users\".\"parent_id\" = ?)", drew.id, ben.id], condition.sanitize
12
+ assert_equal ["\"users\".\"id\" != ? AND \"users\".\"parent_id\" = ?", drew.id, ben.id], condition.sanitize
13
13
  end
14
14
  end
15
15
  end
@@ -73,7 +73,7 @@ module ConditionsTests
73
73
  conditions = Searchlogic::Cache::AccountConditions.new
74
74
  conditions.name_contains = "Binary"
75
75
  conditions.or_id_gt = 5
76
- assert conditions.id_gt_object.any?
76
+ assert conditions.id_gt_object.explicit_any?
77
77
  assert_equal ["\"accounts\".\"name\" LIKE ? OR \"accounts\".\"id\" > ?", "%Binary%", 5], conditions.sanitize
78
78
  now = Time.now
79
79
  conditions.created_at_after = now
@@ -35,17 +35,20 @@ module ConditionsTests
35
35
 
36
36
  def test_group_hash
37
37
  now = Time.now
38
- conditions = Searchlogic::Cache::AccountConditions.new(
39
- :id_gt => 3,
40
- :group => [
38
+ conditions = Searchlogic::Cache::AccountConditions.new([
39
+ {:id_gt => 3},
40
+ {:group => [
41
41
  {:name_like => "Binary"},
42
- {
43
- :id_gt => 5,
44
- :group => {:created_at_after => now}
45
- }
46
- ]
47
- )
48
- assert_equal ["\"accounts\".\"id\" > ? AND (\"accounts\".\"name\" LIKE ?) AND (\"accounts\".\"id\" > ? AND (\"accounts\".\"created_at\" > ?))", 3, "%Binary%", 5, now], conditions.sanitize
42
+ [
43
+ {:id_gt => 5},
44
+ {:group => {
45
+ :id_lt => 20,
46
+ :created_at_after => now
47
+ }}
48
+ ]
49
+ ]}
50
+ ])
51
+ assert_equal ["\"accounts\".\"id\" > ? AND (\"accounts\".\"name\" LIKE ?) AND (\"accounts\".\"id\" > ? AND (\"accounts\".\"id\" < ? AND \"accounts\".\"created_at\" > ?))", 3, "%Binary%", 5, 20, now], conditions.sanitize
49
52
  end
50
53
  end
51
54
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: searchlogic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.6
4
+ version: 1.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Johnson of Binary Logic
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-29 00:00:00 -05:00
12
+ date: 2008-11-30 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency