searchgasm 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,4 +1,10 @@
1
- == 1.0.1 released 2008-09-08
1
+ == 1.0.2 released 2008-09-12
2
+
3
+ * Moved cached searchers out of the global namespace and into the Searchgasm::Cache namespce.
4
+ * Various changes to improve performance. Added in benchmark reports in readme as well as a benchmarks directory.
5
+ * Config.per_page works with new_search & new_search! only. Where as before it was only working if the search was protected.
6
+
7
+ == 1.0.1 released 2008-09-11
2
8
 
3
9
  * Cached "searchers" so when a new search object is instantiated it doesn't go through all of the meta programming and method creation. Helps a lot with performance. You will see the speed benefits after the first instantiation.
4
10
  * Added in new options for page_links.
data/Manifest CHANGED
@@ -1,3 +1,6 @@
1
+ benchmarks/benchmark.rb
2
+ benchmarks/benchmark_helper.rb
3
+ benchmarks/profile.rb
1
4
  CHANGELOG.rdoc
2
5
  examples/README.rdoc
3
6
  init.rb
@@ -57,6 +60,7 @@ test/test_condition_base.rb
57
60
  test/test_condition_types.rb
58
61
  test/test_conditions_base.rb
59
62
  test/test_conditions_protection.rb
63
+ test/test_config.rb
60
64
  test/test_helper.rb
61
65
  test/test_search_base.rb
62
66
  test/test_search_conditions.rb
data/README.rdoc CHANGED
@@ -55,7 +55,7 @@ In both examples, instead of using the "all" method you could use any search met
55
55
 
56
56
  == The beauty of searchgasm, integration into rails
57
57
 
58
- Using Searchgasm in rails is the best part, because rails has all kinds of nifty methods to make dealing with ActiveRecord objects quick and easy, especially with forms. So let's take advantage of them! That's the idea behind this plugin. Searchgasm is searching, ordering, and pagination all rolled into one simple plugin. Take all of that pagination and searching cruft out of your models and let Searchgasm handle it. Check it out:
58
+ Using Searchgasm in rails is the best part, because rails has all kinds of nifty methods to make dealing with ActiveRecord objects quick and easy, especially with forms. So let's take advantage of them! That's the idea behind this plugin. Searchgasm is searching, ordering, and pagination all rolled into one simple plugin. Take all of that pagination and searching cruft out of your models and controllers, and let Searchgasm handle it. Check it out:
59
59
 
60
60
  # app/controllers/users_controller.rb
61
61
  def index
@@ -63,15 +63,7 @@ Using Searchgasm in rails is the best part, because rails has all kinds of nifty
63
63
  @users, @users_count = @search.all, @search.count
64
64
  end
65
65
 
66
- Now your view. Things to note in this view:
67
-
68
- 1. Passing a search object right into form\_for and fields\_for
69
- 2. The built in conditions for each column and how you can traverse the relationships and set conditions on them
70
- 3. The order_by_link helper
71
- 4. The page_select and per_page_select helpers
72
- 5. All of your search logic is in 1 spot: your view. Nice and DRY.
73
-
74
- Your view:
66
+ Now your view:
75
67
 
76
68
  # app/views/users/index.html.haml
77
69
  - form_for @search do |f|
@@ -103,6 +95,14 @@ Your view:
103
95
  - else
104
96
  No users were found.
105
97
 
98
+ Things to note in this view:
99
+
100
+ 1. Passing a search object right into form\_for and fields\_for
101
+ 2. The built in conditions for each column and how you can traverse the relationships and set conditions on them
102
+ 3. The order_by_link helper
103
+ 4. The page_select and per_page_select helpers
104
+ 5. All of your search logic is in 1 spot: your view. Nice and DRY.
105
+
106
106
  <b>See my tutorial on this example: http://www.binarylogic.com/2008/9/7/tutorial-pagination-ordering-and-searching-with-searchgasm</b>
107
107
 
108
108
  == Exhaustive Example w/ Object Based Searching (great for form_for or fields_for)
