thinking-sphinx 1.3.17 → 1.3.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README.textile +2 -0
  2. data/VERSION +1 -1
  3. data/features/attribute_updates.feature +27 -1
  4. data/features/searching_by_model.feature +1 -1
  5. data/features/step_definitions/common_steps.rb +5 -0
  6. data/features/thinking_sphinx/database.yml +1 -2
  7. data/features/thinking_sphinx/db/fixtures/betas.rb +1 -0
  8. data/features/thinking_sphinx/db/fixtures/comments.rb +1 -1
  9. data/features/thinking_sphinx/models/developer.rb +2 -2
  10. data/features/thinking_sphinx/models/extensible_beta.rb +1 -1
  11. data/lib/cucumber/thinking_sphinx/internal_world.rb +6 -5
  12. data/lib/thinking_sphinx.rb +4 -12
  13. data/lib/thinking_sphinx/active_record/attribute_updates.rb +10 -6
  14. data/lib/thinking_sphinx/active_record/scopes.rb +2 -2
  15. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +5 -1
  16. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +4 -0
  17. data/lib/thinking_sphinx/configuration.rb +2 -1
  18. data/lib/thinking_sphinx/context.rb +6 -3
  19. data/lib/thinking_sphinx/excerpter.rb +1 -1
  20. data/lib/thinking_sphinx/index/builder.rb +6 -0
  21. data/lib/thinking_sphinx/index/faux_column.rb +4 -0
  22. data/lib/thinking_sphinx/join.rb +37 -0
  23. data/lib/thinking_sphinx/rails_additions.rb +4 -4
  24. data/lib/thinking_sphinx/search.rb +3 -3
  25. data/lib/thinking_sphinx/source.rb +8 -2
  26. data/spec/thinking_sphinx/active_record/delta_spec.rb +1 -1
  27. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +1 -1
  28. data/spec/thinking_sphinx/active_record/scopes_spec.rb +1 -1
  29. data/spec/thinking_sphinx/active_record_spec.rb +1 -1
  30. data/spec/thinking_sphinx/association_spec.rb +1 -1
  31. data/spec/thinking_sphinx/attribute_spec.rb +1 -1
  32. data/spec/thinking_sphinx/auto_version_spec.rb +1 -1
  33. data/spec/thinking_sphinx/configuration_spec.rb +3 -2
  34. data/spec/thinking_sphinx/context_spec.rb +8 -1
  35. data/spec/thinking_sphinx/core/array_spec.rb +1 -1
  36. data/spec/thinking_sphinx/core/string_spec.rb +1 -1
  37. data/spec/thinking_sphinx/excerpter_spec.rb +1 -9
  38. data/spec/thinking_sphinx/facet_search_spec.rb +1 -1
  39. data/spec/thinking_sphinx/facet_spec.rb +1 -1
  40. data/spec/thinking_sphinx/field_spec.rb +1 -1
  41. data/spec/thinking_sphinx/index/builder_spec.rb +17 -1
  42. data/spec/thinking_sphinx/index/faux_column_spec.rb +1 -1
  43. data/spec/thinking_sphinx/index_spec.rb +1 -1
  44. data/spec/thinking_sphinx/rails_additions_spec.rb +5 -5
  45. data/spec/thinking_sphinx/search_methods_spec.rb +1 -1
  46. data/spec/thinking_sphinx/search_spec.rb +1 -1
  47. data/spec/thinking_sphinx/source_spec.rb +9 -1
  48. data/spec/thinking_sphinx_spec.rb +1 -28
  49. metadata +140 -4
@@ -163,3 +163,5 @@ Since I first released this library, there's been quite a few people who have su
163
163
  * Edgars Beigarts
164
164
  * Ivan Ukhov
165
165
  * Tomáš Pospíšek
166
+ * Tom Stuart
167
+ * James Brooks
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.17
1
+ 1.3.18
@@ -38,7 +38,33 @@ Feature: Update attributes directly to Sphinx
38
38
 
39
39
  When I search for the document id of beta eight in the beta_delta index
40
40
  Then it should not exist
41
-
41
+
42
+ Scenario: Updating attributes in a delta index
43
+ Given Sphinx is running
44
+ And I am searching on betas
45
+
46
+ When I change the name of beta nine to nineteen
47
+ And I change the value of beta nineteen to 19
48
+ And I wait for Sphinx to catch up
49
+
50
+ When I filter by 19 on value
51
+ And I use index beta_delta
52
+ Then I should get 1 result
53
+
54
+ Scenario: Updating attributes in a delta index with deltas disabled
55
+ Given Sphinx is running
56
+ And I am searching on betas
57
+
58
+ When I change the name of beta eleven to twentyone
59
+ And I disable delta updates
60
+ And I change the value of beta twentyone to 21
61
+ And I wait for Sphinx to catch up
62
+
63
+ When I filter by 21 on value
64
+ And I use index beta_delta
65
+ Then I should get 1 result
66
+ And I enable delta updates
67
+
42
68
  Scenario: Updating boolean attribute in Sphinx
