model_set 0.11.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -11,8 +11,8 @@ begin
11
11
  s.homepage = "http://github.com/ninjudd/model_set"
12
12
  s.description = "Easy manipulation of sets of ActiveRecord models"
13
13
  s.authors = ["Justin Balthrop"]
14
- s.add_dependency('ordered_set', '>= 1.0.0')
15
- s.add_dependency('deep_clonable', '>= 1.0.2')
14
+ s.add_dependency('ordered_set', '>= 1.0.1')
15
+ s.add_dependency('deep_clonable', '>= 1.1.0')
16
16
  s.add_dependency('activerecord', '>= 2.0.0')
17
17
  end
18
18
  Jeweler::GemcutterTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -1,7 +1,7 @@
1
1
  class ModelSet
2
2
  module Conditioned
3
3
  # Shared methods for dealing with conditions.
4
- attr_reader :conditions
4
+ attr_accessor :conditions
5
5
 
6
6
  def add_conditions!(*conditions)
7
7
  operator = conditions.shift if conditions.first.kind_of?(Symbol)
@@ -2,12 +2,12 @@ class ModelSet
2
2
  class Query
3
3
  deep_clonable
4
4
 
5
- def initialize(model_set = ModelSet)
5
+ def initialize(model_set = ModelSet, *args)
6
6
  if model_set.kind_of?(Class)
7
7
  @set_class = model_set
8
8
  else
9
9
  @set_class = model_set.class
10
- anchor!(model_set.query) if model_set.query
10
+ anchor!(model_set.query, *args) if model_set.query
11
11
  end
12
12
  end
13
13
 
@@ -57,7 +57,7 @@ class ModelSet
57
57
  end
58
58
 
59
59
  attr_reader :set_class
60
- delegate :id_field, :id_field_with_prefix, :to => :set_class
60
+ delegate :id_field, :to => :set_class
61
61
 
62
62
  def model_class
63
63
  set_class.query_model_class
@@ -71,6 +71,10 @@ class ModelSet
71
71
  model_class.table_name
72
72
  end
73
73
 
74
+ def id_field_with_prefix
75
+ "#{table_name}.#{id_field}"
76
+ end
77
+
74
78
  attr_reader :limit, :sort_order
75
79
 
76
80
  def offset
@@ -1,5 +1,8 @@
1
+ require 'solr'
2
+
1
3
  class ModelSet
2
4
  class SolrQuery < Query
5
+ attr_reader :response
3
6
  include Conditioned
4
7
 
5
8
  MAX_SOLR_RESULTS = 1000
@@ -23,37 +26,41 @@ class ModelSet
23
26
  @ids
24
27
  end
25
28
 
29
+ def config(params)
30
+ @config = @config ? @config.merge(params) : params
31
+ end
32
+
26
33
  private
27
34
 
28
35
  def fetch_results
29
- query = "#{conditions.to_s};#{@sort_order.to_s}"
30
-
31
- solr_params = []
32
- solr_params << "q=#{ ERB::Util::url_encode(query) }"
33
- solr_params << "wt=ruby"
34
- solr_params << "fl=pk_i"
35
-
36
+ query = "#{conditions.to_s}"
37
+ solr_params = {:highlighting => {}}
38
+
39
+ if set_class.respond_to?(:solr_field_list)
40
+ solr_params[:field_list] = set_class.solr_field_list
41
+ end
42
+
36
43
  if limit
37
- solr_params << "rows=#{limit}"
38
- solr_params << "start=#{offset}"
44
+ solr_params[:rows] = limit
45
+ solr_params[:start] = offset
39
46
  else
40
- solr_params << "rows=#{MAX_SOLR_RESULTS}"
47
+ solr_params[:rows] = MAX_SOLR_RESULTS
41
48
  end
42
-
43
- solr_params = solr_params.join('&')
49
+
44
50
  before_query(solr_params)
45
-
46
- # Catch any errors when calling solr so we can log the params.
47
- begin
48
- resp = eval ActsAsSolr::Post.execute(solr_params)
51
+ begin
52
+ solr_uri = "http://" + SOLR_HOST
53
+ if @config[:core]
54
+ solr_uri << "/" + @config[:core]
55
+ end
56
+ @response = Solr::Connection.new(solr_uri).search(query, solr_params)
49
57
  rescue Exception => e
50
58
  on_exception(e, solr_params)
51
59
  end
52
-
53
60
  after_query(solr_params)
54
-
55
- @count = resp['response']['numFound']
56
- @ids = resp['response']['docs'].collect {|doc| doc['pk_i'].to_i}.to_ordered_set
61
+
62
+ @count = @response.total_hits
63
+ @ids = @response.hits.map{ |hit| hit[@config[:response_id_field]].to_i }
57
64
  @size = @ids.size
58
65
  end
59
66
 
@@ -48,7 +48,7 @@ class ModelSet
48
48
  conditions.each do |field, value|
49
49
  next if value.nil?
50
50
  field = field.join(',') if field.kind_of?(Array)
51
- value = value.collect {|v| '"' + v + '"'}.join('|') if value.kind_of?(Array)
51
+ value = "(#{value.join('|')})" if value.kind_of?(Array)
52
52
  add_conditions!("@(#{field}) #{value}")
53
53
  end
54
54
  else
@@ -186,9 +186,9 @@ class ModelSet
186
186
  def filter_values(values)
