searchgasm 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/CHANGELOG.rdoc +11 -1
  2. data/Manifest +7 -2
  3. data/README.rdoc +1 -1
  4. data/Rakefile +1 -1
  5. data/TODO.rdoc +5 -0
  6. data/lib/searchgasm/active_record/connection_adapters/mysql_adapter.rb +15 -0
  7. data/lib/searchgasm/active_record/connection_adapters/postgresql_adapter.rb +0 -0
  8. data/lib/searchgasm/active_record/connection_adapters/sqlite_adapter.rb +0 -0
  9. data/lib/searchgasm/condition/base.rb +26 -10
  10. data/lib/searchgasm/condition/{is_blank.rb → blank.rb} +5 -6
  11. data/lib/searchgasm/condition/does_not_equal.rb +1 -1
  12. data/lib/searchgasm/condition/during_evening.rb +32 -0
  13. data/lib/searchgasm/condition/equals.rb +1 -1
  14. data/lib/searchgasm/condition/greater_than.rb +2 -1
  15. data/lib/searchgasm/condition/greater_than_or_equal_to.rb +7 -1
  16. data/lib/searchgasm/condition/less_than.rb +2 -1
  17. data/lib/searchgasm/condition/less_than_or_equal_to.rb +7 -1
  18. data/lib/searchgasm/condition/nil.rb +21 -0
  19. data/lib/searchgasm/conditions/base.rb +6 -3
  20. data/lib/searchgasm/config.rb +22 -0
  21. data/lib/searchgasm/helpers/control_types/link.rb +9 -26
  22. data/lib/searchgasm/helpers/control_types/select.rb +4 -4
  23. data/lib/searchgasm/helpers/utilities.rb +49 -11
  24. data/lib/searchgasm/search/base.rb +10 -8
  25. data/lib/searchgasm/search/ordering.rb +4 -4
  26. data/lib/searchgasm/shared/utilities.rb +10 -0
  27. data/lib/searchgasm/version.rb +1 -1
  28. data/lib/searchgasm.rb +4 -3
  29. data/searchgasm.gemspec +18 -8
  30. data/test/test_active_record_base.rb +1 -0
  31. data/test/test_condition_base.rb +10 -8
  32. data/test/test_condition_types.rb +30 -30
  33. data/test/test_conditions_base.rb +1 -0
  34. data/test/test_search_base.rb +4 -0
  35. data/test/test_search_ordering.rb +14 -1
  36. metadata +17 -7
  37. data/lib/searchgasm/condition/is_nil.rb +0 -23
data/CHANGELOG.rdoc CHANGED
@@ -1,4 +1,14 @@
1
- == 1.2.1 released 2008-09-24
1
+ == 1.2.2 released 2008-09-29
2
+
3
+ * Fixed bug when reverse engineering order to order_by, assumed ASC and DESC would always be present when they are not.
4
+ * False is a meaningful value for some conditions, and false.blank? == true. So instead of using value.blank? to ignore conditions we use meaningless?(value), which returns false if it is false.
5
+ * Fixed aliases for lt, lte, gt, and gte.
6
+ * Fixed bug when writing conditions on associations via a hash with string keys
7
+ * Added Config.remove_duplicates to turn off the "automatic" removing of duplicates if desired.
8
+ * Updated searchgasm_state helper to insert the entire state all at once.
9
+ * Added CSS class "ordering" to order_by_link if the search is being ordered by that.
10
+
11
+ == 1.2.1 released 2008-09-25
2
12
 
3
13
  * Fixed problem when determining if an order_by_link is currently being ordered. Just "stringified" both comparable values.
4
14
  * Removed default order_by and order_as. They will ONLY have values if you specify how to order, otherwise they are nil.
data/Manifest CHANGED
@@ -3,22 +3,26 @@ examples/README.rdoc
3
3
  init.rb
4
4
  lib/searchgasm/active_record/associations.rb
5
5
  lib/searchgasm/active_record/base.rb
6
+ lib/searchgasm/active_record/connection_adapters/mysql_adapter.rb
7
+ lib/searchgasm/active_record/connection_adapters/postgresql_adapter.rb
8
+ lib/searchgasm/active_record/connection_adapters/sqlite_adapter.rb
6
9
  lib/searchgasm/condition/base.rb
7
10
  lib/searchgasm/condition/begins_with.rb
11
+ lib/searchgasm/condition/blank.rb
8
12
  lib/searchgasm/condition/child_of.rb
9
13
  lib/searchgasm/condition/contains.rb
10
14
  lib/searchgasm/condition/descendant_of.rb
11
15
  lib/searchgasm/condition/does_not_equal.rb
16
+ lib/searchgasm/condition/during_evening.rb
12
17
  lib/searchgasm/condition/ends_with.rb
13
18
  lib/searchgasm/condition/equals.rb
14
19
  lib/searchgasm/condition/greater_than.rb
15
20
  lib/searchgasm/condition/greater_than_or_equal_to.rb
16
21
  lib/searchgasm/condition/inclusive_descendant_of.rb
17
- lib/searchgasm/condition/is_blank.rb
18
- lib/searchgasm/condition/is_nil.rb
19
22
  lib/searchgasm/condition/keywords.rb
20
23
  lib/searchgasm/condition/less_than.rb
21
24
  lib/searchgasm/condition/less_than_or_equal_to.rb
25
+ lib/searchgasm/condition/nil.rb
22
26
  lib/searchgasm/condition/sibling_of.rb
23
27
  lib/searchgasm/condition/tree.rb
24
28
  lib/searchgasm/conditions/base.rb
@@ -66,3 +70,4 @@ test/test_search_conditions.rb
66
70
  test/test_search_ordering.rb
67
71
  test/test_search_pagination.rb
68
72
  test/test_search_protection.rb
73
+ TODO.rdoc
data/README.rdoc CHANGED
@@ -345,7 +345,7 @@ What that rule means is that any options you pass when searching get "sanitized"
345
345
 