43
69
  Given Sphinx is running
44
70
  And I am searching on alphas
@@ -63,7 +63,7 @@ Feature: Searching on a single model
63
63
  Scenario: Filtering on timestamp MVAs
64
64
  Given Sphinx is running
65
65
  And I am searching on posts
66
- When I filter by 978307200 on comments_created_at
66
+ When I filter by 2001-01-01 on comments_created_at
67
67
  Then I should get 1 result
68
68
 
69
69
  Scenario: Searching by NULL/0 values in MVAs
@@ -71,6 +71,11 @@ When /^I filter by (\w+) on (\w+)$/ do |filter, attribute|
71
71
  @with[attribute.to_sym] = filter.to_i
72
72
  end
73
73
 
74
+ When /^I filter by (\d\d\d\d)\-(\d\d)\-(\d\d) on (\w+)$/ do |y, m, d, attribute|
75
+ @results = nil
76
+ @with[attribute.to_sym] = Time.local(y.to_i, m.to_i, d.to_i).to_i
77
+ end
78
+
74
79
  When /^I filter by (\d+) and (\d+) on (\w+)$/ do |value_one, value_two, attribute|
75
80
  @results = nil
76
81
  @with[attribute.to_sym] = [value_one.to_i, value_two.to_i]
@@ -1,4 +1,3 @@
1
- username: root
2
- host: localhost
1
+ username: thinking_sphinx
3
2
  pool: 1
4
3
  min_messages: warning
@@ -8,3 +8,4 @@ Beta.create :name => "seven", :value => 7
8
8
  Beta.create :name => "eight", :value => 8
9
9
  Beta.create :name => "nine", :value => 9
10
10
  Beta.create :name => "ten", :value => 10
11
+ Beta.create :name => "eleven", :value => 11
@@ -4,7 +4,7 @@ Comment.create(
4
4
  :content => "+1",
5
5
  :post_id => 1,
6
6
  :category_id => 1
7
- ).update_attribute(:created_at, Time.utc(2001, 01, 01).getlocal)
7
+ ).update_attribute(:created_at, Time.local(2001, 01, 01).getutc)
8
8
 
9
9
  Comment.create(
10
10
  :name => "Menno",
@@ -1,5 +1,5 @@
1
- require 'features/thinking_sphinx/models/tag'
2
- require 'features/thinking_sphinx/models/tagging'
1
+ require "#{File.dirname(__FILE__)}/tag"
2
+ require "#{File.dirname(__FILE__)}/tagging"
3
3
 
4
4
  class Developer < ActiveRecord::Base
5
5
  has_many :taggings, :as => :taggable
@@ -1,4 +1,4 @@
1
- require 'features/support/lib/generic_delta_handler'
1
+ require "#{Dir.pwd}/features/support/lib/generic_delta_handler"
2
2
 
3
3
  class ExtensibleBeta < ActiveRecord::Base
4
4
  define_index do
@@ -9,11 +9,12 @@ module Cucumber
9
9
  :password, :host
10
10
 
11
11
  def initialize
12
- @temporary_directory = "#{Dir.pwd}/tmp"
13
- @migrations_directory = "features/thinking_sphinx/db/migrations"
14
- @models_directory = "features/thinking_sphinx/models"
15
- @fixtures_directory = "features/thinking_sphinx/db/fixtures"
16
- @database_file = "features/thinking_sphinx/database.yml"
12
+ pwd = Dir.pwd
13
+ @temporary_directory = "#{pwd}/tmp"
14
+ @migrations_directory = "#{pwd}/features/thinking_sphinx/db/migrations"
15
+ @models_directory = "#{pwd}/features/thinking_sphinx/models"
16
+ @fixtures_directory = "#{pwd}/features/thinking_sphinx/db/fixtures"
17
+ @database_file = "#{pwd}/features/thinking_sphinx/database.yml"
17
18
 
18
19
  @adapter = ENV['DATABASE'] || 'mysql'
19
20
  @database = 'thinking_sphinx'
@@ -1,7 +1,6 @@
1
1
  require 'active_record'
2
2
  require 'after_commit'
3
3
  require 'yaml'
4
- require 'cgi'
5
4
  require 'riddle'
6
5
 
7
6
  require 'thinking_sphinx/auto_version'
@@ -19,6 +18,7 @@ require 'thinking_sphinx/class_facet'
19
18
  require 'thinking_sphinx/facet_search'
20
19
  require 'thinking_sphinx/field'
21
20
  require 'thinking_sphinx/index'
21
+ require 'thinking_sphinx/join'
22
22
  require 'thinking_sphinx/source'
23
23
  require 'thinking_sphinx/rails_additions'
24
24
  require 'thinking_sphinx/search'
@@ -70,7 +70,7 @@ module ThinkingSphinx
70
70
  if @@context.nil?
71
71
  @@sphinx_mutex.synchronize do
72
72
  if @@context.nil?
73
- set_context
73
+ @@context = ThinkingSphinx::Context.new
74
74
  @@context.prepare
75
75
  end
76
76
  end
@@ -79,21 +79,11 @@ module ThinkingSphinx
79
79
  @@context
80
80
  end
81
81
 
82
- def self.set_context(*classes)
83
- @@context = ThinkingSphinx::Context.new(*classes)
84
- end
85
-
86
82
  def self.reset_context!
87
83
  @@sphinx_mutex.synchronize do
88
84
  @@context = nil
89
85
  end
90
86
  end
91
-
92
- def self.indexed_models=(classes = [])
93
- @@sphinx_mutex.synchronize do
94
- set_context *classes
95
- end
96
- end
97
87
 
98
88
  def self.unique_id_expression(offset = nil)
99
89
  "* #{context.indexed_models.size} + #{offset || 0}"
@@ -225,6 +215,8 @@ module ThinkingSphinx
225
215
 
226
216
  def self.pid_active?(pid)
227
217
  !!Process.kill(0, pid.to_i)
218
+ rescue Errno::EPERM => e
219
+ true
228
220
  rescue Exception => e
229
221
  false
230
222
  end
@@ -13,9 +13,6 @@ module ThinkingSphinx
13
13
  return true unless ThinkingSphinx.updates_enabled? &&
14
14
  ThinkingSphinx.sphinx_running?
15
15
 
16
- config = ThinkingSphinx::Configuration.instance
17
- client = config.client
18
-
19
16
  self.class.sphinx_indexes.each do |index|
20
17
  attribute_pairs = attribute_values_for_index(index)
21
18
  attribute_names = attribute_pairs.keys
@@ -23,9 +20,9 @@ module ThinkingSphinx
23
20
  attribute_pairs[key]
24
21
  }