@@ -230,7 +230,7 @@ Not only can you use searchgasm when searching, but you can use it when setting
230
230
 
231
231
  == Always use protection...against SQL injections
232
232
 
233
- If there is one thing we all know, it's to always use protection against SQL injections. That's why searchgasm protects you by default. The new\_search and new\_conditions methods are protected by default. This means that various checks are done to ensure it is not possible to perform any type of SQL injection. But this also limits how you can search, meaning you can't write raw SQL. If you want to be daring and search without protection, all that you have to do is add ! to the end of the methods: new\_search! and new\_conditions!.
233
+ If there is one thing we all know, it's to always use protection against SQL injections. That's why searchgasm protects you by default. The new\_search and new\_conditions methods protect mass assignments by default (instantiation and search.options = {}). This means that various checks are done to ensure it is not possible to perform any type of SQL injection during mass assignments. But this also limits how you can search, meaning you can't write raw SQL. If you want to be daring and search without protection, all that you have to do is add ! to the end of the methods: new\_search! and new\_conditions!.
234
234
 
235
235
  === Protected from SQL injections
236
236
 
@@ -296,7 +296,7 @@ I want to use it, so let's add it:
296
296
  class << self
297
297
  # I pass you the column, you tell me what you want the method to be called.
298
298
  # If you don't want to add this condition for that column, return nil
299
- # It defaults to "#{column.name}_sounds_like". So if thats what you want you don't even need to do this.
299
+ # It defaults to "#{column.name}_sounds_like" (using the class name). So if thats what you want you don't even need to do this.
300
300
  def name_for_column(column)
301
301
  super
302
302
  end
@@ -309,7 +309,8 @@ I want to use it, so let's add it:
309
309
 
310
310
  # You can return an array or a string. NOT a hash, because all of these conditions
311
311
  # need to eventually get merged together. The array or string can be anything you would put in
312
- # the :conditions option for ActiveRecord::Base.find()
312
+ # the :conditions option for ActiveRecord::Base.find(). Also, for a list of methods / variables you can use check out
313
+ # Searchgasm::Condition::Base.
313
314
  def to_conditions(value)
314
315
  ["#{quoted_table_name}.#{quoted_column_name} SOUNDS LIKE ?", value]
315
316
  end
@@ -329,6 +330,21 @@ Pretty nifty, huh? You can create any condition ultimately creating any SQL you
329
330
 
330
331
  I'm a big fan of understanding what I'm using, so here's a quick explanation: The design behind this plugin is pretty simple. The search object "sanitizes" down into the options passed into ActiveRecord::Base.find(). It serves as a transparent filter between you and ActiveRecord::Base.find(). This filter provides "enhancements" that get translated into options that ActiveRecord::Base.find() can understand. It doesn't dig into the ActiveRecord internals, it only uses what is publicly available. It jumps in and helps out <em>only</em> when needed, otherwise it sits back and lets ActiveRecord do all of the work. Between that and the extensive tests, this is a solid and fast plugin.
331
332
 
333
+ == Performance / Benchmarking
334
+
335
+ I ran searchgasm through some performance tests using ruby-prof. After working on it for a little while I improved performance quite a bit. Notice the "2nd instantiation" report. This is implementing caching and skips all dynamic method creation / meta programming. It resulted in code over 50 times faster.
336
+
337
+ user system total real
338
+ 1st instantiation: 0.000000 0.000000 0.000000 ( 0.005466)
339
+ 2nd instantiation: 0.000000 0.000000 0.000000 ( 0.000108)
340
+ Local ordering: 0.000000 0.000000 0.000000 ( 0.000265)
341
+ Advanced ordering: 0.000000 0.000000 0.000000 ( 0.000413)
342
+ Local conditions: 0.000000 0.000000 0.000000 ( 0.000241)
343
+ Advanced conditions: 0.000000 0.000000 0.000000 ( 0.000602)
344
+ Its complicated: 0.000000 0.000000 0.000000 ( 0.001017)
345
+
346
+ I also included the benchmarking file in benchmarks/benchmark.rb to see for yourself.
347
+
332
348
  == Reporting problems / bugs