346
346
  Author: {Ben Johnson}[http://github.com/binarylogic] of {Binary Logic}[http://www.binarylogic.com]
347
347
 
348
- Credit to {Zack Ham}[http://github.com/zackham] and {Robert Malko}[http://github.com/malkomalko/] for helping with feature suggestions.
348
+ Credit to {Zack Ham}[http://github.com/zackham] for helping with feature suggestions.
349
349
 
350
350
 
351
351
  Copyright (c) 2008 {Ben Johnson}[http://github.com/binarylogic] of {Binary Logic}[http://www.binarylogic.com], released under the MIT license
data/Rakefile CHANGED
@@ -10,6 +10,6 @@ Echoe.new 'searchgasm' do |p|
10
10
  p.project = 'searchgasm'
11
11
  p.summary = "Object based ActiveRecord searching, ordering, pagination, and more!"
12
12
  p.url = "http://github.com/binarylogic/searchgasm"
13
- p.dependencies = ['activerecord', 'activesupport']
13
+ p.dependencies = %w(activerecord activesupport)
14
14
  p.include_rakefile = true
15
15
  end
data/TODO.rdoc ADDED
@@ -0,0 +1,5 @@
1
+ = To Do
2
+
3
+ 1. Add month condition for date and datetime columns. So you can specify a specific month, by name, number, etc.
4
+ 2. Add day condition for time and datetime columns. So you can specify that the time is during the day or the night.
5
+ 3. Add weekend condition for date and datetime columns. So you can specify if the date is on a friday, saturday, or sunday
@@ -0,0 +1,15 @@
1
+ module Searchgasm
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module MysqlAdapter
5
+ def hour_sql
6
+ "HOUR(?)"
7
+ end
8
+
9
+ def month_sql
10
+ "MONTH(?)"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -8,9 +8,8 @@ module Searchgasm
8
8
  include Shared::Utilities
9
9
 
10
10
  attr_accessor :column, :klass
11
- class_inheritable_accessor :ignore_blanks, :type_cast_value
12
- self.ignore_blanks = true
13
- self.type_cast_value = true
11
+ class_inheritable_accessor :ignore_meaningless, :type_cast_sql_type
12
+ self.ignore_meaningless = true
14
13
 
15
14
  class << self
16
15
  # Name of the condition inferred from the class name
@@ -29,12 +28,8 @@ module Searchgasm
29
28
  []
30
29
  end
31
30
 
32
- def ignore_blanks? # :nodoc:
33
- ignore_blanks == true
34
- end
35
-
36
- def type_cast_value? # :nodoc:
37
- type_cast_value == true
31
+ def ignore_meaningless? # :nodoc:
32
+ ignore_meaningless == true
38
33
  end
39
34
 
40
35
  # Sane as name_for_column but for the class as a whole. For example the tree methods apply to the class as a whole and not
@@ -48,6 +43,16 @@ module Searchgasm
48
43
  []
49
44
  end
50
45
 
46
+ # A utility method for using in name_for_column. Determines if a column contains a date.
47
+ def date_column?(column)
48
+ [:datetime, :date, :timestamp].include?(column.type)
49
+ end
50
+
51
+ # A utility method for using in name_for_column. Determines if a column contains a date and a time.
52
+ def datetime_column?(column)
53
+ [:datetime, :timestamp, :time, :date].include?(column.type)
54
+ end
55
+
51
56
  # A utility method for using in name_for_column. For example the keywords condition only applied to string columns, the great than condition doesnt.
52
57
  def string_column?(column)
53
58
  [:string, :text].include?(column.type)
@@ -57,6 +62,11 @@ module Searchgasm
57
62
  def comparable_column?(column)
58
63
  [:integer, :float, :decimal, :datetime, :timestamp, :time, :date].include?(column.type)
59
64
  end
65
+
66
+ # A utility method for using in name_for_column. Determines if a column contains a time.
67
+ def time_column?(column)
68
+ [:datetime, :timestamp, :time].include?(column.type)
69
+ end
60
70
  end
61
71
 
62
72
  def initialize(klass, column = nil)
@@ -118,14 +128,20 @@ module Searchgasm
118
128
 
119
129
  # The value for the condition
120
130
  def value
121
- self.class.type_cast_value? && @value.is_a?(String) ? column.type_cast(@value) : @value
131
+ @value.is_a?(String) ? column_for_type_cast.type_cast(@value) : @value
122
132
  end
123
133
 
124
134
  # Sets the value for the condition
125
135
  def value=(v)
136
+ return if self.class.ignore_meaningless? && meaningless?(v)
126
137
  self.explicitly_set_value = true
127
138
  @value = v
128
139
  end
140
+
141
+ private
142
+ def column_for_type_cast
143
+ @column_for_type_cast ||= self.class.type_cast_sql_type ? self.column.class.new(column.name, column.default.to_s, self.class.type_cast_sql_type.to_s, column.null) : column
144
+ end
129
145
  end
130
146
  end
131
147
  end
@@ -1,20 +1,19 @@
1
1
  module Searchgasm
2
2
  module Condition
3
- class IsBlank < Base
4
- self.ignore_blanks = false
5
- self.type_cast_value = false
3
+ class Blank < Base
4
+ self.type_cast_sql_type = "boolean"
6
5
 
7
6
  class << self
8
7
  def aliases_for_column(column)
9
- ["#{column.name}_blank"]
8
+ ["#{column.name}_is_blank"]
10
9
  end
11
10
  end
12
11
 
13
12
  def to_conditions(value)
14
13
  # Some databases handle null values differently, let AR handle this
15
- if value == true || value == "true" || value == 1 || value == "1"
14
+ if value == true
16
15
  "#{quoted_table_name}.#{quoted_column_name} is NULL or #{quoted_table_name}.#{quoted_column_name} = ''"
17
- elsif value == false || value == "false" || value == 0 || value == "0"
16
+ elsif value == false
18
17
  "#{quoted_table_name}.#{quoted_column_name} is NOT NULL and #{quoted_table_name}.#{quoted_column_name} != ''"
19
18
  end
20
19
  end
@@ -1,7 +1,7 @@
1
1
  module Searchgasm
2
2
  module Condition
3
3
  class DoesNotEqual < Base
4
- self.ignore_blanks = false
4
+ self.ignore_meaningless = false
5
5
 
6
6
  class << self
7
7
  def aliases_for_column(column)
@@ -0,0 +1,32 @@
1
+ module Searchgasm
2
+ module Condition
3
+ class DuringEvening < Base
4
+ class << self
5
+ def name_for_column(column)
6
+ return unless time_column?(column)
7
+ super
8
+ end
9
+
10
+ def aliases_for_column(column)
11
+ column_names = [column.name]
12
+ column_names << column.name.gsub(/_(at|on)$/, "") if column.name =~ /_(at|on)$/
13
+
14
+ aliases = []
15
+ column_names.each { |column_name| aliases += ["#{column_name}_in_the_evening", "#{column_name}_in_evening", "#{column_name}_evening"] }
16
+ aliases << "#{column_names.last}_during_evening" if column_names.size > 1
17
+ aliases
18
+ end
19
+ end
20
+
21
+ def to_conditions(value)
22
+ evening_start = 17
23
+ evening_end = 22
24
+
25
+ # Need to set up a funcion in each adapter for dealing with dates. Mysql uses HOUR(), sqlite uses strftime(), postgres uses date_part('hour', date). Could potentially be a pain in the ass.
26
+ # Also, you could set up an hour = condition, and leverage that to do this.
27
+ if value == true
28
+ ["#{quoted_table_name}.#{quoted_column_name} >= ? AND #{quoted_table_name}.#{quoted_column_name} <= ?", value]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,7 +1,7 @@
1
1
  module Searchgasm
2
2
  module Condition
3
3
  class Equals < Base
4
- self.ignore_blanks = false
4
+ self.ignore_meaningless = false
5
5
 
6
6
  class << self
7
7
  def aliases_for_column(column)
@@ -9,10 +9,11 @@ module Searchgasm
9
9
 
10
10
  def aliases_for_column(column)
11
11
  column_names = [column.name]
12
- column_names << column.name.gsub(/_at$/, "") if [:datetime, :timestamp, :time, :date].include?(column.type) && column.name =~ /_at$/
12
+ column_names << column.name.gsub(/_(at|on)$/, "") if datetime_column?(column) && column.name =~ /_(at|on)$/
13
13
 
14
14
  aliases = []
15
15
  column_names.each { |column_name| aliases += ["#{column_name}_gt", "#{column_name}_after"] }
16
+ aliases << "#{column_names.last}_greater_than" if column_names.size > 1
16
17
  aliases
17
18
  end
18
19
  end
@@ -8,7 +8,13 @@ module Searchgasm
8
8
  end
9
9
 
10
10
  def aliases_for_column(column)
11
- ["#{column.name}_gte", "#{column.name}_at_least"]
11
+ column_names = [column.name]
12
+ column_names << column.name.gsub(/_(at|on)$/, "") if datetime_column?(column) && column.name =~ /_(at|on)$/
13
+
14
+ aliases = []
15
+ column_names.each { |column_name| aliases += ["#{column_name}_gte", "#{column_name}_at_least"] }
16
+ aliases << "#{column_names.last}_greater_than_or_equal_to" if column_names.size > 1
17
+ aliases
12
18
  end
13
19
  end
14
20
 
@@ -9,10 +9,11 @@ module Searchgasm
9
9
 
10
10
  def aliases_for_column(column)
11
11
  column_names = [column.name]
12
- column_names << column.name.gsub(/_at$/, "") if [:datetime, :timestamp, :time, :date].include?(column.type) && column.name =~ /_at$/
12
+ column_names << column.name.gsub(/_(at|on)$/, "") if datetime_column?(column) && column.name =~ /_(at|on)$/
13
13
 
14
14
  aliases = []
15
15
  column_names.each { |column_name| aliases += ["#{column_name}_lt", "#{column_name}_before"] }
16
+ aliases << "#{column_names.last}_less_than" if column_names.size > 1
16
17
  aliases
17
18
  end
18
19
  end
@@ -8,7 +8,13 @@ module Searchgasm
8
8
  end
9
9
 
10
10
  def aliases_for_column(column)
11
- ["#{column.name}_lte", "#{column.name}_at_most"]
11
+ column_names = [column.name]
12
+ column_names << column.name.gsub(/_(at|on)$/, "") if datetime_column?(column) && column.name =~ /_(at|on)$/
13
+
14
+ aliases = []
15
+ column_names.each { |column_name| aliases += ["#{column_name}_lte", "#{column_name}_at_most"] }
16
+ aliases << "#{column_names.last}_less_than_or_equal_to" if column_names.size > 1
17
+ aliases
12
18
  end
13
19
  end
14
20
 
@@ -0,0 +1,21 @@
1
+ module Searchgasm
2
+ module Condition
3
+ class Nil < Base
4
+ self.type_cast_sql_type = "boolean"
5
+
6
+ class << self
7
+ def aliases_for_column(column)
8
+ ["#{column.name}_is_nil", "#{column.name}_is_null", "#{column.name}_null"]
9
+ end
10
+ end
11
+
12
+ def to_conditions(value)
13
+ if value == true
14
+ "#{quoted_table_name}.#{quoted_column_name} is NULL"
15
+ elsif value == false
16
+ "#{quoted_table_name}.#{quoted_column_name} is NOT NULL"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -68,8 +68,11 @@ module Searchgasm
68
68
 
69
69
  if conditions.is_a?(Hash)
70
70
  return true if conditions[:any]
71
+ stringified_conditions = conditions.stringify_keys
72
+ stringified_conditions.keys.each { |condition| return false if condition.include?(".") } # setting conditions on associations, which is just another way of writing SQL, and we ignore SQL
73
+
71
74
  column_names = model_class.column_names
72
- conditions.stringify_keys.keys.each do |condition|
75
+ stringified_conditions.keys.each do |condition|
73
76
  return true unless column_names.include?(condition)
74
77
  end
75
78
  end
@@ -132,7 +135,7 @@ module Searchgasm
132
135
  when Hash
133
136
  assert_valid_conditions(value)
134
137
  remove_conditions_from_protected_assignement(value).each do |condition, condition_value|
135
- next if condition_value.blank? # ignore blanks on mass assignments
138
+ next if meaningless?(condition_value) # ignore blanks on mass assignments
136
139
  send("#{condition}=", condition_value)
137
140
  end
138
141
  else
@@ -216,7 +219,7 @@ module Searchgasm
216
219
  def #{name}; #{name}_object.value; end
217
220
 
218
221
  def #{name}=(value)
219
- if value.blank? && #{name}_object.class.ignore_blanks?
222
+ if meaningless?(value) && #{name}_object.class.ignore_meaningless?
220
223
  reset_#{name}!
221
224
  else
222
225
  @conditions = nil
@@ -153,6 +153,28 @@ module Searchgasm
153
153
  def per_page_choices=(value)
154
154
  @per_page_choices = value
155
155
  end
156
+
157
+ def remove_duplicates # :nodoc:
158
+ return @remove_duplicates if @set_remove_duplicates
159
+ @remove_duplicates ||= ::ActiveRecord::VERSION::MAJOR < 2 || (::ActiveRecord::VERSION::MAJOR == 2 && ::ActiveRecord::VERSION::MINOR < 2)
160
+ end
161
+
162
+ def remove_duplicates? # :nodoc:
163
+ remove_duplicates == true
164
+ end
165
+
166
+ # If you are using ActiveRecord < 2.2.0 then ActiveRecord does not remove duplicates when using the :joins option, when it should. To fix this problem searchgasm does this for you. Searchgasm tries to act
167
+ # just like ActiveRecord, but in this instance it doesn't make sense.
168
+ #
169
+ # As a result, Searchgasm removes all duplicates results in *ALL* search / calculation queries. It does this by forcing the DISTINCT or GROUP BY operation in your SQL. Which might come as a surprise to you
170
+ # since it is not the "norm". If you don't want searchgasm to do this, set this to false.
171
+ #
172
+ # * <tt>Default:</tt> true
173
+ # * <tt>Accepts:</tt> Boolean
174
+ def remove_duplicates=(value)
175
+ @set_remove_duplicates = true
176
+ @remove_duplicates = value
177
+ end
156
178
  end
157
179
  end
158
180
  end
@@ -85,9 +85,8 @@ module Searchgasm
85
85
  # * <tt>:search_params</tt> -- default: nil, Additional search params to add to the url, must be a hash. Adds the options into the :params_scope.
86
86
  # * <tt>:exclude_search_params</tt> -- default: nil, Same as :exclude_params but for the :search_params.
87
87
  def order_by_link(order_by, options = {})
88
- order_by = deep_stringify(order_by)
89
88
  add_order_by_link_defaults!(order_by, options)
90
- html = searchgasm_state_for(:order_by, options) + searchgasm_state_for(:order_as, options)
89
+ html = searchgasm_state(options)
91
90
 
92
91
  if !options[:is_remote]
93
92
  html += link_to(options[:text], options[:url], options[:html])
@@ -119,7 +118,7 @@ module Searchgasm
119
118
  # * <tt>:exclude_search_params</tt> -- default: nil, Same as :exclude_params but for the :search_params.
120
119
  def order_as_link(order_as, options = {})
121
120
  add_order_as_link_defaults!(order_as, options)
122
- html = searchgasm_state_for(:order_as, options)
121
+ html = searchgasm_state(options)
123
122
 
124
123
  if !options[:is_remote]
125
124
  html += link_to(options[:text], options[:url], options[:html])
@@ -159,9 +158,8 @@ module Searchgasm
159
158
  # * <tt>:search_params</tt> -- default: nil, Additional search params to add to the url, must be a hash. Adds the options into the :params_scope.
160
159
  # * <tt>:exclude_search_params</tt> -- default: nil, Same as :exclude_params but for the :search_params.
161
160
  def priority_order_by_link(priority_order_by, priority_order_as, options = {})
162
- priority_order_by = deep_stringify(priority_order_by)
163
161
  add_priority_order_by_link_defaults!(priority_order_by, priority_order_as, options)
164
- html = searchgasm_state_for(:priority_order_by, options) + searchgasm_state_for(:priority_order_as, options)
162
+ html = searchgasm_state(options)
165
163
 
166
164
  if !options[:is_remote]
167
165
  html += link_to(options[:text], options[:url], options[:html])
@@ -195,7 +193,7 @@ module Searchgasm
195
193
  # * <tt>:exclude_search_params</tt> -- default: nil, Same as :exclude_params but for the :search_params.
196
194
  def per_page_link(per_page, options = {})
197
195
  add_per_page_link_defaults!(per_page, options)
198
- html = searchgasm_state_for(:per_page, options)
196
+ html = searchgasm_state(options)
199
197
 
200
198
  if !options[:is_remote]
201
199
  html += link_to(options[:text], options[:url], options[:html])
@@ -227,7 +225,7 @@ module Searchgasm
227
225
  # * <tt>:exclude_search_params</tt> -- default: nil, Same as :exclude_params but for the :search_params.
228
226
  def page_link(page, options = {})
229
227
  add_page_link_defaults!(page, options)
230
- html = searchgasm_state_for(:page, options)
228
+ html = searchgasm_state(options)
231
229
 
232
230
  if !options[:is_remote]
233
231
  html += link_to(options[:text], options[:url], options[:html])
@@ -241,10 +239,12 @@ module Searchgasm
241
239
  private
242
240
  def add_order_by_link_defaults!(order_by, options = {})
243
241
  add_searchgasm_control_defaults!(:order_by, options)
242
+ ordering_by_this = searchgasm_ordering_by?(order_by, options)
243
+ searchgasm_add_class!(options[:html], "ordering") if ordering_by_this
244
244
  options[:text] ||= determine_order_by_text(order_by)
245
245
  options[:asc_indicator] ||= Config.asc_indicator
246
246
  options[:desc_indicator] ||= Config.desc_indicator
247
- options[:text] += options[:search_obj].desc? ? options[:desc_indicator] : options[:asc_indicator] if deep_stringify(options[:search_obj].order_by) == order_by
247
+ options[:text] += options[:search_obj].desc? ? options[:desc_indicator] : options[:asc_indicator] if ordering_by_this
248
248
  options[:url] = searchgasm_params(options.merge(:search_params => {:order_by => order_by}))
249
249
  options
250
250
  end
@@ -261,7 +261,7 @@ module Searchgasm
261
261
  options[:column_name] ||= determine_order_by_text(priority_order_by).downcase
262
262
  options[:activate_text] ||= "Show #{options[:column_name]} first"
263
263
  options[:deactivate_text] ||= "Don't show #{options[:column_name]} first"
264
- active = deep_stringify(options[:search_obj].priority_order_by) == priority_order_by && options[:search_obj].priority_order_as == priority_order_as
264
+ active = deep_stringify(options[:search_obj].priority_order_by) == deep_stringify(priority_order_by) && options[:search_obj].priority_order_as == priority_order_as
265
265
  options[:text] ||= active ? options[:deactivate_text] : options[:activate_text]
266
266
  if active
267
267
  options.merge!(:search_params => {:priority_order_by => nil, :priority_order_as => nil})
@@ -298,23 +298,6 @@ module Searchgasm
298
298
  determine_order_by_text(v, k)
299
299
  end
300
300
  end
301
-
302
- def deep_stringify(obj)
303
- case obj
304
- when String
305
- obj
306
- when Symbol
307
- obj.to_s
308
- when Array
309
- obj.collect { |item| deep_stringify(item) }
310
- when Hash
311
- new_obj = {}
312
- obj.each { |key, value| new_obj[key.to_s] = deep_stringify(value) }
313
- new_obj
314
- else
315
- obj
316
- end
317
- end
318
301
  end
319
302
  end
320
303
  end
@@ -8,25 +8,25 @@ module Searchgasm
8
8
  # Please see order_by_links. All options are the same and applicable here. The only difference is that instead of a group of links, this gets returned as a select form element that will perform the same function when the value is changed.
9
9
  def order_by_select(options = {})
10
10
  add_order_by_select_defaults!(options)
11
- searchgasm_state_for(:order_by, options) + select(options[:params_scope], :order_by, options[:choices], options[:tag], options[:html] || {})
11
+ searchgasm_state(options) + select(options[:params_scope], :order_by, options[:choices], options[:tag], options[:html] || {})
12
12
  end
13
13
 
14
14
  # Please see order_as_links. All options are the same and applicable here. The only difference is that instead of a group of links, this gets returned as a select form element that will perform the same function when the value is changed.
15
15
  def order_as_select(options = {})
16
16
  add_order_as_select_defaults!(options)
17
- searchgasm_state_for(:order_as, options) + select(options[:params_scope], :order_as, options[:choices], options[:tag], options[:html])
17
+ searchgasm_state(options) + select(options[:params_scope], :order_as, options[:choices], options[:tag], options[:html])
18
18
  end
19
19
 
20
20
  # Please see per_page_links. All options are the same and applicable here. The only difference is that instead of a group of links, this gets returned as a select form element that will perform the same function when the value is changed.
21
21
  def per_page_select(options = {})
22
22
  add_per_page_select_defaults!(options)
23
- searchgasm_state_for(:per_page, options) + select(options[:params_scope], :per_page, options[:choices], options[:tag], options[:html])
23
+ searchgasm_state(options) + select(options[:params_scope], :per_page, options[:choices], options[:tag], options[:html])
24
24
  end
25
25
 
26
26
  # Please see page_links. All options are the same and applicable here, excep the :prev, :next, :first, and :last options. The only difference is that instead of a group of links, this gets returned as a select form element that will perform the same function when the value is changed.
27
27
  def page_select(options = {})
28
28
  add_page_select_defaults!(options)
29
- searchgasm_state_for(:page, options) + select(options[:params_scope], :page, (options[:first_page]..options[:last_page]), options[:tag], options[:html])
29
+ searchgasm_state(options) + select(options[:params_scope], :page, (options[:first_page]..options[:last_page]), options[:tag], options[:html])
30
30
  end
31
31
 
32
32
  private
@@ -37,10 +37,12 @@ module Searchgasm
37
37
  search_params.deep_delete(options[:exclude_search_params])
38
38
 
39
39
  if options[:search_params]
40
+
41
+ #raise params_copy.inspect if options[:search_params][:order_by] == :id
40
42
  search_params.deep_merge!(options[:search_params])
41
43
 
42
44
  if options[:search_params][:order_by] && !options[:search_params][:order_as]
43
- search_params[:order_as] = (options[:search_obj].order_by == options[:search_params][:order_by] && options[:search_obj].asc?) ? "DESC" : "ASC"
45
+ search_params[:order_as] = (searchgasm_ordering_by?(options[:search_params][:order_by], options) && options[:search_obj].asc?) ? "DESC" : "ASC"
44
46
  end
45
47
 
46
48
  [:order_by, :priority_order_by].each { |base64_field| search_params[base64_field] = searchgasm_base64_value(search_params[base64_field]) if search_params.has_key?(base64_field) }
@@ -90,6 +92,30 @@ module Searchgasm
90
92
  url += (url.last == "?" ? "" : (url.include?("?") ? "&amp;" : "?")) + literal_param_strings.join("&amp;")
91
93
  end
92
94
 
95
+ # When you set up a search form using form_for for remote_form_for searchgasm adds in some *magic* for you.
96
+ #
97
+ # Take the instance where a user orders the data by something other than the default, and then does a search. The user would expect the search to remember what the user selected to order the data by, right?
98
+ # What searchgasm does is add in some hidden fields, somewhere in the page, the represent the searchgasm "state". These are automatically added for you when you use the searchgasm helpers.
99
+ # Such as: page_links, page_link, order_by_link, per_page_select, etc. So if you are using those you do not need to worry about this helper.
100
+ #
101
+ # If for some reason you do not use any of these you need to put the searchgasm state on your page somewhere. Somewhere where the state will *always* be up-to-date, which would be most likely be in the
102
+ # partial that renders your search results (assuming you are using AJAX). Otherwise when the user starts a new search, the state will be reset. Meaning the order_by, per_page, etc will all be reset.
103
+ #
104
+ # === Options
105
+ # * <tt>:params_scope</tt> -- default: :search, this is the scope in which your search params will be preserved (params[:search]). If you don't want a scope and want your options to be at base leve in params such as params[:page], params[:per_page], etc, then set this to nil.
106
+ # * <tt>:search_obj</tt> -- default: @#{params_scope}, this is your search object, everything revolves around this. It will try to infer the name from your params_scope. If your params_scope is :search it will try to get @search, etc. If it can not be inferred by this, you need to pass the object itself.
107
+ def searchgasm_state(options)
108
+ return "" if @added_searchgasm_state
109
+ add_searchgasm_defaults!(options)
110
+ html = ""
111
+ (Search::Base::SPECIAL_FIND_OPTIONS - [:page, :priority_order]).each do |option|
112
+ value = options[:search_obj].send(option)
113
+ html += hidden_field(options[:params_scope], option, :value => (option == :order_by ? searchgasm_base64_value(value) : value))
114
+ end
115
+ @added_searchgasm_state = true
116
+ html
117
+ end
118
+
93
119
  private
94
120
  # Adds default options for all helper methods.
95
121
  def add_searchgasm_defaults!(options)
@@ -117,22 +143,17 @@ module Searchgasm
117
143
 
118
144
  def searchgasm_base64_value(order_by)
119
145
  case order_by
120
- when String
146
+ when String, Symbol
121
147
  order_by
122
148
  when Array, Hash
123
149
  [Marshal.dump(order_by)].pack("m")
124
150
  end
125
151
  end
126
152
 
127
- def searchgasm_state_for(option, options)
128
- @added_state_for ||= []
129
- html = ""
130
- unless @added_state_for.include?(option)
131
- value = options[:search_obj].send(option)
132
- html = hidden_field(options[:params_scope], option, :value => (option == :order_by ? searchgasm_base64_value(value) : value))
133
- @added_state_for << option
134
- end
135
- html
153
+ def searchgasm_ordering_by?(order_by, options)
154
+ stringified_search_order_by = deep_stringify(options[:search_obj].order_by)
155
+ stringified_order_by = deep_stringify(order_by)
156
+ (options[:search_obj].order_by.blank? && options[:search_obj].klass.primary_key == stringified_order_by) || stringified_search_order_by == stringified_order_by
136
157
  end
137
158
 
138
159
  def literal_param_strings(literal_params, prefix)
@@ -152,6 +173,23 @@ module Searchgasm
152
173
 
153
174
  param_strings
154
175
  end
176
+
177
+ def deep_stringify(obj)
178
+ case obj
179
+ when String
180
+ obj
181
+ when Symbol
182
+ obj.to_s
183
+ when Array
184
+ obj.collect { |item| deep_stringify(item) }
185
+ when Hash
186
+ new_obj = {}
187
+ obj.each { |key, value| new_obj[key.to_s] = deep_stringify(value) }
188
+ new_obj
189
+ else
190
+ obj
191
+ end
192
+ end
155
193
  end
156
194
  end
157
195
  end
@@ -112,16 +112,18 @@ module Searchgasm #:nodoc:
112
112
  next if value.blank?
113
113
  find_options[find_option] = value
114
114
  end
115
-
116
- unless find_options[:joins].blank?
117
- # The following is to return uniq records since we are using joins instead of includes
118
- if searching
119
- find_options[:group] ||= "#{quote_table_name(klass.table_name)}.#{quote_column_name(klass.primary_key)}"
120
- else
121
- find_options[:distinct] = true
115
+
116
+ if Config.remove_duplicates?
117
+ unless find_options[:joins].blank?
118
+ # The following is to return uniq records since we are using joins instead of includes
119
+ if searching
120
+ find_options[:group] ||= "#{quote_table_name(klass.table_name)}.#{quote_column_name(klass.primary_key)}"
121
+ else
122
+ find_options[:distinct] = true
123
+ end
122
124
  end
123
125
  end
124
-
126
+
125
127
  find_options
126
128
  end
127
129
 
@@ -39,7 +39,6 @@ module Searchgasm
39
39
 
40
40
  # Convenience method for determining if the ordering is ascending
41
41
  def asc?
42
- return false if order_as.nil?
43
42
  !desc?
44
43
  end
45
44
 
@@ -199,7 +198,8 @@ module Searchgasm
199
198
  # Reversege engineer order, only go 1 level deep with relationships, anything beyond that is probably excessive and not good for performance
200
199
  order_parts = order.split(",").collect do |part|
201
200
  part.strip!
202
- part.gsub!(/ (ASC|DESC)$/i, "").gsub!(/(.*)\./, "")
201
+ part.gsub!(/ (ASC|DESC)$/i, "")
202
+ part.gsub!(/(.*)\./, "")
203
203
  table_name = ($1 ? $1.gsub(/[^a-z0-9_]/i, "") : nil)
204
204
  part.gsub!(/[^a-z0-9_]/i, "")
205
205
  reflection = nil
@@ -223,9 +223,9 @@ module Searchgasm
223
223
  value = order_by_value.values.first
224
224
  case value
225
225
  when Hash
226
- {key => build_order_by_auto_joins(value)}
226
+ {key.to_sym => build_order_by_auto_joins(value)}
227
227
  else
228
- key
228
+ key.to_sym
229
229
  end
230
230
  else
231
231
  nil
@@ -45,6 +45,16 @@ module Searchgasm
45
45
 
46
46
  new_joins.compact.uniq
47
47
  end
48
+
49
+ # "meaningful" is subjective which is why this is not a core extension like .blank?
50
+ def meaningless?(value)
51
+ return false if value == false
52
+ value.blank?
53
+ end
54
+
55
+ def meaningful?(value)
56
+ !meaningless?
57
+ end
48
58
  end
49
59
  end
50
60
  end
@@ -67,7 +67,7 @@ module Searchgasm
67
67
 
68
68
  MAJOR = 1
69
69
  MINOR = 2
70
- TINY = 1
70
+ TINY = 2
71
71
 
72
72
  # The current version as a Version instance
73
73
  CURRENT = new(MAJOR, MINOR, TINY)
data/lib/searchgasm.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
2
 
3
3
  require "active_record"
4
+ require "active_record/version"
4
5
  require "active_support"
5
6
 
6
7
  # Core Ext
@@ -33,17 +34,17 @@ require "searchgasm/conditions/base"
33
34
  # Condition
34
35
  require "searchgasm/condition/base"
35
36
  require "searchgasm/condition/begins_with"
37
+ require "searchgasm/condition/blank"
36
38
  require "searchgasm/condition/contains"
37
39
  require "searchgasm/condition/does_not_equal"
38
40
  require "searchgasm/condition/ends_with"
39
41
  require "searchgasm/condition/equals"
40
42
  require "searchgasm/condition/greater_than"
41
43
  require "searchgasm/condition/greater_than_or_equal_to"
42
- require "searchgasm/condition/is_blank"
43
- require "searchgasm/condition/is_nil"
44
44
  require "searchgasm/condition/keywords"
45
45
  require "searchgasm/condition/less_than"
46
46
  require "searchgasm/condition/less_than_or_equal_to"
47
+ require "searchgasm/condition/nil"
47
48
  require "searchgasm/condition/tree"
48
49
  require "searchgasm/condition/child_of"
49
50
  require "searchgasm/condition/descendant_of"
@@ -77,7 +78,7 @@ module Searchgasm
77
78
  include Protection
78
79
  end
79
80
 
80
- [:begins_with, :child_of, :contains, :descendant_of, :does_not_equal, :ends_with, :equals, :greater_than, :greater_than_or_equal_to, :inclusive_descendant_of, :is_blank, :is_nil, :keywords, :less_than, :less_than_or_equal_to, :sibling_of].each do |condition|
81
+ [:begins_with, :blank, :child_of, :contains, :descendant_of, :does_not_equal, :ends_with, :equals, :greater_than, :greater_than_or_equal_to, :inclusive_descendant_of, :nil, :keywords, :less_than, :less_than_or_equal_to, :sibling_of].each do |condition|
81
82
  Base.register_condition("Searchgasm::Condition::#{condition.to_s.camelize}".constantize)
82
83
  end
83
84
  end
data/searchgasm.gemspec CHANGED
@@ -1,18 +1,18 @@
1
1
 
2
- # Gem::Specification for Searchgasm-1.2.1
2
+ # Gem::Specification for Searchgasm-1.2.2
3
3
  # Originally generated by Echoe
4
4
 
5
5
  --- !ruby/object:Gem::Specification
6
6
  name: searchgasm
7
7
  version: !ruby/object:Gem::Version
8
- version: 1.2.1
8
+ version: 1.2.2
9
9
  platform: ruby
10
10
  authors:
11
11
  - Ben Johnson of Binary Logic
12
12
  autorequire:
13
13
  bindir: bin
14
14
 
15
- date: 2008-09-26 00:00:00 -04:00
15
+ date: 2008-09-29 00:00:00 -04:00
16
16
  default_executable:
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
@@ -55,22 +55,26 @@ extra_rdoc_files:
55
55
  - CHANGELOG.rdoc
56
56
  - lib/searchgasm/active_record/associations.rb
57
57
  - lib/searchgasm/active_record/base.rb
58
+ - lib/searchgasm/active_record/connection_adapters/mysql_adapter.rb
59
+ - lib/searchgasm/active_record/connection_adapters/postgresql_adapter.rb
60
+ - lib/searchgasm/active_record/connection_adapters/sqlite_adapter.rb
58
61
  - lib/searchgasm/condition/base.rb
59
62
  - lib/searchgasm/condition/begins_with.rb
63
+ - lib/searchgasm/condition/blank.rb
60
64
  - lib/searchgasm/condition/child_of.rb
61
65
  - lib/searchgasm/condition/contains.rb
62
66
  - lib/searchgasm/condition/descendant_of.rb
63
67
  - lib/searchgasm/condition/does_not_equal.rb
68
+ - lib/searchgasm/condition/during_evening.rb
64
69
  - lib/searchgasm/condition/ends_with.rb
65
70
  - lib/searchgasm/condition/equals.rb
66
71
  - lib/searchgasm/condition/greater_than.rb
67
72
  - lib/searchgasm/condition/greater_than_or_equal_to.rb
68
73
  - lib/searchgasm/condition/inclusive_descendant_of.rb
69
- - lib/searchgasm/condition/is_blank.rb
70
- - lib/searchgasm/condition/is_nil.rb
71
74
  - lib/searchgasm/condition/keywords.rb
72
75
  - lib/searchgasm/condition/less_than.rb
73
76
  - lib/searchgasm/condition/less_than_or_equal_to.rb
77
+ - lib/searchgasm/condition/nil.rb
74
78
  - lib/searchgasm/condition/sibling_of.rb
75
79
  - lib/searchgasm/condition/tree.rb
76
80
  - lib/searchgasm/conditions/base.rb
@@ -96,28 +100,33 @@ extra_rdoc_files:
96
100
  - lib/searchgasm/version.rb
97
101
  - lib/searchgasm.rb
98
102
  - README.rdoc
103
+ - TODO.rdoc
99
104
  files:
100
105
  - CHANGELOG.rdoc
101
106
  - examples/README.rdoc
102
107
  - init.rb
103
108
  - lib/searchgasm/active_record/associations.rb
104
109
  - lib/searchgasm/active_record/base.rb
110
+ - lib/searchgasm/active_record/connection_adapters/mysql_adapter.rb
111
+ - lib/searchgasm/active_record/connection_adapters/postgresql_adapter.rb
112
+ - lib/searchgasm/active_record/connection_adapters/sqlite_adapter.rb
105
113
  - lib/searchgasm/condition/base.rb
106
114
  - lib/searchgasm/condition/begins_with.rb
115
+ - lib/searchgasm/condition/blank.rb
107
116
  - lib/searchgasm/condition/child_of.rb
108
117
  - lib/searchgasm/condition/contains.rb
109
118
  - lib/searchgasm/condition/descendant_of.rb
110
119
  - lib/searchgasm/condition/does_not_equal.rb
120
+ - lib/searchgasm/condition/during_evening.rb
111
121
  - lib/searchgasm/condition/ends_with.rb
112
122
  - lib/searchgasm/condition/equals.rb
113
123
  - lib/searchgasm/condition/greater_than.rb
114
124
  - lib/searchgasm/condition/greater_than_or_equal_to.rb
115
125
  - lib/searchgasm/condition/inclusive_descendant_of.rb
116
- - lib/searchgasm/condition/is_blank.rb
117
- - lib/searchgasm/condition/is_nil.rb
118
126
  - lib/searchgasm/condition/keywords.rb
119
127
  - lib/searchgasm/condition/less_than.rb
120
128
  - lib/searchgasm/condition/less_than_or_equal_to.rb
129
+ - lib/searchgasm/condition/nil.rb
121
130
  - lib/searchgasm/condition/sibling_of.rb
122
131
  - lib/searchgasm/condition/tree.rb
123
132
  - lib/searchgasm/conditions/base.rb
@@ -165,6 +174,7 @@ files:
165
174
  - test/test_search_ordering.rb
166
175
  - test/test_search_pagination.rb
167
176
  - test/test_search_protection.rb
177
+ - TODO.rdoc
168
178
  - searchgasm.gemspec
169
179
  has_rdoc: true
170
180
  homepage: http://github.com/binarylogic/searchgasm
@@ -186,7 +196,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
186
196
  version:
187
197
  required_rubygems_version: !ruby/object:Gem::Requirement
188
198
  requirements:
189
- - - "="
199
+ - - ">="
190
200
  - !ruby/object:Gem::Version
191
201
  version: "1.2"
192
202
  version:
@@ -11,6 +11,7 @@ class TestActiveRecordBase < Test::Unit::TestCase
11
11
  assert_equal 1, Account.find(:first).id
12
12
  assert_equal [1,2,3], Account.find(:all, nil).map(&:id)
13
13
  assert_equal [1,2,3], Account.find(:all, {}).map(&:id)
14
+ assert_equal [1,2,3], Account.find(:all, :select => "id, name").map(&:id)
14
15
  end
15
16
 
16
17
  def test_standard_calculations
@@ -12,16 +12,18 @@ class TestConditionBase < Test::Unit::TestCase
12
12
  assert_equal nil, Searchgasm::Condition::Keywords.name_for_column(Account.columns_hash["id"])
13
13
  end
14
14
 
15
- def test_ignore_blanks?
16
- assert !Searchgasm::Condition::Equals.ignore_blanks?
17
- assert Searchgasm::Condition::Keywords.ignore_blanks?
15
+ def test_ignore_meaningless?
16
+ assert !Searchgasm::Condition::Equals.ignore_meaningless?
17
+ assert Searchgasm::Condition::Keywords.ignore_meaningless?
18
+ assert !Searchgasm::Condition::DoesNotEqual.ignore_meaningless?
18
19
  end
19
20
 
20
- def test_type_cast_value?
21
- assert Searchgasm::Condition::Equals.type_cast_value?
22
- assert Searchgasm::Condition::Keywords.type_cast_value?
23
- assert !Searchgasm::Condition::IsNil.type_cast_value?
24
- assert !Searchgasm::Condition::IsBlank.type_cast_value?
21
+ def test_type_cast_sql_type
22
+ assert_equal nil, Searchgasm::Condition::Equals.type_cast_sql_type
23
+ assert_equal nil, Searchgasm::Condition::Keywords.type_cast_sql_type
24
+ assert_equal "boolean", Searchgasm::Condition::Nil.type_cast_sql_type
25
+ assert_equal "boolean", Searchgasm::Condition::Blank.type_cast_sql_type
26
+ assert_equal nil, Searchgasm::Condition::GreaterThan.type_cast_sql_type
25
27
  end
26
28
 
27
29
  def test_string_column
@@ -6,6 +6,30 @@ class TestConditionTypes < Test::Unit::TestCase
6
6
  condition.value = "Binary"
7
7
  assert_equal condition.sanitize, ["\"accounts\".\"name\" LIKE ?", "Binary%"]
8
8
 
9
+ condition = Searchgasm::Condition::Blank.new(Account, Account.columns_hash["id"])
10
+ condition.value = true
11
+ assert_equal condition.sanitize, "\"accounts\".\"id\" is NULL or \"accounts\".\"id\" = ''"
12
+
13
+ condition = Searchgasm::Condition::Blank.new(Account, Account.columns_hash["id"])
14
+ condition.value = false
15
+ assert_equal condition.sanitize, "\"accounts\".\"id\" is NOT NULL and \"accounts\".\"id\" != ''"
16
+
17
+ condition = Searchgasm::Condition::Blank.new(Account, Account.columns_hash["id"])
18
+ condition.value = "true"
19
+ assert_equal condition.sanitize, "\"accounts\".\"id\" is NULL or \"accounts\".\"id\" = ''"
20
+
21
+ condition = Searchgasm::Condition::Blank.new(Account, Account.columns_hash["id"])
22
+ condition.value = "false"
23
+ assert_equal condition.sanitize, "\"accounts\".\"id\" is NOT NULL and \"accounts\".\"id\" != ''"
24
+
25
+ condition = Searchgasm::Condition::Blank.new(Account, Account.columns_hash["id"])
26
+ condition.value = nil
27
+ assert_equal condition.sanitize, nil
28
+
29
+ condition = Searchgasm::Condition::Blank.new(Account, Account.columns_hash["id"])
30
+ condition.value = ""
31
+ assert_equal condition.sanitize, nil
32
+
9
33
  condition = Searchgasm::Condition::ChildOf.new(User)
10
34
  condition.value = User.first.id
11
35
  assert_equal condition.sanitize, ["\"users\".\"parent_id\" = ?", User.first.id]
@@ -62,51 +86,27 @@ class TestConditionTypes < Test::Unit::TestCase
62
86
  condition.value = User.find(1)
63
87
  assert_equal condition.sanitize, ["(\"users\".\"id\" = ?) OR (\"users\".\"id\" = ? OR \"users\".\"id\" = ?)", 1, 2, 3]
64
88
 
65
- condition = Searchgasm::Condition::IsBlank.new(Account, Account.columns_hash["id"])
66
- condition.value = true
67
- assert_equal condition.sanitize, "\"accounts\".\"id\" is NULL or \"accounts\".\"id\" = ''"
68
-
69
- condition = Searchgasm::Condition::IsBlank.new(Account, Account.columns_hash["id"])
70
- condition.value = false
71
- assert_equal condition.sanitize, "\"accounts\".\"id\" is NOT NULL and \"accounts\".\"id\" != ''"
72
-
73
- condition = Searchgasm::Condition::IsBlank.new(Account, Account.columns_hash["id"])
74
- condition.value = "true"
75
- assert_equal condition.sanitize, "\"accounts\".\"id\" is NULL or \"accounts\".\"id\" = ''"
76
-
77
- condition = Searchgasm::Condition::IsBlank.new(Account, Account.columns_hash["id"])
78
- condition.value = "false"
79
- assert_equal condition.sanitize, "\"accounts\".\"id\" is NOT NULL and \"accounts\".\"id\" != ''"
80
-
81
- condition = Searchgasm::Condition::IsBlank.new(Account, Account.columns_hash["id"])
82
- condition.value = nil
83
- assert_equal condition.sanitize, nil
84
-
85
- condition = Searchgasm::Condition::IsBlank.new(Account, Account.columns_hash["id"])
86
- condition.value = ""
87
- assert_equal condition.sanitize, nil
88
-
89
- condition = Searchgasm::Condition::IsNil.new(Account, Account.columns_hash["id"])
89
+ condition = Searchgasm::Condition::Nil.new(Account, Account.columns_hash["id"])
90
90
  condition.value = true
91
91
  assert_equal condition.sanitize, "\"accounts\".\"id\" is NULL"
92
92
 
93
- condition = Searchgasm::Condition::IsNil.new(Account, Account.columns_hash["id"])
93
+ condition = Searchgasm::Condition::Nil.new(Account, Account.columns_hash["id"])
94
94
  condition.value = false
95
95
  assert_equal condition.sanitize, "\"accounts\".\"id\" is NOT NULL"
96
96
 
97
- condition = Searchgasm::Condition::IsNil.new(Account, Account.columns_hash["id"])
97
+ condition = Searchgasm::Condition::Nil.new(Account, Account.columns_hash["id"])
98
98
  condition.value = "true"
99
99
  assert_equal condition.sanitize, "\"accounts\".\"id\" is NULL"
100
100
 
101
- condition = Searchgasm::Condition::IsNil.new(Account, Account.columns_hash["id"])
101
+ condition = Searchgasm::Condition::Nil.new(Account, Account.columns_hash["id"])
102
102
  condition.value = "false"
103
103
  assert_equal condition.sanitize, "\"accounts\".\"id\" is NOT NULL"
104
104
 
105
- condition = Searchgasm::Condition::IsNil.new(Account, Account.columns_hash["id"])
105
+ condition = Searchgasm::Condition::Nil.new(Account, Account.columns_hash["id"])
106
106
  condition.value = nil
107
107
  assert_equal condition.sanitize, nil
108
108
 
109
- condition = Searchgasm::Condition::IsNil.new(Account, Account.columns_hash["id"])
109
+ condition = Searchgasm::Condition::Nil.new(Account, Account.columns_hash["id"])
110
110
  condition.value = ""
111
111
  assert_equal condition.sanitize, nil
112
112
 
@@ -22,6 +22,7 @@ class TestConditionsBase < Test::Unit::TestCase
22
22
  assert !Searchgasm::Conditions::Base.needed?(User, {})
23
23
  assert !Searchgasm::Conditions::Base.needed?(User, {:first_name => "Ben"})
24
24
  assert Searchgasm::Conditions::Base.needed?(User, {:first_name_contains => "Awesome"})
25
+ assert !Searchgasm::Conditions::Base.needed?(User, {"orders.id" => 2})
25
26
  end
26
27
 
27
28
  def test_initialize
@@ -180,6 +180,10 @@ class TestSearchBase < Test::Unit::TestCase
180
180
  assert_equal [Account.find(1)], search.find(:all)
181
181
  assert_equal Account.find(1), search.first
182
182
  assert_equal Account.find(1), search.find(:first)
183
+
184
+ search = Account.new_search
185
+ search.select = "id, name"
186
+ assert_equal Account.all, search.all
183
187
  end
184
188
 
185
189
  def test_calculations
@@ -1,6 +1,18 @@
1
1
  require File.dirname(__FILE__) + '/test_helper.rb'
2
2
 
3
3
  class TestSearchOrdering < Test::Unit::TestCase
4
+ def test_order_to_order_by
5
+ search = Account.new_search
6
+ search.order = "name"
7
+ assert_equal "name", search.order_by
8
+ search.order = "users.first_name"
9
+ assert_equal({"users" => "first_name"}, search.order_by)
10
+ search.order = "\"users\".\"first_name\""
11
+ assert_equal({"users" => "first_name"}, search.order_by)
12
+ search.order = "\"users\".\"first_name\", name ASC"
13
+ assert_equal([{"users" => "first_name"}, "name"], search.order_by)
14
+ end
15
+
4
16
  def test_order_by
5
17
  search = Account.new_search
6
18
  assert_equal nil, search.order
@@ -55,7 +67,8 @@ class TestSearchOrdering < Test::Unit::TestCase
55
67
  search = Account.new_search
56
68
  assert_equal nil, search.order
57
69
  assert_equal nil, search.order_as
58
- assert !search.asc?
70
+ assert search.asc?
71
+ assert !search.desc?
59
72
 
60
73
  search.order_as = "DESC"
61
74
  assert_equal nil, search.order_as
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: searchgasm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
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-09-26 00:00:00 -04:00
12
+ date: 2008-09-29 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -52,22 +52,26 @@ extra_rdoc_files:
52
52
  - CHANGELOG.rdoc
53
53
  - lib/searchgasm/active_record/associations.rb
54
54
  - lib/searchgasm/active_record/base.rb
55
+ - lib/searchgasm/active_record/connection_adapters/mysql_adapter.rb
56
+ - lib/searchgasm/active_record/connection_adapters/postgresql_adapter.rb
57
+ - lib/searchgasm/active_record/connection_adapters/sqlite_adapter.rb
55
58
  - lib/searchgasm/condition/base.rb
56
59
  - lib/searchgasm/condition/begins_with.rb
60
+ - lib/searchgasm/condition/blank.rb
57
61
  - lib/searchgasm/condition/child_of.rb
58
62
  - lib/searchgasm/condition/contains.rb
59
63
  - lib/searchgasm/condition/descendant_of.rb
60
64
  - lib/searchgasm/condition/does_not_equal.rb
65
+ - lib/searchgasm/condition/during_evening.rb
61
66
  - lib/searchgasm/condition/ends_with.rb
62
67
  - lib/searchgasm/condition/equals.rb
63
68
  - lib/searchgasm/condition/greater_than.rb
64
69
  - lib/searchgasm/condition/greater_than_or_equal_to.rb
65
70
  - lib/searchgasm/condition/inclusive_descendant_of.rb
66
- - lib/searchgasm/condition/is_blank.rb
67
- - lib/searchgasm/condition/is_nil.rb
68
71
  - lib/searchgasm/condition/keywords.rb
69
72
  - lib/searchgasm/condition/less_than.rb
70
73
  - lib/searchgasm/condition/less_than_or_equal_to.rb
74
+ - lib/searchgasm/condition/nil.rb
71
75
  - lib/searchgasm/condition/sibling_of.rb
72
76
  - lib/searchgasm/condition/tree.rb
73
77
  - lib/searchgasm/conditions/base.rb
@@ -93,28 +97,33 @@ extra_rdoc_files:
93
97
  - lib/searchgasm/version.rb
94
98
  - lib/searchgasm.rb
95
99
  - README.rdoc
100
+ - TODO.rdoc
96
101
  files:
97
102
  - CHANGELOG.rdoc
98
103
  - examples/README.rdoc
99
104
  - init.rb
100
105
  - lib/searchgasm/active_record/associations.rb
101
106
  - lib/searchgasm/active_record/base.rb
107
+ - lib/searchgasm/active_record/connection_adapters/mysql_adapter.rb
108
+ - lib/searchgasm/active_record/connection_adapters/postgresql_adapter.rb
109
+ - lib/searchgasm/active_record/connection_adapters/sqlite_adapter.rb
102
110
  - lib/searchgasm/condition/base.rb
103
111
  - lib/searchgasm/condition/begins_with.rb
112
+ - lib/searchgasm/condition/blank.rb
104
113
  - lib/searchgasm/condition/child_of.rb
105
114
  - lib/searchgasm/condition/contains.rb
106
115
  - lib/searchgasm/condition/descendant_of.rb
107
116
  - lib/searchgasm/condition/does_not_equal.rb
117
+ - lib/searchgasm/condition/during_evening.rb
108
118
  - lib/searchgasm/condition/ends_with.rb
109
119
  - lib/searchgasm/condition/equals.rb
110
120
  - lib/searchgasm/condition/greater_than.rb
111
121
  - lib/searchgasm/condition/greater_than_or_equal_to.rb
112
122
  - lib/searchgasm/condition/inclusive_descendant_of.rb
113
- - lib/searchgasm/condition/is_blank.rb
114
- - lib/searchgasm/condition/is_nil.rb
115
123
  - lib/searchgasm/condition/keywords.rb
116
124
  - lib/searchgasm/condition/less_than.rb
117
125
  - lib/searchgasm/condition/less_than_or_equal_to.rb
126
+ - lib/searchgasm/condition/nil.rb
118
127
  - lib/searchgasm/condition/sibling_of.rb
119
128
  - lib/searchgasm/condition/tree.rb
120
129
  - lib/searchgasm/conditions/base.rb
@@ -162,6 +171,7 @@ files:
162
171
  - test/test_search_ordering.rb
163
172
  - test/test_search_pagination.rb
164
173
  - test/test_search_protection.rb
174
+ - TODO.rdoc
165
175
  - searchgasm.gemspec
166
176
  has_rdoc: true
167
177
  homepage: http://github.com/binarylogic/searchgasm
@@ -183,7 +193,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
193
  version:
184
194
  required_rubygems_version: !ruby/object:Gem::Requirement
185
195
  requirements:
186
- - - "="
196
+ - - ">="
187
197
  - !ruby/object:Gem::Version
188
198
  version: "1.2"
189
199
  version:
@@ -1,23 +0,0 @@
1
- module Searchgasm
2
- module Condition
3
- class IsNil < Base
4
- self.ignore_blanks = false
5
- self.type_cast_value = false
6
-
7
- class << self
8
- def aliases_for_column(column)
9
- ["#{column.name}_nil", "#{column.name}_is_null", "#{column.name}_null"]
10
- end
11
- end
12
-
13
- def to_conditions(value)
14
- # Some databases handle null values differently, let AR handle this
15
- if value == true || value == "true" || value == 1 || value == "1"
16
- "#{quoted_table_name}.#{quoted_column_name} is NULL"
17
- elsif value == false || value == "false" || value == 0 || value == "0"
18
- "#{quoted_table_name}.#{quoted_column_name} is NOT NULL"
19
- end
20
- end
21
- end
22
- end
23
- end