25
22
 
26
- client.update "#{index.core_name}", attribute_names, {
27
- sphinx_document_id => attribute_values
28
- } if self.class.search_for_id(sphinx_document_id, index.core_name)
23
+ update_index index.core_name, attribute_names, attribute_values
24
+ next unless index.delta?
25
+ update_index index.delta_name, attribute_names, attribute_values
29
26
  end
30
27
 
31
28
  true
@@ -41,6 +38,13 @@ module ThinkingSphinx
41
38
  hash
42
39
  }
43
40
  end
41
+
42
+ def update_index(index_name, attribute_names, attribute_values)
43
+ config = ThinkingSphinx::Configuration.instance
44
+ config.client.update index_name, attribute_names, {
45
+ sphinx_document_id => attribute_values
46
+ } if self.class.search_for_id(sphinx_document_id, index_name)
47
+ end
44
48
  end
45
49
  end
46
50
  end
@@ -46,7 +46,7 @@ module ThinkingSphinx
46
46
  @sphinx_scopes ||= []
47
47
  @sphinx_scopes << method
48
48
 
49
- metaclass.instance_eval do
49
+ singleton_class.instance_eval do
50
50
  define_method(method) do |*args|
51
51
  options = {:classes => classes_option}
52
52
  options.merge! block.call(*args)
@@ -64,7 +64,7 @@ module ThinkingSphinx
64
64
 
65
65
  def remove_sphinx_scopes
66
66
  sphinx_scopes.each do |scope|
67
- metaclass.send(:undef_method, scope)
67
+ singleton_class.send(:undef_method, scope)
68
68
  end
69
69
 
70
70
  sphinx_scopes.clear
@@ -50,5 +50,9 @@ module ThinkingSphinx
50
50
  def time_difference(diff)
51
51
  "DATE_SUB(NOW(), INTERVAL #{diff} SECOND)"
52
52
  end
53
+
54
+ def utc_query_pre
55
+ "SET TIME_ZONE = '+0:00'"
56
+ end
53
57
  end
54
- end
58
+ end
@@ -67,6 +67,10 @@ module ThinkingSphinx
67
67
  "current_timestamp - interval '#{diff} seconds'"
68
68
  end
69
69
 
70
+ def utc_query_pre
71
+ 'SET TIME ZONE UTC'
72
+ end
73
+
70
74
  private
71
75
 
72
76
  def execute(command, output_error = false)
@@ -65,7 +65,7 @@ module ThinkingSphinx
65
65
  CustomOptions = %w( disable_range )
66
66
 
67
67
  attr_accessor :searchd_file_path, :allow_star, :database_yml_file,
68
- :app_root, :model_directories, :delayed_job_priority
68
+ :app_root, :model_directories, :delayed_job_priority, :indexed_models
69
69
 
70
70
  attr_accessor :source_options, :index_options
71
71
  attr_accessor :version
@@ -109,6 +109,7 @@ module ThinkingSphinx
109
109
  self.model_directories = ["#{app_root}/app/models/"] +
110
110
  Dir.glob("#{app_root}/vendor/plugins/*/app/models/")
111
111
  self.delayed_job_priority = 0
112
+ self.indexed_models = []
112
113
 
113
114
  self.source_options = {}
