thinking-sphinx 1.3.17 → 1.3.18

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 (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