187
187
  Array(values).collect do |value|
188
188
  case value
189
- when Date : value.to_time.to_i
190
- when TrueClass : 1
191
- when FalseClass : 0
189
+ when Date then value.to_time.to_i
190
+ when TrueClass then 1
191
+ when FalseClass then 0
192
192
  else
193
193
  value.to_i
194
194
  end
@@ -2,25 +2,44 @@ class ModelSet
2
2
  class SQLQuery < SQLBaseQuery
3
3
  include Conditioned
4
4
 
5
- def anchor!(query)
6
- if query.respond_to?(:sql)
7
- sql = "#{id_field_with_prefix} IN (#{query.sql})"
5
+ def anchor!(query, opts = {})
6
+ if @limit_fetch = opts[:limit_fetch]
7
+ @reorder = query.ids
8
8
  else
9
- sql = ids_clause(query.ids)
9
+ if query.respond_to?(:sql)
10
+ sql = "#{id_field_with_prefix} IN (#{query.sql})"
11
+ else
12
+ sql = ids_clause(query.ids)
13
+ @reorder = query.ids
14
+ end
15
+ add_conditions!(sql)
10
16
  end
11
- @reorder = query.ids
12
- add_conditions!(sql)
13
17
  end
14
-
18
+
15
19
  def ids
16
20
  if @ids.nil?
17
- @ids = fetch_id_set(sql)
18
- @ids.reorder!(@reorder) if @reorder
21
+ if @limit_fetch
22
+ base_conditions = conditions
23
+ @ids = [].to_ordered_set
24
+ @reorder.each_slice(@limit_fetch) do |ids|
25
+ self.conditions = Conditions.new(:and, ids_clause(ids), *base_conditions)
26
+ @ids.concat fetch_id_set(sql)
27
+ if limit and @ids.size >= limit
28
+ @ids.reorder!(@reorder).limit!(limit)
29
+ break
30
+ end
31
+ end
32
+ self.conditions = base_conditions
33
+ else
34
+ @ids = fetch_id_set(sql)
35
+ @ids.reorder!(@reorder) if @reorder
36
+ end
19
37
  end
20
38
  @ids
21
39
  end
22
40
 
23
41
  def limit_enabled?
42
+ return true if @limit_fetch
24
43
  return false if @reorder
25
44
  super
26
45
  end
@@ -56,7 +75,7 @@ class ModelSet
56
75
  @reorder = nil
57
76
  clear_cache!
58
77
  end
59
-
78
+
60
79
  def reverse!
61
80
  if @reorder
62
81
  @reorder.reverse!
@@ -81,23 +100,23 @@ class ModelSet
81
100
  def count
82
101
  @count ||= limit ? aggregate("COUNT(DISTINCT #{id_field_with_prefix})").to_i : size
83
102
  end
84
-
103
+
85
104
  private
86
-
105
+
87
106
  def select_clause
88
107
  "SELECT #{id_field_with_prefix}"
89
108
  end
90
-
109
+
91
110
  def from_clause
92
111
  "FROM #{table_name} #{join_clause} WHERE #{conditions.to_s}"
93
112
  end
94
-
113
+
95
114
  def order_clause
96
115
  return unless @sort_order
97
116
  # Prevent SQL injection attacks.
98
- "ORDER BY #{@sort_order.join(', ').gsub(/[^\w_, \.\(\)'\"]/, '')}"
117
+ "ORDER BY #{@sort_order.join(', ').gsub(/[^\w_, \.\(\)\[\]'\"]/, '')}"
99
118
  end
100
-
119
+
101
120
  def join_clause
102
121
  return unless @joins or @sort_join
103
122
  joins = []
data/lib/model_set.rb CHANGED
@@ -398,6 +398,11 @@ class ModelSet
398
398
  end
399
399
  end
400
400
 
401
+ clone_method :lazy_limit
402
+ def lazy_limit!(limit, fetch = limit * 10)
403
+ anchor!(:sql, :limit_fetch => fetch).limit!(limit)
404
+ end
405
+
401
406
  def extract_opt(key, args)
402
407
  opts = args.last.kind_of?(Hash) ? args.pop : {}
403
408
  opt = opts.delete(key)
@@ -610,11 +615,15 @@ private
610
615
  end
611
616
  models.each do |model|
612
617
  id = model.send(id_field)
613
- models_by_id[id] ||= model
618
+ models_by_id[id] ||= after_fetch(model)
614
619
  end
615
620
  end
616
621
  end
617
622
 
623
+ def after_fetch(model)
624
+ model
625
+ end
626
+
618
627
  def as_id(model)
619
628
  case model
620
629
  when model_class
@@ -741,3 +750,11 @@ class ActiveRecord::Base
741
750
  end
742
751
  end
743
752
  end
753
+
754
+ unless defined?(PGconn) and PGconn.respond_to?(:quote_ident)
755
+ class PGconn
756
+ def self.quote_ident(name)
757
+ %("#{name}")
758
+ end
759
+ end
760
+ end
data/model_set.gemspec CHANGED
@@ -1,146 +1,140 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{model_set}
8
- s.version = "0.11.1"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Justin Balthrop"]
12
- s.date = %q{2010-04-13}
12
+ s.date = %q{2011-06-02}
13
13
  s.description = %q{Easy manipulation of sets of ActiveRecord models}