114
115
  self.index_options = {
@@ -3,12 +3,15 @@ class ThinkingSphinx::Context
3
3
 
4
4
  def initialize(*models)
5
5
  @indexed_models = []
6
- models.each do |model|
7
- add_indexed_model model
8
- end
9
6
  end
10
7
 
11
8
  def prepare
9
+ ThinkingSphinx::Configuration.instance.indexed_models.each do |model|
10
+ add_indexed_model model
11
+ end
12
+
13
+ return unless indexed_models.empty?
14
+
12
15
  load_models
13
16
  add_indexed_models
14
17
  end
@@ -14,7 +14,7 @@ module ThinkingSphinx
14
14
  end
15
15
 
16
16
  def method_missing(method, *args, &block)
17
- string = CGI::escapeHTML @instance.send(method, *args, &block).to_s
17
+ string = @instance.send(method, *args, &block).to_s
18
18
 
19
19
  @search.excerpt_for(string, @instance.class)
20
20
  end
@@ -164,6 +164,12 @@ module ThinkingSphinx
164
164
  end
165
165
  end
166
166
 
167
+ def join(*args)
168
+ args.each do |association|
169
+ Join.new(source, association)
170
+ end
171
+ end
172
+
167
173
  # Use this method to add some manual SQL conditions for your index
168
174
  # request. You can pass in as many strings as you like, they'll get
169
175
  # joined together with ANDs later on.
@@ -42,6 +42,10 @@ module ThinkingSphinx
42
42
  @stack
43
43
  end
44
44
 
45
+ def __path
46
+ @stack + [@name]
47
+ end
48
+
45
49
  # Returns true if the stack is empty *and* if the name is a string -
46
50
  # which is an indication that of raw SQL, as opposed to a value from a
47
51
  # table's column.
@@ -0,0 +1,37 @@
1
+ module ThinkingSphinx
2
+ class Join
3
+ attr_accessor :source, :column, :associations
4
+
5
+ def initialize(source, column)
6
+ @source = source
7
+ @column = column
8
+
9
+ @associations = association_stack(column.__path.clone).each { |assoc|
10
+ assoc.join_to(source.base)
11
+ }
12
+
13
+ source.joins << self
14
+ end
15
+
16
+ private
17
+
18
+ # Gets a stack of associations for a specific path.
19
+ #
20
+ def association_stack(path, parent = nil)
21
+ assocs = []
22
+
23
+ if parent.nil?
24
+ assocs = @source.association(path.shift)
25
+ else
26
+ assocs = parent.children(path.shift)
27
+ end
28
+
29
+ until path.empty?
30
+ point = path.shift
31
+ assocs = assocs.collect { |assoc| assoc.children(point) }.flatten
32
+ end
33
+
34
+ assocs
35
+ end
36
+ end
37
+ end
@@ -136,8 +136,8 @@ Class.extend(
136
136
  ) unless Class.respond_to?(:cattr_reader)
137
137
 
138
138
  module ThinkingSphinx
139
- module MetaClass
140
- def metaclass
139
+ module SingletonClass
140
+ def singleton_class
141
141
  class << self
142
142
  self
143
143
  end
@@ -145,6 +145,6 @@ module ThinkingSphinx
145
145
  end
146
146
  end
147
147
 
148
- unless Object.new.respond_to?(:metaclass)
149
- Object.send(:include, ThinkingSphinx::MetaClass)
148
+ unless Object.new.respond_to?(:singleton_class)
149
+ Object.send(:include, ThinkingSphinx::SingletonClass)
150
150
  end
@@ -294,7 +294,7 @@ module ThinkingSphinx
294
294
  excerpter = ThinkingSphinx::Excerpter.new self, object
295
295
  block = lambda { excerpter }
296
296
 
297
- object.metaclass.instance_eval do
297
+ object.singleton_class.instance_eval do
298
298
  define_method(:excerpts, &block)
299
299
  end
300
300
  end
@@ -307,7 +307,7 @@ module ThinkingSphinx
307
307
  match = match_hash object
308
308
  next if match.nil?
309
309
 
310
- object.metaclass.instance_eval do
310
+ object.singleton_class.instance_eval do
311
311
  define_method(:sphinx_attributes) { match[:attributes] }
312
312
  end
313
313
  end
@@ -323,7 +323,7 @@ module ThinkingSphinx
323
323
  @results[:fields], match[:weight]
324
324
  )
325
325
 
326
- object.metaclass.instance_eval do
326
+ object.singleton_class.instance_eval do
327
327
  define_method(:matching_fields) { fields }
328
328
  end
329
329
  end
@@ -6,7 +6,7 @@ module ThinkingSphinx
6
6
  include ThinkingSphinx::Source::InternalProperties
7
7
  include ThinkingSphinx::Source::SQL
8
8
 
9
- attr_accessor :model, :fields, :attributes, :conditions, :groupings,
9
+ attr_accessor :model, :fields, :attributes, :joins, :conditions, :groupings,
10
10
  :options
11
11
  attr_reader :base, :index, :database_configuration
12
12
 
@@ -15,6 +15,7 @@ module ThinkingSphinx
15
15
  @model = index.model
16
16
  @fields = []
17
17
  @attributes = []
18
+ @joins = []
18
19
  @conditions = []