333
349
 
334
350
  http://binarylogic.lighthouseapp.com/projects/16601-searchgasm
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/benchmark_helper.rb'
2
+
3
+ times = 1
4
+
5
+ Benchmark.bm(20) do |x|
6
+ x.report("1st instantiation:") { Account.new_search }
7
+ x.report("2nd instantiation:") { Account.new_search }
8
+
9
+ # Now that we see the benefits of caching, lets cache the rest of the classes and perform the rest of the tests,
10
+ # so that they are fair
11
+ User.new_search
12
+ Order.new_search
13
+
14
+ x.report("Local ordering:") do
15
+ times.times do
16
+ Account.new_search(:order_by => :name).sanitize
17
+ end
18
+ end
19
+
20
+ x.report("Advanced ordering:") do
21
+ times.times do
22
+ Account.new_search(:order_by => {:users => {:orders => :total}}).sanitize
23
+ end
24
+ end
25
+
26
+ x.report("Local conditions:") do
27
+ times.times do
28
+ Account.new_search(:conditions => {:name_like => "Binary"}).sanitize
29
+ end
30
+ end
31
+
32
+ x.report("Advanced conditions:") do
33
+ times.times do
34
+ Account.new_search(:conditions => {:users => {:orders => {:total_gt => 1}}}).sanitize
35
+ end
36
+ end
37
+
38
+ x.report("Its complicated:") do
39
+ times.times do
40
+ Account.new_search(:conditions => {:users => {:orders => {:total_gt => 1, :created_at_after => Time.now}, :first_name_like => "Ben"}, :name_begins_with => "Awesome"}, :per_page => 20, :page => 2, :order_by => {:users => {:orders => :total}}, :order_as => "ASC").sanitize
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,52 @@
1
+ require "rubygems"
2
+ require "benchmark"
3
+ require "ruby-prof"
4
+ require "activerecord"
5
+ require File.dirname(__FILE__) + '/../test/libs/acts_as_tree'
6
+ require File.dirname(__FILE__) + '/../lib/searchgasm'
7
+
8
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
9
+
10
+ ActiveRecord::Schema.define(:version => 1) do
11
+ create_table :accounts do |t|
12
+ t.datetime :created_at
13
+ t.datetime :updated_at
14
+ t.string :name
15
+ t.boolean :active
16
+ end
17
+
18
+ create_table :users do |t|
19
+ t.datetime :created_at
20
+ t.datetime :updated_at
21
+ t.integer :account_id
22
+ t.integer :parent_id
23
+ t.string :first_name
24
+ t.string :last_name
25
+ t.boolean :active
26
+ t.text :bio
27
+ end
28
+
29
+ create_table :orders do |t|
30
+ t.datetime :created_at
31
+ t.datetime :updated_at
32
+ t.integer :user_id
33
+ t.float :total
34
+ t.text :description
35
+ t.binary :receipt
36
+ end
37
+ end
38
+
39
+ class Account < ActiveRecord::Base
40
+ has_many :users, :dependent => :destroy
41
+ has_many :orders, :through => :users
42
+ end
43
+
44
+ class User < ActiveRecord::Base
45
+ acts_as_tree
46
+ belongs_to :account
47
+ has_many :orders, :dependent => :destroy
48
+ end
49
+
50
+ class Order < ActiveRecord::Base
51
+ belongs_to :user
52
+ end
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/benchmark_helper.rb'
2
+ require "ruby-prof"
3
+
4
+ Account.new_search
5
+ User.new_search
6
+ Order.new_search
7
+
8
+ RubyProf.start
9
+
10
+ # Put profile code here
11
+
12
+ result = RubyProf.stop
13
+
14
+ printer = RubyProf::FlatPrinter.new(result)
15
+ printer.print(STDOUT, 0)
@@ -118,7 +118,9 @@ module Searchgasm
118
118
  private
119
119
  def sanitize_options_with_searchgasm(options = {})
120
120
  return options unless Searchgasm::Search::Base.needed?(self, options)