14
14
  s.email = %q{code@justinbalthrop.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.rdoc"
17
+ "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  "LICENSE",
21
- "README.rdoc",
22
- "Rakefile",
23
- "VERSION.yml",
24
- "lib/model_set.rb",
25
- "lib/model_set/conditioned.rb",
26
- "lib/model_set/conditions.rb",
27
- "lib/model_set/query.rb",
28
- "lib/model_set/raw_query.rb",
29
- "lib/model_set/raw_sql_query.rb",
30
- "lib/model_set/set_query.rb",
31
- "lib/model_set/solr_query.rb",
32
- "lib/model_set/sphinx_query.rb",
33
- "lib/model_set/sql_base_query.rb",
34
- "lib/model_set/sql_query.rb",
35
- "lib/multi_set.rb",
36
- "model_set.gemspec",
37
- "test/model_set_test.rb",
38
- "test/multi_set_test.rb",
39
- "test/test_helper.rb",
40
- "vendor/sphinx_client/README.rdoc",
41
- "vendor/sphinx_client/Rakefile",
42
- "vendor/sphinx_client/init.rb",
43
- "vendor/sphinx_client/install.rb",
44
- "vendor/sphinx_client/lib/sphinx.rb",
45
- "vendor/sphinx_client/lib/sphinx/client.rb",
46
- "vendor/sphinx_client/lib/sphinx/request.rb",
47
- "vendor/sphinx_client/lib/sphinx/response.rb",
48
- "vendor/sphinx_client/spec/client_response_spec.rb",
49
- "vendor/sphinx_client/spec/client_spec.rb",
50
- "vendor/sphinx_client/spec/fixtures/default_search.php",
51
- "vendor/sphinx_client/spec/fixtures/default_search_index.php",
52
- "vendor/sphinx_client/spec/fixtures/excerpt_custom.php",
53
- "vendor/sphinx_client/spec/fixtures/excerpt_default.php",
54
- "vendor/sphinx_client/spec/fixtures/excerpt_flags.php",
55
- "vendor/sphinx_client/spec/fixtures/field_weights.php",
56
- "vendor/sphinx_client/spec/fixtures/filter.php",
57
- "vendor/sphinx_client/spec/fixtures/filter_exclude.php",
58
- "vendor/sphinx_client/spec/fixtures/filter_float_range.php",
59
- "vendor/sphinx_client/spec/fixtures/filter_float_range_exclude.php",
60
- "vendor/sphinx_client/spec/fixtures/filter_range.php",
61
- "vendor/sphinx_client/spec/fixtures/filter_range_exclude.php",
62
- "vendor/sphinx_client/spec/fixtures/filter_range_int64.php",
63
- "vendor/sphinx_client/spec/fixtures/filter_ranges.php",
64
- "vendor/sphinx_client/spec/fixtures/filters.php",
65
- "vendor/sphinx_client/spec/fixtures/filters_different.php",
66
- "vendor/sphinx_client/spec/fixtures/geo_anchor.php",
67
- "vendor/sphinx_client/spec/fixtures/group_by_attr.php",
68
- "vendor/sphinx_client/spec/fixtures/group_by_attrpair.php",
69
- "vendor/sphinx_client/spec/fixtures/group_by_day.php",
70
- "vendor/sphinx_client/spec/fixtures/group_by_day_sort.php",
71
- "vendor/sphinx_client/spec/fixtures/group_by_month.php",
72
- "vendor/sphinx_client/spec/fixtures/group_by_week.php",
73
- "vendor/sphinx_client/spec/fixtures/group_by_year.php",
74
- "vendor/sphinx_client/spec/fixtures/group_distinct.php",
75
- "vendor/sphinx_client/spec/fixtures/id_range.php",
76
- "vendor/sphinx_client/spec/fixtures/id_range64.php",
77
- "vendor/sphinx_client/spec/fixtures/index_weights.php",
78
- "vendor/sphinx_client/spec/fixtures/keywords.php",
79
- "vendor/sphinx_client/spec/fixtures/limits.php",
80
- "vendor/sphinx_client/spec/fixtures/limits_cutoff.php",
81
- "vendor/sphinx_client/spec/fixtures/limits_max.php",
82
- "vendor/sphinx_client/spec/fixtures/limits_max_cutoff.php",
83
- "vendor/sphinx_client/spec/fixtures/match_all.php",
84
- "vendor/sphinx_client/spec/fixtures/match_any.php",
85
- "vendor/sphinx_client/spec/fixtures/match_boolean.php",
86
- "vendor/sphinx_client/spec/fixtures/match_extended.php",
87
- "vendor/sphinx_client/spec/fixtures/match_extended2.php",
88
- "vendor/sphinx_client/spec/fixtures/match_fullscan.php",
89
- "vendor/sphinx_client/spec/fixtures/match_phrase.php",
90
- "vendor/sphinx_client/spec/fixtures/max_query_time.php",
91
- "vendor/sphinx_client/spec/fixtures/miltiple_queries.php",
92
- "vendor/sphinx_client/spec/fixtures/ranking_bm25.php",
93
- "vendor/sphinx_client/spec/fixtures/ranking_none.php",
94
- "vendor/sphinx_client/spec/fixtures/ranking_proximity.php",
95
- "vendor/sphinx_client/spec/fixtures/ranking_proximity_bm25.php",
96
- "vendor/sphinx_client/spec/fixtures/ranking_wordcount.php",
97
- "vendor/sphinx_client/spec/fixtures/retries.php",
98
- "vendor/sphinx_client/spec/fixtures/retries_delay.php",
99
- "vendor/sphinx_client/spec/fixtures/select.php",
100
- "vendor/sphinx_client/spec/fixtures/set_override.php",
101
- "vendor/sphinx_client/spec/fixtures/sort_attr_asc.php",
102
- "vendor/sphinx_client/spec/fixtures/sort_attr_desc.php",
103
- "vendor/sphinx_client/spec/fixtures/sort_expr.php",
104
- "vendor/sphinx_client/spec/fixtures/sort_extended.php",
105
- "vendor/sphinx_client/spec/fixtures/sort_relevance.php",
106
- "vendor/sphinx_client/spec/fixtures/sort_time_segments.php",
107
- "vendor/sphinx_client/spec/fixtures/sphinxapi.php",
108
- "vendor/sphinx_client/spec/fixtures/update_attributes.php",
109
- "vendor/sphinx_client/spec/fixtures/update_attributes_mva.php",
110
- "vendor/sphinx_client/spec/fixtures/weights.php",
111
- "vendor/sphinx_client/spec/sphinx/sphinx-id64.conf",
112
- "vendor/sphinx_client/spec/sphinx/sphinx.conf",
113
- "vendor/sphinx_client/spec/sphinx/sphinx_test.sql",
114
- "vendor/sphinx_client/sphinx.yml.tpl",
115
- "vendor/sphinx_client/tasks/sphinx.rake"
21
+ "README.rdoc",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/model_set.rb",
25
+ "lib/model_set/conditioned.rb",
26
+ "lib/model_set/conditions.rb",
27
+ "lib/model_set/query.rb",
28
+ "lib/model_set/raw_query.rb",
29
+ "lib/model_set/raw_sql_query.rb",
30
+ "lib/model_set/set_query.rb",
31
+ "lib/model_set/solr_query.rb",
32
+ "lib/model_set/sphinx_query.rb",
33
+ "lib/model_set/sql_base_query.rb",
34
+ "lib/model_set/sql_query.rb",
35
+ "lib/multi_set.rb",
36
+ "model_set.gemspec",
37
+ "test/model_set_test.rb",
38
+ "test/multi_set_test.rb",
39
+ "test/test_helper.rb",
40
+ "vendor/sphinx_client/README.rdoc",
41
+ "vendor/sphinx_client/Rakefile",
42
+ "vendor/sphinx_client/init.rb",
43
+ "vendor/sphinx_client/install.rb",
44
+ "vendor/sphinx_client/lib/sphinx.rb",
45
+ "vendor/sphinx_client/lib/sphinx/client.rb",
46
+ "vendor/sphinx_client/lib/sphinx/request.rb",
47
+ "vendor/sphinx_client/lib/sphinx/response.rb",
48
+ "vendor/sphinx_client/spec/client_response_spec.rb",
49
+ "vendor/sphinx_client/spec/client_spec.rb",
50
+ "vendor/sphinx_client/spec/fixtures/default_search.php",
51
+ "vendor/sphinx_client/spec/fixtures/default_search_index.php",
52
+ "vendor/sphinx_client/spec/fixtures/excerpt_custom.php",
53
+ "vendor/sphinx_client/spec/fixtures/excerpt_default.php",
54
+ "vendor/sphinx_client/spec/fixtures/excerpt_flags.php",
55
+ "vendor/sphinx_client/spec/fixtures/field_weights.php",
56
+ "vendor/sphinx_client/spec/fixtures/filter.php",
57
+ "vendor/sphinx_client/spec/fixtures/filter_exclude.php",
58
+ "vendor/sphinx_client/spec/fixtures/filter_float_range.php",
59
+ "vendor/sphinx_client/spec/fixtures/filter_float_range_exclude.php",
60
+ "vendor/sphinx_client/spec/fixtures/filter_range.php",
61
+ "vendor/sphinx_client/spec/fixtures/filter_range_exclude.php",
62
+ "vendor/sphinx_client/spec/fixtures/filter_range_int64.php",
63
+ "vendor/sphinx_client/spec/fixtures/filter_ranges.php",
64
+ "vendor/sphinx_client/spec/fixtures/filters.php",
65
+ "vendor/sphinx_client/spec/fixtures/filters_different.php",
66
+ "vendor/sphinx_client/spec/fixtures/geo_anchor.php",
67
+ "vendor/sphinx_client/spec/fixtures/group_by_attr.php",
68
+ "vendor/sphinx_client/spec/fixtures/group_by_attrpair.php",
69
+ "vendor/sphinx_client/spec/fixtures/group_by_day.php",
70
+ "vendor/sphinx_client/spec/fixtures/group_by_day_sort.php",
71
+ "vendor/sphinx_client/spec/fixtures/group_by_month.php",
72
+ "vendor/sphinx_client/spec/fixtures/group_by_week.php",
73
+ "vendor/sphinx_client/spec/fixtures/group_by_year.php",
74
+ "vendor/sphinx_client/spec/fixtures/group_distinct.php",
75
+ "vendor/sphinx_client/spec/fixtures/id_range.php",
76
+ "vendor/sphinx_client/spec/fixtures/id_range64.php",
77
+ "vendor/sphinx_client/spec/fixtures/index_weights.php",
78
+ "vendor/sphinx_client/spec/fixtures/keywords.php",
79
+ "vendor/sphinx_client/spec/fixtures/limits.php",
80
+ "vendor/sphinx_client/spec/fixtures/limits_cutoff.php",
81
+ "vendor/sphinx_client/spec/fixtures/limits_max.php",
82
+ "vendor/sphinx_client/spec/fixtures/limits_max_cutoff.php",
83
+ "vendor/sphinx_client/spec/fixtures/match_all.php",
84
+ "vendor/sphinx_client/spec/fixtures/match_any.php",
85
+ "vendor/sphinx_client/spec/fixtures/match_boolean.php",
86
+ "vendor/sphinx_client/spec/fixtures/match_extended.php",
87
+ "vendor/sphinx_client/spec/fixtures/match_extended2.php",
88
+ "vendor/sphinx_client/spec/fixtures/match_fullscan.php",
89
+ "vendor/sphinx_client/spec/fixtures/match_phrase.php",
90
+ "vendor/sphinx_client/spec/fixtures/max_query_time.php",
91
+ "vendor/sphinx_client/spec/fixtures/miltiple_queries.php",
92
+ "vendor/sphinx_client/spec/fixtures/ranking_bm25.php",
93
+ "vendor/sphinx_client/spec/fixtures/ranking_none.php",
94
+ "vendor/sphinx_client/spec/fixtures/ranking_proximity.php",
95
+ "vendor/sphinx_client/spec/fixtures/ranking_proximity_bm25.php",
96
+ "vendor/sphinx_client/spec/fixtures/ranking_wordcount.php",
97
+ "vendor/sphinx_client/spec/fixtures/retries.php",
98
+ "vendor/sphinx_client/spec/fixtures/retries_delay.php",
99
+ "vendor/sphinx_client/spec/fixtures/select.php",
100
+ "vendor/sphinx_client/spec/fixtures/set_override.php",
101
+ "vendor/sphinx_client/spec/fixtures/sort_attr_asc.php",
102
+ "vendor/sphinx_client/spec/fixtures/sort_attr_desc.php",
103
+ "vendor/sphinx_client/spec/fixtures/sort_expr.php",
104
+ "vendor/sphinx_client/spec/fixtures/sort_extended.php",
105
+ "vendor/sphinx_client/spec/fixtures/sort_relevance.php",
106
+ "vendor/sphinx_client/spec/fixtures/sort_time_segments.php",
107
+ "vendor/sphinx_client/spec/fixtures/sphinxapi.php",
108
+ "vendor/sphinx_client/spec/fixtures/update_attributes.php",
109
+ "vendor/sphinx_client/spec/fixtures/update_attributes_mva.php",
110
+ "vendor/sphinx_client/spec/fixtures/weights.php",
111
+ "vendor/sphinx_client/spec/sphinx/sphinx-id64.conf",
112
+ "vendor/sphinx_client/spec/sphinx/sphinx.conf",
113
+ "vendor/sphinx_client/spec/sphinx/sphinx_test.sql",
114
+ "vendor/sphinx_client/sphinx.yml.tpl",
115
+ "vendor/sphinx_client/tasks/sphinx.rake"
116
116
  ]