19
20
  @groupings = []
20
21
  @options = options
@@ -110,6 +111,7 @@ module ThinkingSphinx
110
111
  end
111
112
 
112
113
  source.sql_query_pre += [adapter.utf8_query_pre].compact if utf8?
114
+ source.sql_query_pre << adapter.utc_query_pre
113
115
  end
114
116
 
115
117
  def set_source_settings(source)
@@ -139,7 +141,11 @@ module ThinkingSphinx
139
141
  # attribute associations
140
142
  @attributes.collect { |attrib|
141
143
  attrib.associations.values if attrib.include_as_association?
142
- }.compact.flatten
144
+ }.compact.flatten +
145
+ # explicit joins
146
+ @joins.collect { |join|
147
+ join.associations
148
+ }.flatten
143
149
  ).uniq.collect { |assoc|
144
150
  # get ancestors as well as column-level associations
145
151
  assoc.ancestors
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe "ThinkingSphinx::ActiveRecord::Delta" do
4
4
  it "should call the toggle_delta method after a save" do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'ThinkingSphinx::ActiveRecord::HasManyAssociation' do
4
4
  describe "search method" do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::ActiveRecord::Scopes do
4
4
  after :each do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::ActiveRecord do
4
4
  before :each do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Association do
4
4
  describe '.children' do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Attribute do
4
4
  before :each do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::AutoVersion do
4
4
  describe '.detect' do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Configuration do
4
4
  describe "environment class method" do
@@ -87,7 +87,8 @@ describe ThinkingSphinx::Configuration do
87
87
  "ignore_chars" => "e",
88
88
  "searchd_binary_name" => "sphinx-searchd",
89
89
  "indexer_binary_name" => "sphinx-indexer",
90
- "index_exact_words" => true
90
+ "index_exact_words" => true,
91
+ "indexed_models" => ['Alpha', 'Beta']
91
92
  }
92
93
  }
93
94
 
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Context do
4
4
  before :each do
@@ -59,6 +59,13 @@ describe ThinkingSphinx::Context do
59
59
  @context.prepare
60
60
  }.should_not raise_error
61
61
  end
62
+
63
+ it "should not load models if they're explicitly set in the configuration" do
64
+ @config.indexed_models = ['Alpha', 'Beta']
65
+ @context.prepare
66
+
67
+ @context.indexed_models.should == ['Alpha', 'Beta']
68
+ end
62
69
  end
63
70
 
64
71
  describe '#define_indexes' do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Array do
4
4
  describe '.===' do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe String do
4
4
  describe "to_crc32 instance method" do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Excerpter do
4
4
  before :each do
@@ -40,14 +40,6 @@ describe ThinkingSphinx::Excerpter do
40
40
  @excerpter.big_name
41
41
  end
42
42
 
43
- it "should escape the text in the excerpt" do
44
- @search.should_receive(:excerpt_for) do |string, model|
45
- string.should == 'test &quot;escaping&quot; &lt;characters&gt;'
46
- end
47
-
48
- @excerpter.string_to_escape
49
- end
50
-
51
43
  it "should still raise an exception if no column or method exists" do
52
44
  lambda {
53
45
  @excerpter.foo
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::FacetSearch do
4
4
  describe 'populate' do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Facet do
4
4
  describe ".name_for" do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Field do
4
4
  before :each do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Index::Builder do
4
4
  describe ".generate without source scope" do
@@ -109,6 +109,22 @@ describe ThinkingSphinx::Index::Builder do
109
109
  end
110
110
  end
111
111
 
112
+ describe '#join' do
113
+ before :each do
114
+ @index = ThinkingSphinx::Index::Builder.generate(Person) do
115
+ indexes first_name
116
+
117
+ join contacts
118
+ end
119
+
120
+ @source = @index.sources.first
121
+ end
122
+
123
+ it "should include the explicit join" do
124
+ @source.joins.length.should == 1
125
+ end
126
+ end
127
+
112
128
  describe "faceted field" do
113
129
  before :each do
114
130
  @index = ThinkingSphinx::Index::Builder.generate(Person) do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Index::FauxColumn do
4
4
  describe "coerce class method" do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Index do
4
4
  describe "prefix_fields method" do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::HashExcept do
4
4
  before(:each) do
@@ -118,14 +118,14 @@ describe ThinkingSphinx::ActiveRecordStoreFullSTIClass do
118
118
  end
119
119
  end
120
120
 
121
- describe ThinkingSphinx::MetaClass do
122
- describe 'metaclass' do
121
+ describe ThinkingSphinx::SingletonClass do
122
+ describe 'singleton_class' do
123
123
  it "should exist as an instance method in Object" do
124
- Object.new.should respond_to('metaclass')
124
+ Object.new.should respond_to('singleton_class')
125
125
  end
126
126
 
127
127
  it "should return the meta/eigen/singleton class" do
128
- Object.new.metaclass.should be_a(Class)
128
+ Object.new.singleton_class.should be_a(Class)
129
129
  end
130
130
  end
131
131
  end
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::SearchMethods do
4
4
  it "should be included into models with indexes" do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
  require 'will_paginate/collection'
3
3
 
4
4
  describe ThinkingSphinx::Search do
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Source do
4
4
  before :each do
@@ -49,6 +49,10 @@ describe ThinkingSphinx::Source do
49
49
  :as => :contact_ids, :source => :query
50
50
  )