121
- searchgasm_searcher(options).sanitize
121
+ search = searchgasm_searcher(options)
122
+ search.acting_as_filter = true
123
+ search.sanitize
122
124
  end
123
125
 
124
126
  def searchgasm_conditions(options = {})
@@ -22,7 +22,7 @@ module Searchgasm
22
22
  # class << self
23
23
  # # I pass you the column, you tell me what you want the method to be called.
24
24
  # # If you don't want to add this condition for that column, return nil
25
- # # It defaults to "#{column.name}_sounds_like". So if thats what you want you don't even need to do this.
25
+ # # It defaults to "#{column.name}_sounds_like" (using the class name). So if thats what you want you don't even need to do this.
26
26
  # def name_for_column(column)
27
27
  # super
28
28
  # end
@@ -35,7 +35,7 @@ module Searchgasm
35
35
  #
36
36
  # # You can return an array or a string. NOT a hash, because all of these conditions
37
37
  # # need to eventually get merged together. The array or string can be anything you would put in
38
- # # the :conditions option for ActiveRecord::Base.find()
38
+ # # the :conditions option for ActiveRecord::Base.find(). Also, for a list of methods / variables you can use check out earchgasm::Condition::Base
39
39
  # def to_conditions(value)
40
40
  # ["#{quoted_table_name}.#{quoted_column_name} SOUNDS LIKE ?", value]
41
41
  # end
@@ -75,24 +75,26 @@ module Searchgasm
75
75
  # Creates virtual classes for the class passed to it. This is a neccesity for keeping dynamically created method
76
76
  # names specific to models. It provides caching and helps a lot with performance.
77
77
  def create_virtual_class(model_class)
78
- class_search_name = "::#{model_class.name}Conditions"
78
+ class_search_name = "::Searchgasm::Cache::#{model_class.name}Conditions"
79
79
 
80
80
  begin
81
- class_search_name.constantize
81
+ eval(class_search_name)
82
82
  rescue NameError
83
83
  eval <<-end_eval
84
- class #{class_search_name} < ::Searchgasm::Conditions::Base; end;
84
+ class #{class_search_name} < ::Searchgasm::Conditions::Base
85
+ def self.klass
86
+ #{model_class.name}
87
+ end
88
+
89
+ def klass
90
+ #{model_class.name}
91
+ end
92
+ end
93
+
94
+ #{class_search_name}
85
95
  end_eval
86
-
87
- class_search_name.constantize
88
96
  end
89
97
  end
90
-
91
- # The class / model we are searching
92
- def klass
93
- # Can't cache this because thin and mongrel don't play nice with caching constants
94
- name.split("::").last.gsub(/Conditions$/, "").constantize
95
- end
96
98
  end
97
99
 
98
100
  def initialize(init_conditions = {})
@@ -123,10 +125,6 @@ module Searchgasm
123
125
  i.blank? ? nil : (i.size == 1 ? i.first : i)
124
126
  end
125
127
 
126
- def klass
127
- self.class.klass
128
- end
129
-
130
128
  # Sanitizes the conditions down into conditions that ActiveRecord::Base.find can understand.
131
129
  def sanitize
132
130
  conditions = merge_conditions(*objects.collect { |object| object.sanitize })
@@ -244,7 +242,7 @@ module Searchgasm
244
242
  end
245
243
 
246
244
  def assert_valid_conditions(conditions)
247
- conditions.stringify_keys.assert_valid_keys(self.class.condition_names + self.class.association_names)
245
+ conditions.stringify_keys.fast_assert_valid_keys(self.class.condition_names + self.class.association_names)
248
246
  end
249
247
 
250
248
  def associations
@@ -15,6 +15,12 @@ module Searchgasm
15
15
 
16
16
  new_hash
17
17
  end
18
+
19
+ # assert_valid_keys was killing performance. Array.flatten was the culprit, so I rewrote this method, got a 35% performance increase
20
+ def fast_assert_valid_keys(valid_keys)
21
+ unknown_keys = keys - valid_keys
22
+ raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -32,24 +32,27 @@ module Searchgasm #:nodoc:
32
32
  # Creates virtual classes for the class passed to it. This is a neccesity for keeping dynamically created method