117
117
  s.homepage = %q{http://github.com/ninjudd/model_set}
118
- s.rdoc_options = ["--charset=UTF-8"]
119
118
  s.require_paths = ["lib"]
120
- s.rubygems_version = %q{1.3.5}
119
+ s.rubygems_version = %q{1.3.7}
121
120
  s.summary = %q{Easy manipulation of sets of ActiveRecord models}
122
- s.test_files = [
123
- "test/model_set_test.rb",
124
- "test/multi_set_test.rb",
125
- "test/test_helper.rb"
126
- ]
127
121
 
128
122
  if s.respond_to? :specification_version then
129
123
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
130
124
  s.specification_version = 3
131
125
 
132
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
133
- s.add_runtime_dependency(%q<ordered_set>, [">= 1.0.0"])
134
- s.add_runtime_dependency(%q<deep_clonable>, [">= 1.0.2"])
126
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
127
+ s.add_runtime_dependency(%q<ordered_set>, [">= 1.0.1"])
128
+ s.add_runtime_dependency(%q<deep_clonable>, [">= 1.1.0"])
135
129
  s.add_runtime_dependency(%q<activerecord>, [">= 2.0.0"])
136
130
  else
137
- s.add_dependency(%q<ordered_set>, [">= 1.0.0"])
138
- s.add_dependency(%q<deep_clonable>, [">= 1.0.2"])
131
+ s.add_dependency(%q<ordered_set>, [">= 1.0.1"])
132
+ s.add_dependency(%q<deep_clonable>, [">= 1.1.0"])
139
133
  s.add_dependency(%q<activerecord>, [">= 2.0.0"])
140
134
  end
141
135
  else
142
- s.add_dependency(%q<ordered_set>, [">= 1.0.0"])
143
- s.add_dependency(%q<deep_clonable>, [">= 1.0.2"])
136
+ s.add_dependency(%q<ordered_set>, [">= 1.0.1"])
137
+ s.add_dependency(%q<deep_clonable>, [">= 1.1.0"])
144
138
  s.add_dependency(%q<activerecord>, [">= 2.0.0"])
145
139
  end
146
140
  end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  class ModelSetTest < Test::Unit::TestCase
4
- class CreateTables < ActiveRecord::Migration
4
+ class CreateTables < ActiveRecord::Migration
5
5
  def self.up
6
6
  create_table :heroes do |t|
7
7
  t.column :name, :string
@@ -49,7 +49,7 @@ class ModelSetTest < Test::Unit::TestCase
49
49
  drop_table :robots
50
50
  end
51
51
  end
52
-
52
+
53
53
  class Superpower < ActiveRecord::Base
54
54
  end
55
55
 
@@ -71,13 +71,13 @@ class ModelSetTest < Test::Unit::TestCase
71
71
  end
72
72
  end
73
73
  end
74
-
74
+
75
75
  class HeroSet < ModelSet
76
76
  constructor :with_universe
77
77
  clone_method :with_universe
78
78
  def with_universe!(universe)
79
79
  add_conditions!("universe = '#{universe}'")
80
- end
80
+ end
81
81
 
82
82
  clone_method :add_birthday
83
83
  def add_birthday!
@@ -90,18 +90,18 @@ class ModelSetTest < Test::Unit::TestCase
90
90
  CreateTables.verbose = false
91
91
  CreateTables.up
92
92
  end
93
-
93
+
94
94
  teardown do
95
95
  CreateTables.down
96
96
  end
97
-
97
+
98
98
  should "construct a model set" do
99
99
  captain = Hero.create(:name => 'Captain America', :universe => 'Marvel')
100
100
  spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
101
101
  batman = Hero.create(:name => 'Batman', :universe => 'D.C.' )
102
102
  superman = Hero.create(:name => 'Superman', :universe => 'D.C.' )
103
103
  ironman = Hero.create(:name => 'Iron Man', :universe => 'Marvel')
104
-
104
+
105
105
  set = HeroSet.with_universe('Marvel')
106
106
  assert_equal [captain.id, spidey.id, ironman.id], set.ids
107
107
  end
@@ -123,10 +123,10 @@ class ModelSetTest < Test::Unit::TestCase
123
123
  should "order and reverse set" do
124
124
  captain = Hero.create(:name => 'Captain America', :universe => 'Marvel')
125
125
  spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
126
- wolverine = Hero.create(:name => 'Wolverine', :universe => 'Marvel' )
127
- phoenix = Hero.create(:name => 'Phoenix', :universe => 'Marvel' )
126
+ wolverine = Hero.create(:name => 'Wolverine', :universe => 'Marvel')
127
+ phoenix = Hero.create(:name => 'Phoenix', :universe => 'Marvel')
128
128
  ironman = Hero.create(:name => 'Iron Man', :universe => 'Marvel')
129
-
129
+
130
130
  ids = [captain.id, ironman.id, phoenix.id, spidey.id, wolverine.id]
131
131
  set = HeroSet.with_universe('Marvel')
132
132
 
@@ -154,59 +154,59 @@ class ModelSetTest < Test::Unit::TestCase
154
154
  missing_id = 5555
155
155
  spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
156
156
  set = HeroSet.new([spidey.id, missing_id])
157
-
157
+
158
158
  # Iterate through the profiles so the missing ones will be detected.
159
159
  set.each {}
160
160
  assert_equal [missing_id], set.missing_ids
161
161
  end
162
-
162
+
163
163
  should "have missing ids with add_fields" do
164
164
  missing_id = 5555
165
165
  spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
166
166
  set = HeroSet.new([spidey.id, missing_id]).add_birthday
167
-
167
+
168
168
  # Iterate through the profiles so the missing ones will be detected.
169
169
  set.each {}
170
170
  assert_equal [missing_id], set.missing_ids
171
171
  end
172
-
172
+
173
173
  should "support has_set" do
174
174
  hero = Hero.create(:name => 'Mr. Invisible')
175
175
  mighty_mouse = Superpet.create(:name => 'Mighty Mouse', :owner_id => hero.id)
176
176
  underdog = Superpet.create(:name => 'Underdog', :owner_id => hero.id)
177
-
177
+
178
178
  set = hero.pets
179
179
  assert_equal SuperpetSet, set.class
180
180
  assert_equal [mighty_mouse.id, underdog.id], set.ids
181
181
  end
182
-
182
+
183
183
  should "support has_set with through" do
184
184
  hero = Hero.create(:name => 'Mr. Invisible')
185
185
  invisibility = Superpower.create(:name => 'Invisibility')
186
186
  flying = Superpower.create(:name => 'Flying')
187
187
  HeroSuperpower.create(:hero_id => hero.id, :power_id => invisibility.id)
188
188
  HeroSuperpower.create(:hero_id => hero.id, :power_id => flying.id)
189
-
189
+
190
190
  set = hero.superpowers
191
191
  assert_equal SuperpowerSet, set.class
192
192
  assert_equal [invisibility.id, flying.id], set.ids
193
193
  end
194
-
194
+
195
195
  should "allow set extensions" do
196
196
  hero = Hero.create(:name => 'Mr. Invisible')
197
197
  mighty_mouse = Superpet.create(:name => 'Mighty Mouse', :owner_id => hero.id, :species => 'mouse')
198
198
  sammy = Superpet.create(:name => 'Sammy Davis Jr. Jr.', :owner_id => hero.id, :species => 'dog')
199
199
  underdog = Superpet.create(:name => 'Underdog', :owner_id => hero.id, :species => 'dog')
200
-
200
+
201
201
  set = hero.pets
202
202
  assert_equal ['mouse', 'dog', 'dog'], set.collect {|pet| pet.species}
203
-
203
+
204
204
  assert_equal [sammy.id, underdog.id], set.dogs!.ids
205
205
  end
206
206
 
207
207
  class Robot < ActiveRecord::Base
208
208
  end
209
-
209
+
210
210
  class RobotSet < ModelSet
211
211
  end
212
212
 
@@ -218,18 +218,18 @@ class ModelSetTest < Test::Unit::TestCase
218
218
  @small_wonder = Robot.create(:name => 'Vicki', :classification => :child )
219
219
  @t1000 = Robot.create(:name => 'Terminator', :classification => :assasin )
220
220
  @johnny5 = Robot.create(:name => 'Johnny 5', :classification => :miltary )
221
-
221
+
222
222
  @bot_set = RobotSet.new([@bender,@r2d2,@c3po,@rosie,@small_wonder,@t1000,@johnny5])
223
-
223
+
224
224
  @data = Robot.create(:name => 'Data', :classification => :positronic)
225
225
  @number8 = Robot.create(:name => 'Boomer', :classification => :cylon )
226
226
  end
227
-
227
+
228
228
  should "be empty" do
229
229
  set = RobotSet.empty
230
230
  assert_equal 0, set.size
231
231
  assert set.empty?
232
-
232
+
233
233
  set = RobotSet.new(@bender)
234
234
  assert !set.empty?
235
235
  end
@@ -248,13 +248,13 @@ class ModelSetTest < Test::Unit::TestCase
248
248
 
249
249
  should "delete models from a set" do
250
250
  set = RobotSet.new([@rosie, @small_wonder, @c3po])
251
-
251
+
252
252
  set.delete(@c3po)
253
253
  assert_equal [@rosie.id, @small_wonder.id], set.ids
254
-
254
+
255
255
  set.delete(@rosie.id)
256
256
  assert_equal [@small_wonder.id], set.ids
257
-
257
+
258
258
  set.delete(@small_wonder)
259
259
  assert_equal [], set.ids
260
260
  assert set.empty?
@@ -263,26 +263,26 @@ class ModelSetTest < Test::Unit::TestCase
263
263
  should "select models from a set" do
264
264
  assert_equal [@r2d2, @c3po], @bot_set.select {|bot| bot.classification == :droid}.to_a
265
265
  assert_equal 7, @bot_set.size
266
-
266
+
267
267
  @bot_set.select! {|bot| bot.classification == :miltary}
268
- assert_equal [@johnny5], @bot_set.to_a
268
+ assert_equal [@johnny5], @bot_set.to_a
269
269
  end
270
-
270
+
271
271
  should "sort a set" do
272
272
  assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder], @bot_set.sort {|a,b| a.name <=> b.name}.to_a
