model_set 0.10.6

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.
Files changed (95) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +39 -0
  3. data/VERSION.yml +5 -0
  4. data/lib/model_set/conditioned.rb +33 -0
  5. data/lib/model_set/conditions.rb +103 -0
  6. data/lib/model_set/query.rb +132 -0
  7. data/lib/model_set/raw_query.rb +41 -0
  8. data/lib/model_set/raw_sql_query.rb +19 -0
  9. data/lib/model_set/set_query.rb +34 -0
  10. data/lib/model_set/solr_query.rb +70 -0
  11. data/lib/model_set/sphinx_query.rb +206 -0
  12. data/lib/model_set/sql_base_query.rb +52 -0
  13. data/lib/model_set/sql_query.rb +109 -0
  14. data/lib/model_set.rb +743 -0
  15. data/lib/multi_set.rb +67 -0
  16. data/test/model_set_test.rb +329 -0
  17. data/test/multi_set_test.rb +65 -0
  18. data/test/test_helper.rb +23 -0
  19. data/vendor/sphinx_client/README.rdoc +41 -0
  20. data/vendor/sphinx_client/Rakefile +21 -0
  21. data/vendor/sphinx_client/init.rb +1 -0
  22. data/vendor/sphinx_client/install.rb +5 -0
  23. data/vendor/sphinx_client/lib/sphinx/client.rb +1093 -0
  24. data/vendor/sphinx_client/lib/sphinx/request.rb +50 -0
  25. data/vendor/sphinx_client/lib/sphinx/response.rb +69 -0
  26. data/vendor/sphinx_client/lib/sphinx.rb +6 -0
  27. data/vendor/sphinx_client/spec/client_response_spec.rb +112 -0
  28. data/vendor/sphinx_client/spec/client_spec.rb +469 -0
  29. data/vendor/sphinx_client/spec/fixtures/default_search.php +8 -0
  30. data/vendor/sphinx_client/spec/fixtures/default_search_index.php +8 -0
  31. data/vendor/sphinx_client/spec/fixtures/excerpt_custom.php +11 -0
  32. data/vendor/sphinx_client/spec/fixtures/excerpt_default.php +8 -0
  33. data/vendor/sphinx_client/spec/fixtures/excerpt_flags.php +11 -0
  34. data/vendor/sphinx_client/spec/fixtures/field_weights.php +9 -0
  35. data/vendor/sphinx_client/spec/fixtures/filter.php +9 -0
  36. data/vendor/sphinx_client/spec/fixtures/filter_exclude.php +9 -0
  37. data/vendor/sphinx_client/spec/fixtures/filter_float_range.php +9 -0
  38. data/vendor/sphinx_client/spec/fixtures/filter_float_range_exclude.php +9 -0
  39. data/vendor/sphinx_client/spec/fixtures/filter_range.php +9 -0
  40. data/vendor/sphinx_client/spec/fixtures/filter_range_exclude.php +9 -0
  41. data/vendor/sphinx_client/spec/fixtures/filter_range_int64.php +10 -0
  42. data/vendor/sphinx_client/spec/fixtures/filter_ranges.php +10 -0
  43. data/vendor/sphinx_client/spec/fixtures/filters.php +10 -0
  44. data/vendor/sphinx_client/spec/fixtures/filters_different.php +13 -0
  45. data/vendor/sphinx_client/spec/fixtures/geo_anchor.php +9 -0
  46. data/vendor/sphinx_client/spec/fixtures/group_by_attr.php +9 -0
  47. data/vendor/sphinx_client/spec/fixtures/group_by_attrpair.php +9 -0
  48. data/vendor/sphinx_client/spec/fixtures/group_by_day.php +9 -0
  49. data/vendor/sphinx_client/spec/fixtures/group_by_day_sort.php +9 -0
  50. data/vendor/sphinx_client/spec/fixtures/group_by_month.php +9 -0
  51. data/vendor/sphinx_client/spec/fixtures/group_by_week.php +9 -0
  52. data/vendor/sphinx_client/spec/fixtures/group_by_year.php +9 -0
  53. data/vendor/sphinx_client/spec/fixtures/group_distinct.php +10 -0
  54. data/vendor/sphinx_client/spec/fixtures/id_range.php +9 -0
  55. data/vendor/sphinx_client/spec/fixtures/id_range64.php +9 -0
  56. data/vendor/sphinx_client/spec/fixtures/index_weights.php +9 -0
  57. data/vendor/sphinx_client/spec/fixtures/keywords.php +8 -0
  58. data/vendor/sphinx_client/spec/fixtures/limits.php +9 -0
  59. data/vendor/sphinx_client/spec/fixtures/limits_cutoff.php +9 -0
  60. data/vendor/sphinx_client/spec/fixtures/limits_max.php +9 -0
  61. data/vendor/sphinx_client/spec/fixtures/limits_max_cutoff.php +9 -0
  62. data/vendor/sphinx_client/spec/fixtures/match_all.php +9 -0
  63. data/vendor/sphinx_client/spec/fixtures/match_any.php +9 -0
  64. data/vendor/sphinx_client/spec/fixtures/match_boolean.php +9 -0
  65. data/vendor/sphinx_client/spec/fixtures/match_extended.php +9 -0
  66. data/vendor/sphinx_client/spec/fixtures/match_extended2.php +9 -0
  67. data/vendor/sphinx_client/spec/fixtures/match_fullscan.php +9 -0
  68. data/vendor/sphinx_client/spec/fixtures/match_phrase.php +9 -0
  69. data/vendor/sphinx_client/spec/fixtures/max_query_time.php +9 -0
  70. data/vendor/sphinx_client/spec/fixtures/miltiple_queries.php +12 -0
  71. data/vendor/sphinx_client/spec/fixtures/ranking_bm25.php +9 -0
  72. data/vendor/sphinx_client/spec/fixtures/ranking_none.php +9 -0
  73. data/vendor/sphinx_client/spec/fixtures/ranking_proximity.php +9 -0
  74. data/vendor/sphinx_client/spec/fixtures/ranking_proximity_bm25.php +9 -0
  75. data/vendor/sphinx_client/spec/fixtures/ranking_wordcount.php +9 -0
  76. data/vendor/sphinx_client/spec/fixtures/retries.php +9 -0
  77. data/vendor/sphinx_client/spec/fixtures/retries_delay.php +9 -0
  78. data/vendor/sphinx_client/spec/fixtures/select.php +9 -0
  79. data/vendor/sphinx_client/spec/fixtures/set_override.php +11 -0
  80. data/vendor/sphinx_client/spec/fixtures/sort_attr_asc.php +9 -0
  81. data/vendor/sphinx_client/spec/fixtures/sort_attr_desc.php +9 -0
  82. data/vendor/sphinx_client/spec/fixtures/sort_expr.php +9 -0
  83. data/vendor/sphinx_client/spec/fixtures/sort_extended.php +9 -0
  84. data/vendor/sphinx_client/spec/fixtures/sort_relevance.php +9 -0
  85. data/vendor/sphinx_client/spec/fixtures/sort_time_segments.php +9 -0
  86. data/vendor/sphinx_client/spec/fixtures/sphinxapi.php +1269 -0
  87. data/vendor/sphinx_client/spec/fixtures/update_attributes.php +8 -0
  88. data/vendor/sphinx_client/spec/fixtures/update_attributes_mva.php +8 -0
  89. data/vendor/sphinx_client/spec/fixtures/weights.php +9 -0
  90. data/vendor/sphinx_client/spec/sphinx/sphinx-id64.conf +67 -0
  91. data/vendor/sphinx_client/spec/sphinx/sphinx.conf +67 -0
  92. data/vendor/sphinx_client/spec/sphinx/sphinx_test.sql +86 -0
  93. data/vendor/sphinx_client/sphinx.yml.tpl +3 -0
  94. data/vendor/sphinx_client/tasks/sphinx.rake +75 -0
  95. metadata +151 -0