33
33
  # names specific to models. It provides caching and helps a lot with performance.
34
34
  def create_virtual_class(model_class)
35
- class_search_name = "::#{model_class.name}Search"
35
+ class_search_name = "::Searchgasm::Cache::#{model_class.name}Search"
36
36
 
37
37
  begin
38
- class_search_name.constantize
38
+ eval(class_search_name)
39
39
  rescue NameError
40
+ # The method definitions are for performance, bottlenecks found with ruby-prof
40
41
  eval <<-end_eval
41
- class #{class_search_name} < ::Searchgasm::Search::Base; end;
42
+ class #{class_search_name} < ::Searchgasm::Search::Base
43
+ def self.klass
44
+ #{model_class.name}
45
+ end
46
+
47
+ def klass
48
+ #{model_class.name}
49
+ end
50
+ end
51
+
52
+ #{class_search_name}
42
53
  end_eval
43
-
44
- class_search_name.constantize
45
54
  end
46
55
  end
47
-
48
- # The class / model we are searching
49
- def klass
50
- # Can't cache this because thin and mongrel don't play nice with caching constants
51
- name.split("::").last.gsub(/Search$/, "").constantize
52
- end
53
56
  end
54
57
 
55
58
  def initialize(init_options = {})
@@ -67,28 +70,40 @@ module Searchgasm #:nodoc:
67
70
  end_eval
68
71
  end
69
72
 
73
+ # Flag to determine if searchgasm is acting as a filter for the ActiveRecord search methods.
74
+ # The purpose of this is to determine if Config.per_page should be implemented.
75
+ def acting_as_filter=(value)
76
+ @acting_as_filter == true
77
+ end
78
+
79
+ # See acting_as_filter=
80
+ def acting_as_filter?
81
+ @acting_as_filter == true
82
+ end
83
+
70
84
  # Makes using searchgasm in the console less annoying and keeps the output meaningful and useful
71
85
  def inspect
72
86
  options_as_nice_string = ::ActiveRecord::Base.valid_find_options.collect { |name| "#{name}: #{send(name)}" }.join(", ")
73
87
  "#<#{klass} #{options_as_nice_string}>"
74
88
  end
75
89
 
76
- # Convenience method for self.class.klass
77
- def klass
78
- self.class.klass
79
- end
80
-
81
90
  def limit=(value)
91
+ @set_limit = true
82
92
  @limit = value.blank? || value == 0 ? nil : value.to_i
83
93
  end
84
94
 
95
+ def limit
96
+ @limit ||= Config.per_page if !acting_as_filter? && !@set_limit
97
+ @limit
98
+ end
99
+
85
100
  def offset=(value)
86
101
  @offset = value.to_i
87
102
  end
88
103
 
89
104
  def options=(values)
90
105
  return unless values.is_a?(Hash)
91
- values.symbolize_keys.assert_valid_keys(VALID_FIND_OPTIONS)
106
+ values.symbolize_keys.fast_assert_valid_keys(VALID_FIND_OPTIONS)
92
107
  values.each { |option, value| send("#{option}=", value) }
93
108
  end
94
109
 
@@ -33,6 +33,7 @@ module Searchgasm
33
33
  # now you can create the rest of your search and your "scope" will get merged into your final SQL.
34
34
  # What this does is determine if the value a hash or a conditions object, if not it sets it up as a scope.
35
35
  def conditions_with_conditions=(values)
36
+
36
37
  case values
37
38
  when Searchgasm::Conditions::Base
38
39
  @conditions = values
@@ -99,7 +99,7 @@ module Searchgasm
99
99
  # order_by = :id # => users.id ASC
100
100
  # order_by = [:id, name] # => users.id ASC, user.name ASC
101
101
  # order_by = [:id, {:user_group => :name}] # => users.id ASC, user_groups.name ASC