273
273
  assert_equal @johnny5, @bot_set.last
274
-
274
+
275
275
  @bot_set.sort! {|a,b| b.name <=> a.name}
276
- assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder].reverse, @bot_set.to_a
276
+ assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder].reverse, @bot_set.to_a
277
277
 
278
278
  @bot_set.reverse!
279
- assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder], @bot_set.to_a
279
+ assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder], @bot_set.to_a
280
280
  end
281
-
281
+
282
282
  should "sort a set by name" do
283
283
  assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder], @bot_set.sort_by {|bot| bot.name}.to_a
284
284
  end
285
-
285
+
286
286
  should "reject models from a set" do
287
287
  @bot_set.reject! {|bot| bot.classification == :domestic}
288
288
  assert !@bot_set.include?(@rosie)
@@ -294,19 +294,19 @@ class ModelSetTest < Test::Unit::TestCase
294
294
  humanoids = RobotSet.new([@small_wonder, @t1000, @data, @number8])
295
295
  metalics = RobotSet.new([@r2d2, @c3po, @johnny5])
296
296
  cartoons = RobotSet.new([@bender, @rosie])
297
-
297
+
298
298
  assert_equal ['C3PO', 'R2D2', 'Johnny 5'], (droids + metalics).collect {|bot| bot.name}