51
51
 
52
+ ThinkingSphinx::Join.new(
53
+ @source, ThinkingSphinx::Index::FauxColumn.new(:links)
54
+ )
55
+
52
56
  @source.conditions << "`birthday` <= NOW()"
53
57
  @source.groupings << "`first_name`"
54
58
 
@@ -136,6 +140,10 @@ describe ThinkingSphinx::Source do
136
140
  @query.should_not match(/LEFT OUTER JOIN `contacts`/)
137
141
  end
138
142
 
143
+ it "should include explicitly requested joins" do
144
+ @query.should match(/LEFT OUTER JOIN `links`/)
145
+ end
146
+
139
147
  it "should include any defined conditions" do
140
148
  @query.should match(/WHERE.+`birthday` <= NOW()/)
141
149
  end
@@ -1,4 +1,4 @@
1
- require 'spec/spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx do
4
4
  describe '.context' do
@@ -16,22 +16,6 @@ describe ThinkingSphinx do
16
16
  end
17
17
  end
18
18
 
19
- describe '.set_context' do
20
- before :each do
21
- ThinkingSphinx.reset_context!
22
- end
23
-
24
- it "should set the context instance" do
25
- ThinkingSphinx.set_context
26
- ThinkingSphinx.context.should be_a(ThinkingSphinx::Context)
27
- end
28
-
29
- it "should pass through any given arguments to the initialiser" do
30
- ThinkingSphinx::Context.should_receive(:new).with(Alpha, Beta)
31
- ThinkingSphinx.set_context Alpha, Beta
32
- end
33
- end
34
-
35
19
  describe '.reset_context!' do
36
20
  it "should remove the existing Context instance" do
37
21
  existing = ThinkingSphinx.context
@@ -42,18 +26,7 @@ describe ThinkingSphinx do
42
26
  Thread.current[:thinking_sphinx_context] = existing
43
27
  end
44
28
  end
45
-
46
- describe '.indexed_models=' do
47
- before :each do
48
- ThinkingSphinx.reset_context!
49
- end
50
29
 
51
- it "should set the indexed models for the context" do
52
- ThinkingSphinx.indexed_models = [Alpha, Beta]
53
- ThinkingSphinx.context.indexed_models.should == ['Alpha', 'Beta']
54
- end
55
- end
56
-
57
30
  describe '.define_indexes?' do
58
31
  it "should define indexes by default" do
59
32
  ThinkingSphinx.define_indexes?.should be_true
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thinking-sphinx
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 63
4
5
  prerelease: false
5
6
  segments:
6
7
  - 1
7
8
  - 3
8
- - 17
9
- version: 1.3.17
9
+ - 18
10
+ version: 1.3.18
10
11
  platform: ruby
11
12
  authors:
12
13
  - Pat Allan
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-06-05 00:00:00 +10:00
18
+ date: 2010-06-29 00:00:00 +10:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: activerecord
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 39
27
30
  segments:
28
31
  - 1
29
32
  - 15
@@ -35,9 +38,11 @@ dependencies:
35
38
  name: riddle
36
39
  prerelease: false
37
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ">="
40
44
  - !ruby/object:Gem::Version
45
+ hash: 3
41
46
  segments:
42
47
  - 1
43
48
  - 0
@@ -49,9 +54,11 @@ dependencies:
49
54
  name: after_commit
50
55
  prerelease: false
51
56
  requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
52
58
  requirements:
53
59
  - - ">="
54
60
  - !ruby/object:Gem::Version
61
+ hash: 27
55
62
  segments:
56
63
  - 1
57
64
  - 0
@@ -63,9 +70,11 @@ dependencies:
63
70
  name: yard
64
71
  prerelease: false
65
72
  requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
66
74
  requirements:
67
75
  - - ">="
68
76
  - !ruby/object:Gem::Version
77
+ hash: 3
69
78
  segments:
70
79
  - 0
71
80
  version: "0"
@@ -75,9 +84,11 @@ dependencies:
75
84
  name: rspec
76
85
  prerelease: false
77
86
  requirement: &id005 !ruby/object:Gem::Requirement
87
+ none: false
78
88
  requirements:
79
89
  - - ">="
80
90
  - !ruby/object:Gem::Version
91
+ hash: 13
81
92
  segments:
82
93
  - 1
83
94
  - 2
@@ -89,9 +100,11 @@ dependencies:
89
100
  name: cucumber
90
101
  prerelease: false
91
102
  requirement: &id006 !ruby/object:Gem::Requirement
103
+ none: false
92
104
  requirements:
93
105
  - - ">="
94
106
  - !ruby/object:Gem::Version
107
+ hash: 3
95
108
  segments:
96
109
  - 0
