model_set 0.10.6

Sign up to get free protection for your applications and to get access to all the features.
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'))