299
299
  assert_equal ['Bender', 'Rosie', 'C3PO', 'R2D2', 'Johnny 5'], (cartoons + droids + metalics).collect {|bot| bot.name}
300
300
  assert_equal 5, (cartoons + droids + metalics).size
301
301
  assert_equal 5, (cartoons + droids + metalics).count
302
-
302
+
303
303
  assert_equal [], (droids - metalics).collect {|bot| bot.name}
304
304
  assert_equal ['Johnny 5'], (metalics - droids).collect {|bot| bot.name}
305
305
  assert_equal ['Terminator', 'Data'], (humanoids - womanoids).collect {|bot| bot.name}
306
306
  assert_equal ['Bender'], (cartoons - womanoids).collect {|bot| bot.name}
307
307
  assert_equal 2, (humanoids - womanoids).size
308
308
  assert_equal 2, (humanoids - womanoids).count
309
-
309
+
310
310
  assert_equal ['C3PO', 'R2D2'], (droids & metalics).collect {|bot| bot.name}
311
311
  assert_equal ['R2D2', 'C3PO'], (metalics & droids).collect {|bot| bot.name}
312
312
  assert_equal ['Vicki', 'Boomer'], (humanoids & womanoids).collect {|bot| bot.name}
@@ -319,11 +319,33 @@ class ModelSetTest < Test::Unit::TestCase
319
319
  set -= @r2d2