102
- def order_by=(value)
102
+ def order_by=(value)
103
103
  @order_by = get_order_by_value(value)
104
104
  @order = order_by_to_order(@order_by, order_as) # use @order so @order_by doesnt get reset
105
105
  @order_by
@@ -126,7 +126,7 @@ module Searchgasm
126
126
  k = order_by.keys.first
127
127
  v = order_by.values.first
128
128
  new_includes << k.to_sym
129
- sql_parts << order_by_to_order(v, order_as, k.to_s.classify.constantize, new_includes)
129
+ sql_parts << order_by_to_order(v, order_as, eval(k.to_s.classify), new_includes) # using eval, better performance, protection makes sure nothing fishy goes on here
130
130
  when Symbol, String
131
131
  new_include = build_order_by_includes(new_includes)
132
132
  self.order_by_includes << new_include if new_include
@@ -149,11 +149,15 @@ module Searchgasm
149
149
  end
150
150
 
151
151
  def quote_column_name(column_name)
152
- klass.connection.quote_column_name(column_name)
152
+ klass_connection.quote_column_name(column_name)
153
153
  end
154
154
 
155
155
  def quote_table_name(table_name)
156
- klass.connection.quote_table_name(table_name)
156
+ klass_connection.quote_table_name(table_name)
157
+ end
158
+
159
+ def klass_connection
160
+ @connection ||= klass.connection
157
161
  end
158
162
  end
159
163
  end
@@ -30,22 +30,10 @@ module Searchgasm
30
30
  def self.included(klass)
31
31
  klass.class_eval do
32
32
  attr_reader :protect
33
- alias_method_chain :limit, :protection
34
- alias_method_chain :limit=, :protection
35
33
  alias_method_chain :options=, :protection
36
34
  end
37
35
  end
38
36
 
39
- def limit_with_protection # :nodoc:
40
- return Config.per_page if protected? && !@set_limit
41
- limit_without_protection
42
- end
43
-
44
- def limit_with_protection=(value) # :nodoc:
45
- @set_limit = true
46
- self.limit_without_protection = value
47
- end
48
-
49
37
  def options_with_protection=(values) # :nodoc:
50
38
  return unless values.is_a?(Hash)
51
39
  self.protect = values.delete(:protect) if values.has_key?(:protect) # make sure we do this first
@@ -88,7 +76,7 @@ module Searchgasm
88
76
  end
89
77
 
90
78
  def frisk!(options)
91
- options.symbolize_keys.assert_valid_keys(SAFE_OPTIONS)
79
+ options.symbolize_keys.fast_assert_valid_keys(SAFE_OPTIONS)
92
80
  raise(ArgumentError, ":order_by can only contain colum names in the string, hash, or array format") unless order_by_safe?(get_order_by_value(options[:order_by]))
93
81
  end
94
82
  end
@@ -67,7 +67,7 @@ module Searchgasm
67
67
 
68
68
  MAJOR = 1
69
69
  MINOR = 0
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,3 +1,5 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+
1
3
  require "active_record"
2
4
  require "active_support"
3
5
 
@@ -72,4 +74,8 @@ module Searchgasm
72
74
  Base.register_condition("Searchgasm::Condition::#{condition.to_s.camelize}".constantize)
73
75
  end
74
76
  end
77
+
78
+ # The namespace I put all cached search classes.
79
+ module Cache
80
+ end
75
81
  end
data/searchgasm.gemspec CHANGED
@@ -1,18 +1,18 @@
1
1
 
2
- # Gem::Specification for Searchgasm-1.0.1
2
+ # Gem::Specification for Searchgasm-1.0.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.0.1
8
+ version: 1.0.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-11 00:00:00 -04:00
15
+ date: 2008-09-12 00:00:00 -04:00
16
16
  default_executable:
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
@@ -96,6 +96,9 @@ extra_rdoc_files:
96
96
  - lib/searchgasm.rb
97
97
  - README.rdoc
98
98
  files:
99
+ - benchmarks/benchmark.rb
100
+ - benchmarks/benchmark_helper.rb
101
+ - benchmarks/profile.rb
99
102
  - CHANGELOG.rdoc
100
103
  - examples/README.rdoc
101
104
  - init.rb
@@ -155,6 +158,7 @@ files:
155
158
  - test/test_condition_types.rb
156
159
  - test/test_conditions_base.rb
157
160
  - test/test_conditions_protection.rb
161
+ - test/test_config.rb
158
162
  - test/test_helper.rb
159
163
  - test/test_search_base.rb
160
164
  - test/test_search_conditions.rb
@@ -200,6 +204,7 @@ test_files:
200
204
  - test/test_condition_types.rb
201
205
  - test/test_conditions_base.rb
202
206
  - test/test_conditions_protection.rb
207
+ - test/test_config.rb
203
208
  - test/test_helper.rb
204
209
  - test/test_search_base.rb
205
210
  - test/test_search_conditions.rb
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestConfig < Test::Unit::TestCase
4
+ fixtures :accounts, :users, :orders
5
+
6
+ def setup
7
+ setup_db
8
+ load_fixtures
9
+ end
10
+
11
+ def teardown
12
+ teardown_db
13
+ end
14
+
15
+ def test_per_page
16
+ Searchgasm::Config.per_page = 1
17
+
18
+ assert Account.count > 1
19
+ assert Account.all.size > 1
20
+ assert User.all.size > 1
21
+ assert User.find(:all, :per_page => 1).size == 1
22
+ assert User.new_search.all.size == 1
23
+ assert User.new_search(:per_page => nil).all.size > 1
24
+
25
+ Searchgasm::Config.per_page = nil
26
+
27
+ assert Account.count > 1
28
+ assert Account.all.size > 1
29
+ assert User.all.size > 1
30
+ assert User.find(:all, :per_page => 1).size == 1
31
+ assert User.new_search.all.size > 1
32
+ assert User.new_search(:per_page => 1).all.size == 1
33
+ end
34
+ end
@@ -150,10 +150,10 @@ class TestSearchBase < Test::Unit::TestCase
150
150
  def test_searching
151
151
  search = Account.new_search
152
152
  search.conditions.name_like = "Binary"
153
- assert_equal search.all, [Account.find(1), Account.find(3)]
154
- assert_equal search.find(:all), [Account.find(1), Account.find(3)]
155
- assert_equal search.first, Account.find(1)
156
- assert_equal search.find(:first), Account.find(1)
153
+ assert_equal [Account.find(1), Account.find(3)], search.all
154
+ assert_equal [Account.find(1), Account.find(3)], search.find(:all)
155
+ assert_equal Account.find(1), search.first
156
+ assert_equal Account.find(1), search.find(:first)
157
157
 
158
158
  search.per_page = 20
159
159
  search.page = 2
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.0.1
4
+ version: 1.0.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-11 00:00:00 -04:00
12
+ date: 2008-09-12 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -93,6 +93,9 @@ extra_rdoc_files:
93
93
  - lib/searchgasm.rb
94
94
  - README.rdoc
95
95
  files:
96
+ - benchmarks/benchmark.rb
97
+ - benchmarks/benchmark_helper.rb
98
+ - benchmarks/profile.rb
96
99
  - CHANGELOG.rdoc
97
100
  - examples/README.rdoc
98
101
  - init.rb
@@ -152,6 +155,7 @@ files:
152
155
  - test/test_condition_types.rb
153
156
  - test/test_conditions_base.rb
154
157
  - test/test_conditions_protection.rb
158
+ - test/test_config.rb
155
159
  - test/test_helper.rb
156
160
  - test/test_search_base.rb
157
161
  - test/test_search_conditions.rb
@@ -198,6 +202,7 @@ test_files:
198
202
  - test/test_condition_types.rb
199
203
  - test/test_conditions_base.rb
200
204
  - test/test_conditions_protection.rb
205
+ - test/test_config.rb
201
206
  - test/test_helper.rb
202
207
  - test/test_search_base.rb
203
208
  - test/test_search_conditions.rb