97
110
  version: "0"
@@ -101,9 +114,11 @@ dependencies:
101
114
  name: will_paginate
102
115
  prerelease: false
103
116
  requirement: &id007 !ruby/object:Gem::Requirement
117
+ none: false
104
118
  requirements:
105
119
  - - "="
106
120
  - !ruby/object:Gem::Version
121
+ hash: 21
107
122
  segments:
108
123
  - 2
109
124
  - 3
@@ -115,9 +130,11 @@ dependencies:
115
130
  name: ginger
116
131
  prerelease: false
117
132
  requirement: &id008 !ruby/object:Gem::Requirement
133
+ none: false
118
134
  requirements:
119
135
  - - "="
120
136
  - !ruby/object:Gem::Version
137
+ hash: 31
121
138
  segments:
122
139
  - 1
123
140
  - 2
@@ -129,9 +146,11 @@ dependencies:
129
146
  name: faker
130
147
  prerelease: false
131
148
  requirement: &id009 !ruby/object:Gem::Requirement
149
+ none: false
132
150
  requirements:
133
151
  - - "="
134
152
  - !ruby/object:Gem::Version
153
+ hash: 17
135
154
  segments:
136
155
  - 0
137
156
  - 3
@@ -181,6 +200,7 @@ files:
181
200
  - lib/thinking_sphinx/index.rb
182
201
  - lib/thinking_sphinx/index/builder.rb
183
202
  - lib/thinking_sphinx/index/faux_column.rb
203
+ - lib/thinking_sphinx/join.rb
184
204
  - lib/thinking_sphinx/property.rb
185
205
  - lib/thinking_sphinx/rails_additions.rb
186
206
  - lib/thinking_sphinx/search.rb
@@ -194,6 +214,118 @@ files:
194
214
  - tasks/distribution.rb
195
215
  - tasks/rails.rake
196
216
  - tasks/testing.rb