320
320
  assert_equal ['C3PO', 'Johnny 5'], set.collect {|bot| bot.name}
321
321
  end
322
-
322
+
323
323
  should "clone a set" do
324
324
  set = RobotSet.new([1])
325
325
  new_set = set.clone
326
326
  assert new_set.object_id != set.object_id
327
327
  end
328
+
329
+ should "limit lazily" do
330
+ captain = Hero.create(:name => 'Captain America', :universe => 'Marvel')
331
+ spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
332
+ wolverine = Hero.create(:name => 'Wolverine', :universe => 'Marvel')
333
+ phoenix = Hero.create(:name => 'Phoenix', :universe => 'Marvel')
334
+ ironman = Hero.create(:name => 'Iron Man', :universe => 'Marvel')
335
+ zombie = Hero.create(:name => 'Zombie 1', :universe => 'Zombie')
336
+ batman = Hero.create(:name => 'Batman', :universe => 'D.C.' )
337
+ superman = Hero.create(:name => 'Superman', :universe => 'D.C.' )
338
+ ryu = Hero.create(:name => 'Ryu', :universe => 'Capcom')
339
+ ken = Hero.create(:name => 'Ryu', :universe => 'Capcom')
340
+ zangief = Hero.create(:name => 'Zangief', :universe => 'Capcom')
341
+ blanka = Hero.create(:name => 'Blanka', :universe => 'Capcom')
342
+
343
+ ids = [superman.id, phoenix.id, zangief.id, captain.id, ryu.id, zombie.id, batman.id, blanka.id, spidey.id, ken.id]
344
+
345
+ s = HeroSet.new(ids)
346
+ s.lazy_limit!(3, 3).add_conditions!(:universe => 'Capcom')
347
+
348
+ assert_equal [zangief.id, ryu.id, blanka.id], s.ids
349
+ end
328
350
  end