data/lib/multi_set.rb ADDED
@@ -0,0 +1,67 @@
1
+ class MultiSet
2
+ include Enumerable
3
+ deep_clonable
4
+
5
+ attr_accessor :sets
6
+
7
+ def initialize(*sets)
8
+ @sets = sets
9
+ end
10
+
11
+ def add!(other)
12
+ if other.kind_of?(MultiSet)
13
+ sets.concat(other.sets)
14
+ else
15
+ sets << other
16
+ end
17
+ self
18
+ end
19
+
20
+ alias << add!
21
+
22
+ def method_missing(method_name, *args)
23
+ method_name = method_name.to_s
24
+ if method_name =~ /\!$/
25
+ sets.each do |set|
26
+ set.send(method_name, *args)
27
+ end
28
+ self
29
+ else
30
+ sets.collect do |set|
31
+ set.send(method_name, *args)
32
+ end
33
+ end
34
+ end
35
+
36
+ def ids_by_class
37
+ ids_by_class = {}
38
+ sets.each do |set|
39
+ ids_by_class[set.model_class] ||= OrderedSet.new
40
+ ids_by_class[set.model_class].concat(set.ids)
41
+ end
42
+ ids_by_class.keys.each do |model_class|
43
+ ids_by_class[model_class] = ids_by_class[model_class].to_a
44
+ end
45
+ ids_by_class
46
+ end
47
+
48
+ def ids
49
+ ids = OrderedSet.new
50
+ sets.each do |set|
51
+ ids.concat(set.ids)
52
+ end
53
+ ids.to_a
54
+ end
55
+
56
+ def each
57
+ sets.each do |set|
58
+ set.each do |model|
59
+ yield model
60
+ end
61
+ end
62
+ end
63
+
64
+ clone_method :+, :add!
65
+ clone_method :-, :subtract!
66
+ clone_method :&, :intersect!
67
+ end
@@ -0,0 +1,329 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ModelSetTest < Test::Unit::TestCase
4
+ class CreateTables < ActiveRecord::Migration
5
+ def self.up
6
+ create_table :heroes do |t|
7
+ t.column :name, :string
8
+ t.column :universe, :string
9
+ end
10
+
11
+ create_table :superpowers do |t|
12
+ t.column :name, :string
13
+ end
14
+
15
+ create_table :mutations do |t|
16
+ t.column :name, :string
17
+ end
18
+
19
+ create_table :superpets do |t|
20
+ t.column :name, :string
21
+ t.column :species, :string
22
+ t.column :owner_id, :bigint
23
+ end
24
+
25
+ create_table :hero_superpowers do |t|
26
+ t.column :hero_id, :bigint
27
+ t.column :power_type, :string
28
+ t.column :power_id, :bigint
29
+ end
30
+
31
+ create_table :hero_birthdays do |t|
32
+ t.column :hero_id, :bigint
33
+ t.column :birthday, :date
34
+ end
35
+
36
+ create_table :robots do |t|
37
+ t.string :name
38
+ t.string :classification
39
+ end
40
+ end
41
+
42
+ def self.down
43
+ drop_table :heroes
44
+ drop_table :superpowers
45
+ drop_table :mutations
46
+ drop_table :superpets
47
+ drop_table :hero_superpowers
48
+ drop_table :hero_birthdays
49
+ drop_table :robots
50
+ end
51
+ end
52
+
53
+ class Superpower < ActiveRecord::Base
54
+ end
55
+
56
+ class Mutation < ActiveRecord::Base
57
+ end
58
+
59
+ class Superpet < ActiveRecord::Base
60
+ end
61
+
62
+ class HeroSuperpower < ActiveRecord::Base
63
+ end
64
+
65
+ class Hero < ActiveRecord::Base
66
+ set_table_name 'heroes'
67
+ has_set :superpowers, :through => :hero_superpowers, :other_key => :power_id
68
+ has_set :pets, :class_name => 'Superpet', :own_key => :owner_id do
69
+ def dogs!
70
+ add_conditions!("species = 'dog'")
71
+ end
72
+ end
73
+ end
74
+
75
+ class HeroSet < ModelSet
76
+ constructor :with_universe
77
+ clone_method :with_universe
78
+ def with_universe!(universe)
79
+ add_conditions!("universe = '#{universe}'")
80
+ end
81
+
82
+ clone_method :add_birthday
83
+ def add_birthday!
84
+ add_fields!( "hero_birthdays.birthday" => "LEFT OUTER JOIN hero_birthdays ON heroes.id = hero_birthdays.hero_id" )
85
+ end
86
+ end
87
+
88
+ context 'with a db connection' do
89
+ setup do
90
+ CreateTables.verbose = false
91
+ CreateTables.up
92
+ end
93
+
94
+ teardown do
95
+ CreateTables.down
96
+ end
97
+
98
+ should "construct a model set" do
99
+ captain = Hero.create(:name => 'Captain America', :universe => 'Marvel')
100
+ spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
101
+ batman = Hero.create(:name => 'Batman', :universe => 'D.C.' )
102
+ superman = Hero.create(:name => 'Superman', :universe => 'D.C.' )
103
+ ironman = Hero.create(:name => 'Iron Man', :universe => 'Marvel')
104
+
105
+ set = HeroSet.with_universe('Marvel')
106
+ assert_equal [captain.id, spidey.id, ironman.id], set.ids
107
+ end
108
+
109
+ should "maintain initial order when adding conditions" do
110
+ captain = Hero.create(:name => 'Captain America', :universe => 'Marvel')
111
+ spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
112
+ batman = Hero.create(:name => 'Batman', :universe => 'D.C.' )
113
+ superman = Hero.create(:name => 'Superman', :universe => 'D.C.' )
114
+ ironman = Hero.create(:name => 'Iron Man', :universe => 'Marvel')
115
+
116
+ set = HeroSet.new([ironman, captain, superman, spidey, batman])
117
+
118
+ set.add_conditions!("universe = 'Marvel'")
119
+
120
+ assert_equal [ironman.id, captain.id, spidey.id], set.ids
121
+ end
122
+
123
+ should "order and reverse set" do
124
+ captain = Hero.create(:name => 'Captain America', :universe => 'Marvel')
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' )
128
+ ironman = Hero.create(:name => 'Iron Man', :universe => 'Marvel')
129
+
130
+ ids = [captain.id, ironman.id, phoenix.id, spidey.id, wolverine.id]
131
+ set = HeroSet.with_universe('Marvel')
132
+
133
+ set.order_by!('name')
134
+ assert_equal ids, set.ids
135
+
136
+ set.reverse!
137
+ assert_equal ids.reverse, set.ids
138
+
139
+ set.order_by!('name DESC')
140
+ assert_equal ids.reverse, set.ids
141
+
142
+ set.reverse!
143
+ assert_equal ids, set.ids
144
+
145
+ # Make sure that a comma in a function call works.
146
+ set.order_by!("lower(ltrim(name, 'C'))")
147
+ assert_equal ids, set.ids
148
+
149
+ set.reverse!
150
+ assert_equal ids.reverse, set.ids
151
+ end
152
+
153
+ should "have missing ids" do
154
+ missing_id = 5555
155
+ spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
156
+ set = HeroSet.new([spidey.id, missing_id])
157
+
158
+ # Iterate through the profiles so the missing ones will be detected.
159
+ set.each {}
160
+ assert_equal [missing_id], set.missing_ids
161
+ end
162
+
163
+ should "have missing ids with add_fields" do
164
+ missing_id = 5555
165
+ spidey = Hero.create(:name => 'Spider Man', :universe => 'Marvel')
166
+ set = HeroSet.new([spidey.id, missing_id]).add_birthday
167
+
168
+ # Iterate through the profiles so the missing ones will be detected.
169
+ set.each {}
170
+ assert_equal [missing_id], set.missing_ids
171
+ end
172
+
173
+ should "support has_set" do
174
+ hero = Hero.create(:name => 'Mr. Invisible')
175
+ mighty_mouse = Superpet.create(:name => 'Mighty Mouse', :owner_id => hero.id)
176
+ underdog = Superpet.create(:name => 'Underdog', :owner_id => hero.id)
177
+
178
+ set = hero.pets
179
+ assert_equal SuperpetSet, set.class
180
+ assert_equal [mighty_mouse.id, underdog.id], set.ids
181
+ end
182
+
183
+ should "support has_set with through" do
184
+ hero = Hero.create(:name => 'Mr. Invisible')
185
+ invisibility = Superpower.create(:name => 'Invisibility')
186
+ flying = Superpower.create(:name => 'Flying')
187
+ HeroSuperpower.create(:hero_id => hero.id, :power_id => invisibility.id)
188
+ HeroSuperpower.create(:hero_id => hero.id, :power_id => flying.id)
189
+
190
+ set = hero.superpowers
191
+ assert_equal SuperpowerSet, set.class
192
+ assert_equal [invisibility.id, flying.id], set.ids
193
+ end
194
+
195
+ should "allow set extensions" do
196
+ hero = Hero.create(:name => 'Mr. Invisible')
197
+ mighty_mouse = Superpet.create(:name => 'Mighty Mouse', :owner_id => hero.id, :species => 'mouse')
198
+ sammy = Superpet.create(:name => 'Sammy Davis Jr. Jr.', :owner_id => hero.id, :species => 'dog')
199
+ underdog = Superpet.create(:name => 'Underdog', :owner_id => hero.id, :species => 'dog')
200
+
201
+ set = hero.pets
202
+ assert_equal ['mouse', 'dog', 'dog'], set.collect {|pet| pet.species}
203
+
204
+ assert_equal [sammy.id, underdog.id], set.dogs!.ids
205
+ end
206
+
207
+ class Robot < ActiveRecord::Base
208
+ end
209
+
210
+ class RobotSet < ModelSet
211
+ end
212
+
213
+ setup do
214
+ @bender = Robot.create(:name => 'Bender', :classification => :smart_ass )
215
+ @r2d2 = Robot.create(:name => 'R2D2', :classification => :droid )
216
+ @c3po = Robot.create(:name => 'C3PO', :classification => :droid )
217
+ @rosie = Robot.create(:name => 'Rosie', :classification => :domestic )
218
+ @small_wonder = Robot.create(:name => 'Vicki', :classification => :child )
219
+ @t1000 = Robot.create(:name => 'Terminator', :classification => :assasin )
220
+ @johnny5 = Robot.create(:name => 'Johnny 5', :classification => :miltary )
221
+
222
+ @bot_set = RobotSet.new([@bender,@r2d2,@c3po,@rosie,@small_wonder,@t1000,@johnny5])
223
+
224
+ @data = Robot.create(:name => 'Data', :classification => :positronic)
225
+ @number8 = Robot.create(:name => 'Boomer', :classification => :cylon )
226
+ end
227
+
228
+ should "be empty" do
229
+ set = RobotSet.empty
230
+ assert_equal 0, set.size
231
+ assert set.empty?
232
+
233
+ set = RobotSet.new(@bender)
234
+ assert !set.empty?
235
+ end
236
+
237
+ should "create a set with single model" do
238
+ set = RobotSet.new(@bender)
239
+ assert_equal [@bender.id], set.ids
240
+ end
241
+
242
+ should "include models" do
243
+ set = RobotSet.new([@bender, @r2d2.id, @c3po.id])
244
+ assert set.include?(@bender)
245
+ assert set.include?(@r2d2.id)
246
+ assert set.include?(@c3po)
247
+ end
248
+
249
+ should "delete models from a set" do
250
+ set = RobotSet.new([@rosie, @small_wonder, @c3po])
251
+
252
+ set.delete(@c3po)
253
+ assert_equal [@rosie.id, @small_wonder.id], set.ids
254
+
255
+ set.delete(@rosie.id)
256
+ assert_equal [@small_wonder.id], set.ids
257
+
258
+ set.delete(@small_wonder)
259
+ assert_equal [], set.ids
260
+ assert set.empty?
261
+ end
262
+
263
+ should "select models from a set" do
264
+ assert_equal [@r2d2, @c3po], @bot_set.select {|bot| bot.classification == :droid}.to_a
265
+ assert_equal 7, @bot_set.size
266
+
267
+ @bot_set.select! {|bot| bot.classification == :miltary}
268
+ assert_equal [@johnny5], @bot_set.to_a
269
+ end
270
+
271
+ should "sort a set" do
272
+ assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder], @bot_set.sort {|a,b| a.name <=> b.name}.to_a
273
+ assert_equal @johnny5, @bot_set.last
274
+
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
277
+
278
+ @bot_set.reverse!
279
+ assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder], @bot_set.to_a
280
+ end
281
+
282
+ should "sort a set by name" do
283
+ assert_equal [@bender,@c3po,@johnny5,@r2d2,@rosie,@t1000,@small_wonder], @bot_set.sort_by {|bot| bot.name}.to_a
284
+ end
285
+
286
+ should "reject models from a set" do
287
+ @bot_set.reject! {|bot| bot.classification == :domestic}
288
+ assert !@bot_set.include?(@rosie)
289
+ end
290
+
291
+ should "do set arithmetic" do
292
+ droids = RobotSet.new([@c3po, @r2d2])
293
+ womanoids = RobotSet.new([@rosie, @small_wonder, @number8])
294
+ humanoids = RobotSet.new([@small_wonder, @t1000, @data, @number8])
295
+ metalics = RobotSet.new([@r2d2, @c3po, @johnny5])
296
+ cartoons = RobotSet.new([@bender, @rosie])
297
+
298
+ assert_equal ['C3PO', 'R2D2', 'Johnny 5'], (droids + metalics).collect {|bot| bot.name}
299
+ assert_equal ['Bender', 'Rosie', 'C3PO', 'R2D2', 'Johnny 5'], (cartoons + droids + metalics).collect {|bot| bot.name}
300
+ assert_equal 5, (cartoons + droids + metalics).size
301
+ assert_equal 5, (cartoons + droids + metalics).count
302
+
303
+ assert_equal [], (droids - metalics).collect {|bot| bot.name}
304
+ assert_equal ['Johnny 5'], (metalics - droids).collect {|bot| bot.name}
305
+ assert_equal ['Terminator', 'Data'], (humanoids - womanoids).collect {|bot| bot.name}
306
+ assert_equal ['Bender'], (cartoons - womanoids).collect {|bot| bot.name}
307
+ assert_equal 2, (humanoids - womanoids).size
308
+ assert_equal 2, (humanoids - womanoids).count
309
+
310
+ assert_equal ['C3PO', 'R2D2'], (droids & metalics).collect {|bot| bot.name}
311
+ assert_equal ['R2D2', 'C3PO'], (metalics & droids).collect {|bot| bot.name}
312
+ assert_equal ['Vicki', 'Boomer'], (humanoids & womanoids).collect {|bot| bot.name}
313
+ assert_equal ['Rosie'], (cartoons & womanoids).collect {|bot| bot.name}
314
+ assert_equal 2, (humanoids & womanoids).size
315
+ assert_equal 2, (humanoids & womanoids).count
316
+
317
+ set = (droids + @johnny5)
318
+ assert_equal ['C3PO', 'R2D2', 'Johnny 5'], set.collect {|bot| bot.name}
319
+ set -= @r2d2
320
+ assert_equal ['C3PO', 'Johnny 5'], set.collect {|bot| bot.name}
321
+ end
322
+
323
+ should "clone a set" do
324
+ set = RobotSet.new([1])
325
+ new_set = set.clone
326
+ assert new_set.object_id != set.object_id
327
+ end
328
+ end
329
+ end
@@ -0,0 +1,65 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class MultiSetTest < Test::Unit::TestCase
4
+ class CreateTables < ActiveRecord::Migration
5
+ def self.up
6
+ create_table :robots do |t|
7
+ t.string :name
8
+ t.string :classification
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :robots
14
+ end
15
+ end
16
+
17
+ class Robot < ActiveRecord::Base
18
+ end
19
+
20
+ class RobotSet < ModelSet
21
+ end
22
+
23
+ context 'with a db connection' do
24
+ setup do
25
+ CreateTables.verbose = false
26
+ CreateTables.up
27
+
28
+ @bender = Robot.create(:name => 'Bender', :classification => :smart_ass )
29
+ @r2d2 = Robot.create(:name => 'R2D2', :classification => :droid )
30
+ @c3po = Robot.create(:name => 'C3PO', :classification => :droid )
31
+ @rosie = Robot.create(:name => 'Rosie', :classification => :domestic )
32
+ @small_wonder = Robot.create(:name => 'Vicki', :classification => :child )
33
+ @t1000 = Robot.create(:name => 'Terminator', :classification => :assasin )
34
+ @johnny5 = Robot.create(:name => 'Johnny 5', :classification => :miltary )
35
+ @data = Robot.create(:name => 'Data', :classification => :positronic)
36
+ @number8 = Robot.create(:name => 'Boomer', :classification => :cylon )
37
+ end
38
+
39
+ teardown do
40
+ CreateTables.down
41
+ end
42
+
43
+ should "add, subtract, intersect" do
44
+ set = MultiSet.new
45
+ set += RobotSet.new([@bender, @r2d2, @rosie])
46
+ set += RobotSet.new([@c3po, @r2d2, @t1000])
47
+ set += RobotSet.new([@data, @number8, @johnny5])
48
+
49
+ assert_equal [3,3,3], set.size
50
+ assert_equal [@bender,@r2d2,@rosie,@c3po,@t1000,@data,@number8,@johnny5].collect {|r| r.id}, set.ids
51
+ assert_equal [@bender,@r2d2,@rosie,@c3po,@r2d2,@t1000,@data,@number8,@johnny5], set.to_a
52
+
53
+ set -= RobotSet.new([@r2d2, @rosie, @t1000, @johnny5])
54
+
55
+ assert_equal [1,1,2], set.size
56
+ assert_equal [@bender,@c3po,@data,@number8].collect {|r| r.id}, set.ids
57
+
58
+ other_set = MultiSet.new(RobotSet.new([@data]), RobotSet.new([@bender]))
59
+
60
+ set &= other_set
61
+ assert_equal [1,0,1], set.size
62
+ assert_equal [@bender,@data].collect {|r| r.id}, set.ids
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
7
+ ['deep_clonable', 'ordered_set'].each do |dir|
8
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/../../#{dir}/lib"
9
+ end
10
+ require 'model_set'
11
+
12
+ class Test::Unit::TestCase
13
+ end
14
+
15
+ ActiveRecord::Base.establish_connection(
16
+ :adapter => "postgresql",
17
+ :host => "localhost",
18
+ :username => "postgres",
19
+ :password => "",
20
+ :database => "model_set_test"
21
+ )
22
+ ActiveRecord::Migration.verbose = false
23
+ ActiveRecord::Base.connection.client_min_messages = 'panic'
@@ -0,0 +1,41 @@
1
+ =Sphinx Client API 0.9.9-dev (r1299)
2
+
3
+ This document gives an overview of what is Sphinx itself and how to use in
4
+ within Ruby on Rails. For more information or documentation,
5
+ please go to http://www.sphinxsearch.com
6
+
7
+ ==Sphinx
8
+
9
+ Sphinx is a standalone full-text search engine, meant to provide fast,
10
+ size-efficient and relevant fulltext search functions to other applications.
11
+ Sphinx was specially designed to integrate well with SQL databases and
12
+ scripting languages. Currently built-in data sources support fetching data
13
+ either via direct connection to MySQL, or from an XML pipe.
14
+
15
+ Simplest way to communicate with Sphinx is to use <tt>searchd</tt> -
16
+ a daemon to search through fulltext indices from external software.
17
+
18
+ ==Documentation
19
+
20
+ You can create the documentation by running:
21
+
22
+ rake rdoc
23
+
24
+ ==Latest version
25
+
26
+ You can always get latest version from
27
+ http://kpumuk.info/projects/ror-plugins/sphinx
28
+
29
+ ==Credits
30
+
31
+ Dmytro Shteflyuk <kpumuk@kpumuk.info> http://kpumuk.info
32
+
33
+ Andrew Aksyonoff http://sphinxsearch.com/
34
+
35
+ Special thanks to Alexey Kovyrin <alexey@kovyrin.net> http://blog.kovyrin.net
36
+
37
+ ==License
38
+
39
+ This library is distributed under the terms of the Ruby license.
40
+ You can freely distribute/modify this library.
41
+
@@ -0,0 +1,21 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :spec
7
+
8
+ desc 'Test the sphinx plugin.'
9
+ Spec::Rake::SpecTask.new(:spec) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'spec/*_spec.rb'
12
+ end
13
+
14
+ desc 'Generate documentation for the sphinx plugin.'
15
+ Rake::RDocTask.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Sphinx Client API'
18
+ rdoc.options << '--line-numbers' << '--inline-source'
19
+ rdoc.rdoc_files.include('README')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/lib/sphinx'
@@ -0,0 +1,5 @@
1
+ require 'fileutils'
2
+
3
+ sphinx_config = File.dirname(__FILE__) + '/../../../config/sphinx.yml'
4
+ FileUtils.cp File.dirname(__FILE__) + '/sphinx.yml.tpl', sphinx_config unless File.exist?(sphinx_config)
5
+ puts IO.read(File.join(File.dirname(__FILE__), 'README'))