217
+ - features/abstract_inheritance.feature
218
+ - features/alternate_primary_key.feature
219
+ - features/attribute_transformation.feature
220
+ - features/attribute_updates.feature
221
+ - features/deleting_instances.feature
222
+ - features/direct_attributes.feature
223
+ - features/excerpts.feature
224
+ - features/extensible_delta_indexing.feature
225
+ - features/facets.feature
226
+ - features/facets_across_model.feature
227
+ - features/handling_edits.feature
228
+ - features/retry_stale_indexes.feature
229
+ - features/searching_across_models.feature
230
+ - features/searching_by_index.feature
231
+ - features/searching_by_model.feature
232
+ - features/searching_with_find_arguments.feature
233
+ - features/sphinx_detection.feature
234
+ - features/sphinx_scopes.feature
235
+ - features/step_definitions/alpha_steps.rb
236
+ - features/step_definitions/beta_steps.rb
237
+ - features/step_definitions/common_steps.rb
238
+ - features/step_definitions/extensible_delta_indexing_steps.rb
239
+ - features/step_definitions/facet_steps.rb
240
+ - features/step_definitions/find_arguments_steps.rb
241
+ - features/step_definitions/gamma_steps.rb
242
+ - features/step_definitions/scope_steps.rb
243
+ - features/step_definitions/search_steps.rb
244
+ - features/step_definitions/sphinx_steps.rb
245
+ - features/sti_searching.feature
246
+ - features/support/env.rb
247
+ - features/support/lib/generic_delta_handler.rb
248
+ - features/thinking_sphinx/database.example.yml
249
+ - features/thinking_sphinx/database.yml
250
+ - features/thinking_sphinx/db/fixtures/alphas.rb
251
+ - features/thinking_sphinx/db/fixtures/authors.rb
252
+ - features/thinking_sphinx/db/fixtures/betas.rb
253
+ - features/thinking_sphinx/db/fixtures/boxes.rb
254
+ - features/thinking_sphinx/db/fixtures/categories.rb
255
+ - features/thinking_sphinx/db/fixtures/cats.rb
256
+ - features/thinking_sphinx/db/fixtures/comments.rb
257
+ - features/thinking_sphinx/db/fixtures/developers.rb
258
+ - features/thinking_sphinx/db/fixtures/dogs.rb
259
+ - features/thinking_sphinx/db/fixtures/extensible_betas.rb
260
+ - features/thinking_sphinx/db/fixtures/foxes.rb
261
+ - features/thinking_sphinx/db/fixtures/gammas.rb
262
+ - features/thinking_sphinx/db/fixtures/music.rb
263
+ - features/thinking_sphinx/db/fixtures/people.rb
264
+ - features/thinking_sphinx/db/fixtures/posts.rb
265
+ - features/thinking_sphinx/db/fixtures/robots.rb
266
+ - features/thinking_sphinx/db/fixtures/tags.rb
267
+ - features/thinking_sphinx/db/migrations/create_alphas.rb
268
+ - features/thinking_sphinx/db/migrations/create_animals.rb
269
+ - features/thinking_sphinx/db/migrations/create_authors.rb
270
+ - features/thinking_sphinx/db/migrations/create_authors_posts.rb
271
+ - features/thinking_sphinx/db/migrations/create_betas.rb
272
+ - features/thinking_sphinx/db/migrations/create_boxes.rb
273
+ - features/thinking_sphinx/db/migrations/create_categories.rb
274
+ - features/thinking_sphinx/db/migrations/create_comments.rb
275
+ - features/thinking_sphinx/db/migrations/create_developers.rb
276
+ - features/thinking_sphinx/db/migrations/create_extensible_betas.rb
277
+ - features/thinking_sphinx/db/migrations/create_gammas.rb
278
+ - features/thinking_sphinx/db/migrations/create_genres.rb
279
+ - features/thinking_sphinx/db/migrations/create_music.rb
280
+ - features/thinking_sphinx/db/migrations/create_people.rb
281
+ - features/thinking_sphinx/db/migrations/create_posts.rb
282
+ - features/thinking_sphinx/db/migrations/create_robots.rb
283
+ - features/thinking_sphinx/db/migrations/create_taggings.rb
284
+ - features/thinking_sphinx/db/migrations/create_tags.rb
285
+ - features/thinking_sphinx/models/alpha.rb
286
+ - features/thinking_sphinx/models/animal.rb
287
+ - features/thinking_sphinx/models/author.rb
288
+ - features/thinking_sphinx/models/beta.rb
289
+ - features/thinking_sphinx/models/box.rb
290
+ - features/thinking_sphinx/models/cat.rb
291
+ - features/thinking_sphinx/models/category.rb
292
+ - features/thinking_sphinx/models/comment.rb
293
+ - features/thinking_sphinx/models/developer.rb
294
+ - features/thinking_sphinx/models/dog.rb
295
+ - features/thinking_sphinx/models/extensible_beta.rb
296
+ - features/thinking_sphinx/models/fox.rb
297
+ - features/thinking_sphinx/models/gamma.rb
298
+ - features/thinking_sphinx/models/genre.rb
299
+ - features/thinking_sphinx/models/medium.rb
300
+ - features/thinking_sphinx/models/music.rb
301
+ - features/thinking_sphinx/models/person.rb
302
+ - features/thinking_sphinx/models/post.rb
303
+ - features/thinking_sphinx/models/robot.rb
304
+ - features/thinking_sphinx/models/tag.rb
305
+ - features/thinking_sphinx/models/tagging.rb
306
+ - spec/thinking_sphinx/active_record/delta_spec.rb
307
+ - spec/thinking_sphinx/active_record/has_many_association_spec.rb
308
+ - spec/thinking_sphinx/active_record/scopes_spec.rb
309
+ - spec/thinking_sphinx/active_record_spec.rb
310
+ - spec/thinking_sphinx/association_spec.rb
311
+ - spec/thinking_sphinx/attribute_spec.rb
312
+ - spec/thinking_sphinx/auto_version_spec.rb
313
+ - spec/thinking_sphinx/configuration_spec.rb
314
+ - spec/thinking_sphinx/context_spec.rb
315
+ - spec/thinking_sphinx/core/array_spec.rb
316
+ - spec/thinking_sphinx/core/string_spec.rb
317
+ - spec/thinking_sphinx/excerpter_spec.rb
318
+ - spec/thinking_sphinx/facet_search_spec.rb
319
+ - spec/thinking_sphinx/facet_spec.rb
320
+ - spec/thinking_sphinx/field_spec.rb
321
+ - spec/thinking_sphinx/index/builder_spec.rb
322
+ - spec/thinking_sphinx/index/faux_column_spec.rb
323
+ - spec/thinking_sphinx/index_spec.rb
324
+ - spec/thinking_sphinx/rails_additions_spec.rb
325
+ - spec/thinking_sphinx/search_methods_spec.rb
326
+ - spec/thinking_sphinx/search_spec.rb
327
+ - spec/thinking_sphinx/source_spec.rb
328
+ - spec/thinking_sphinx_spec.rb
197
329
  has_rdoc: true
198
330
  homepage: http://ts.freelancing-gods.com
199
331
  licenses: []
@@ -207,23 +339,27 @@ rdoc_options:
207
339
  require_paths:
208
340
  - lib
209
341
  required_ruby_version: !ruby/object:Gem::Requirement
342
+ none: false
210
343
  requirements:
211
344
  - - ">="
212
345
  - !ruby/object:Gem::Version
346
+ hash: 3
213
347
  segments:
214
348
  - 0
215
349
  version: "0"
216
350
  required_rubygems_version: !ruby/object:Gem::Requirement
351
+ none: false
217
352
  requirements:
218
353
  - - ">="
219
354
  - !ruby/object:Gem::Version
355
+ hash: 3
220
356
  segments:
221
357
  - 0
222
358
  version: "0"
223
359
  requirements: []
224
360
 
225
361
  rubyforge_project:
226
- rubygems_version: 1.3.6
362
+ rubygems_version: 1.3.7
227
363
  signing_key:
228
364
  specification_version: 3
229
365
  summary: ActiveRecord/Rails Sphinx library