329
351
  end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
2
2
  require 'test/unit'
3
3
  require 'shoulda'
4
4
  require 'mocha'
5
+ require 'pp'
5
6
 
6
7
  $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
7
8
  ['deep_clonable', 'ordered_set'].each do |dir|
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: model_set
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.1
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Justin Balthrop
@@ -9,39 +15,57 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-04-13 00:00:00 -07:00
18
+ date: 2011-06-02 00:00:00 -07:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: ordered_set
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
23
- version: 1.0.0
24
- version:
29
+ hash: 21
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 1
34
+ version: 1.0.1
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: deep_clonable
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
33
- version: 1.0.2
34
- version:
45
+ hash: 19
46
+ segments:
47
+ - 1
48
+ - 1
49
+ - 0
50
+ version: 1.1.0
51
+ type: :runtime
52
+ version_requirements: *id002
35
53
  - !ruby/object:Gem::Dependency
36
54
  name: activerecord
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
40
58
  requirements:
41
59
  - - ">="
42
60
  - !ruby/object:Gem::Version
61
+ hash: 15
62
+ segments:
63
+ - 2
64
+ - 0
65
+ - 0
43
66
  version: 2.0.0
44
- version:
67
+ type: :runtime
68
+ version_requirements: *id003
45
69
  description: Easy manipulation of sets of ActiveRecord models
46
70
  email: code@justinbalthrop.com
47
71
  executables: []
@@ -55,7 +79,7 @@ files:
55
79
  - LICENSE
56
80
  - README.rdoc
57
81
  - Rakefile
58
- - VERSION.yml
82
+ - VERSION
59
83
  - lib/model_set.rb
60
84
  - lib/model_set/conditioned.rb
61
85
  - lib/model_set/conditions.rb
@@ -153,30 +177,34 @@ homepage: http://github.com/ninjudd/model_set
153
177
  licenses: []
154
178
 
155
179
  post_install_message:
156
- rdoc_options:
157
- - --charset=UTF-8
180
+ rdoc_options: []
181
+
158
182
  require_paths:
159
183
  - lib
160
184
  required_ruby_version: !ruby/object:Gem::Requirement
185
+ none: false
161
186
  requirements:
162
187
  - - ">="
163
188
  - !ruby/object:Gem::Version
189
+ hash: 3
190
+ segments:
191
+ - 0
164
192
  version: "0"
165
- version:
166
193
  required_rubygems_version: !ruby/object:Gem::Requirement
194
+ none: false
167
195
  requirements:
168
196
  - - ">="
169
197
  - !ruby/object:Gem::Version
198
+ hash: 3
199
+ segments:
200
+ - 0
170
201
  version: "0"
171
- version:
172
202
  requirements: []
173
203
 
174
204
  rubyforge_project:
175
- rubygems_version: 1.3.5
205
+ rubygems_version: 1.3.7
176
206
  signing_key:
177
207
  specification_version: 3
178
208
  summary: Easy manipulation of sets of ActiveRecord models
179
- test_files:
180
- - test/model_set_test.rb
181
- - test/multi_set_test.rb
182
- - test/test_helper.rb
209
+ test_files: []
210
+
data/VERSION.yml DELETED
@@ -1,5 +0,0 @@
1
- ---
2
- :build:
3
- :patch: 1
4
- :major: 0
5
- :minor: 11