thinking-sphinx 3.0.0.rc → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -4
- data/HISTORY +9 -0
- data/lib/thinking_sphinx.rb +1 -0
- data/lib/thinking_sphinx/active_record/index.rb +5 -0
- data/lib/thinking_sphinx/active_record/interpreter.rb +5 -0
- data/lib/thinking_sphinx/active_record/property.rb +2 -12
- data/lib/thinking_sphinx/active_record/sql_source.rb +3 -10
- data/lib/thinking_sphinx/active_record/sql_source/template.rb +4 -3
- data/lib/thinking_sphinx/configuration.rb +1 -1
- data/lib/thinking_sphinx/configuration/consistent_ids.rb +3 -1
- data/lib/thinking_sphinx/connection.rb +14 -0
- data/lib/thinking_sphinx/core.rb +1 -0
- data/lib/thinking_sphinx/core/index.rb +5 -9
- data/lib/thinking_sphinx/core/property.rb +13 -0
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +1 -1
- data/lib/thinking_sphinx/rake_interface.rb +28 -5
- data/lib/thinking_sphinx/real_time.rb +1 -0
- data/lib/thinking_sphinx/real_time/attribute.rb +10 -0
- data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +3 -14
- data/lib/thinking_sphinx/real_time/field.rb +3 -1
- data/lib/thinking_sphinx/real_time/index.rb +29 -2
- data/lib/thinking_sphinx/real_time/index/template.rb +6 -5
- data/lib/thinking_sphinx/real_time/interpreter.rb +4 -0
- data/lib/thinking_sphinx/real_time/property.rb +2 -0
- data/lib/thinking_sphinx/real_time/transcriber.rb +37 -0
- data/lib/thinking_sphinx/tasks.rb +6 -5
- data/spec/acceptance/facets_spec.rb +2 -1
- data/spec/acceptance/index_options_spec.rb +20 -0
- data/spec/acceptance/searching_within_a_model_spec.rb +0 -1
- data/spec/acceptance/support/sphinx_helpers.rb +3 -0
- data/spec/internal/app/indices/product_index.rb +3 -3
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +14 -9
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +1 -1
- data/spec/thinking_sphinx/real_time/attribute_spec.rb +2 -2
- data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +3 -2
- data/spec/thinking_sphinx/real_time/field_spec.rb +4 -4
- data/spec/thinking_sphinx/real_time/index_spec.rb +9 -4
- data/thinking-sphinx.gemspec +4 -3
- metadata +42 -7
data/Gemfile
CHANGED
data/HISTORY
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
2013-01-02: 3.0.0
|
2
|
+
* [CHANGE] Updating Riddle dependency to 1.5.4.
|
3
|
+
* [FIX] Respect source options as well as underlying settings via the set_property method in index definitions.
|
4
|
+
* [FIX] Load real-time index definitions when listing fields, attributes, and/or conditions.
|
5
|
+
* [CHANGE] UTF-8 is now the default charset again (as it was in earlier Thinking Sphinx versions).
|
6
|
+
* [FEATURE] Initial realtime index support, including the ts:generate task for building index datasets. Sphinx 2.0.6 is required.
|
7
|
+
* [CHANGE] Removing ts:version rake task.
|
8
|
+
* [FEATURE] SphinxQL connection pooling via the Innertube gem.
|
9
|
+
|
1
10
|
2012-12-22: 3.0.0.rc
|
2
11
|
* [FEATURE] Source type support (query and ranged query) for both attributes and fields. Custom SQL strings can be supplied as well.
|
3
12
|
* [FEATURE] Wordcount attributes and fields now supported.
|
data/lib/thinking_sphinx.rb
CHANGED
@@ -24,6 +24,11 @@ class ThinkingSphinx::ActiveRecord::Index < Riddle::Configuration::Index
|
|
24
24
|
@facets ||= sources.collect(&:facets).flatten
|
25
25
|
end
|
26
26
|
|
27
|
+
def sources
|
28
|
+
interpret_definition!
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
27
32
|
def unique_attribute_names
|
28
33
|
attributes.collect(&:name)
|
29
34
|
end
|
@@ -36,6 +36,7 @@ class ThinkingSphinx::ActiveRecord::Interpreter <
|
|
36
36
|
properties.each do |key, value|
|
37
37
|
@index.send("#{key}=", value) if @index.class.settings.include?(key)
|
38
38
|
__source.send("#{key}=", value) if __source.class.settings.include?(key)
|
39
|
+
__source.options[key] = value if source_option?(key)
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
@@ -53,4 +54,8 @@ class ThinkingSphinx::ActiveRecord::Interpreter <
|
|
53
54
|
options = columns.extract_options!
|
54
55
|
columns.collect { |column| klass.new(__source.model, column, options) }
|
55
56
|
end
|
57
|
+
|
58
|
+
def source_option?(key)
|
59
|
+
::ThinkingSphinx::ActiveRecord::SQLSource::OPTIONS.include?(key)
|
60
|
+
end
|
56
61
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
class ThinkingSphinx::ActiveRecord::Property
|
2
|
+
include ThinkingSphinx::Core::Property
|
3
|
+
|
2
4
|
attr_reader :columns, :options
|
3
5
|
|
4
6
|
def initialize(model, columns, options = {})
|
@@ -10,14 +12,6 @@ class ThinkingSphinx::ActiveRecord::Property
|
|
10
12
|
}
|
11
13
|
end
|
12
14
|
|
13
|
-
def facet?
|
14
|
-
options[:facet]
|
15
|
-
end
|
16
|
-
|
17
|
-
def multi?
|
18
|
-
false
|
19
|
-
end
|
20
|
-
|
21
15
|
def name
|
22
16
|
(options[:as] || columns.first.__name).to_s
|
23
17
|
end
|
@@ -25,8 +19,4 @@ class ThinkingSphinx::ActiveRecord::Property
|
|
25
19
|
def source_type
|
26
20
|
options[:source]
|
27
21
|
end
|
28
|
-
|
29
|
-
def type
|
30
|
-
nil
|
31
|
-
end
|
32
22
|
end
|
@@ -2,16 +2,9 @@ class ThinkingSphinx::ActiveRecord::SQLSource < Riddle::Configuration::SQLSource
|
|
2
2
|
attr_reader :model, :database_settings, :options
|
3
3
|
attr_accessor :fields, :attributes, :associations, :conditions, :groupings
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
# - :delta_processor
|
9
|
-
# - :delta?
|
10
|
-
# - :disable_range?
|
11
|
-
# - :group_concat_max_len
|
12
|
-
# - :utf8?
|
13
|
-
# - :position
|
14
|
-
#
|
5
|
+
OPTIONS = [:name, :offset, :delta_processor, :delta?, :disable_range?,
|
6
|
+
:group_concat_max_len, :utf8?, :position]
|
7
|
+
|
15
8
|
def initialize(model, options = {})
|
16
9
|
@model = model
|
17
10
|
@database_settings = model.connection.instance_variable_get(:@config).clone
|
@@ -6,10 +6,11 @@ class ThinkingSphinx::ActiveRecord::SQLSource::Template
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def apply
|
9
|
-
add_field class_column, :
|
9
|
+
add_field class_column, :sphinx_internal_class_name
|
10
10
|
|
11
|
-
add_attribute :id,
|
12
|
-
add_attribute
|
11
|
+
add_attribute :id, :sphinx_internal_id, nil
|
12
|
+
add_attribute class_column, :sphinx_internal_class, :string, :facet => true
|
13
|
+
add_attribute '0', :sphinx_deleted, :integer
|
13
14
|
end
|
14
15
|
|
15
16
|
private
|
@@ -25,7 +25,7 @@ class ThinkingSphinx::Configuration < Riddle::Configuration
|
|
25
25
|
searchd.address = Defaults::ADDRESS unless searchd.address.present?
|
26
26
|
searchd.mysql41 = settings['mysql41'] || settings['port'] ||
|
27
27
|
Defaults::PORT
|
28
|
-
|
28
|
+
searchd.workers = 'threads'
|
29
29
|
|
30
30
|
@offsets = {}
|
31
31
|
end
|
@@ -21,6 +21,13 @@ module ThinkingSphinx::Connection
|
|
21
21
|
ThinkingSphinx::Connection::MRI
|
22
22
|
end
|
23
23
|
|
24
|
+
def self.pool
|
25
|
+
@pool ||= Innertube::Pool.new(
|
26
|
+
Proc.new { ThinkingSphinx::Connection.new },
|
27
|
+
Proc.new { |connection| connection.close }
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
24
31
|
class MRI
|
25
32
|
attr_reader :client
|
26
33
|
|
@@ -32,8 +39,15 @@ module ThinkingSphinx::Connection
|
|
32
39
|
}.merge(options))
|
33
40
|
end
|
34
41
|
|
42
|
+
def close
|
43
|
+
client.close
|
44
|
+
end
|
45
|
+
|
35
46
|
def execute(statement)
|
36
47
|
client.query statement
|
48
|
+
rescue
|
49
|
+
puts "Error with statement: #{statement}"
|
50
|
+
raise
|
37
51
|
end
|
38
52
|
|
39
53
|
def query(statement)
|
data/lib/thinking_sphinx/core.rb
CHANGED
@@ -7,10 +7,11 @@ module ThinkingSphinx::Core::Index
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def initialize(reference, options = {})
|
10
|
-
@reference
|
11
|
-
@docinfo
|
12
|
-
@
|
13
|
-
@
|
10
|
+
@reference = reference.to_sym
|
11
|
+
@docinfo = :extern
|
12
|
+
@charset_type = 'utf-8'
|
13
|
+
@options = options
|
14
|
+
@offset = config.next_offset(reference)
|
14
15
|
|
15
16
|
super "#{options[:name] || reference.to_s.gsub('/', '_')}_#{name_suffix}"
|
16
17
|
end
|
@@ -47,11 +48,6 @@ module ThinkingSphinx::Core::Index
|
|
47
48
|
super
|
48
49
|
end
|
49
50
|
|
50
|
-
def sources
|
51
|
-
interpret_definition!
|
52
|
-
super
|
53
|
-
end
|
54
|
-
|
55
51
|
private
|
56
52
|
|
57
53
|
def config
|
@@ -69,7 +69,7 @@ class ThinkingSphinx::Middlewares::SphinxQL <
|
|
69
69
|
|
70
70
|
def extended_query
|
71
71
|
conditions = options[:conditions] || {}
|
72
|
-
conditions[:
|
72
|
+
conditions[:sphinx_internal_class_name] = class_condition if classes.any?
|
73
73
|
@extended_query ||= begin
|
74
74
|
ThinkingSphinx::Search::Query.new(context.search.query, conditions,
|
75
75
|
options[:star]).to_s
|
@@ -1,12 +1,35 @@
|
|
1
1
|
class ThinkingSphinx::RakeInterface
|
2
2
|
def configure
|
3
|
-
puts "Generating configuration to #{
|
4
|
-
|
3
|
+
puts "Generating configuration to #{configuration.configuration_file}"
|
4
|
+
configuration.render_to_file
|
5
|
+
end
|
6
|
+
|
7
|
+
def generate
|
8
|
+
configuration.preload_indices
|
9
|
+
configuration.render
|
10
|
+
|
11
|
+
FileUtils.mkdir_p configuration.indices_location
|
12
|
+
|
13
|
+
configuration.indices.each do |index|
|
14
|
+
next unless index.is_a?(ThinkingSphinx::RealTime::Index)
|
15
|
+
|
16
|
+
puts "Generating index files for #{index.name}"
|
17
|
+
transcriber = ThinkingSphinx::RealTime::Transcriber.new index
|
18
|
+
Dir["#{index.path}*"].each { |file| FileUtils.rm file }
|
19
|
+
|
20
|
+
index.model.find_each do |instance|
|
21
|
+
transcriber.copy instance
|
22
|
+
print "."
|
23
|
+
end
|
24
|
+
print "\n"
|
25
|
+
|
26
|
+
controller.rotate
|
27
|
+
end
|
5
28
|
end
|
6
29
|
|
7
30
|
def index(reconfigure = true)
|
8
31
|
configure if reconfigure
|
9
|
-
FileUtils.mkdir_p
|
32
|
+
FileUtils.mkdir_p configuration.indices_location
|
10
33
|
controller.index :verbose => true
|
11
34
|
end
|
12
35
|
|
@@ -37,11 +60,11 @@ class ThinkingSphinx::RakeInterface
|
|
37
60
|
|
38
61
|
private
|
39
62
|
|
40
|
-
def
|
63
|
+
def configuration
|
41
64
|
ThinkingSphinx::Configuration.instance
|
42
65
|
end
|
43
66
|
|
44
67
|
def controller
|
45
|
-
|
68
|
+
configuration.controller
|
46
69
|
end
|
47
70
|
end
|
@@ -7,5 +7,6 @@ require 'thinking_sphinx/real_time/attribute'
|
|
7
7
|
require 'thinking_sphinx/real_time/field'
|
8
8
|
require 'thinking_sphinx/real_time/index'
|
9
9
|
require 'thinking_sphinx/real_time/interpreter'
|
10
|
+
require 'thinking_sphinx/real_time/transcriber'
|
10
11
|
|
11
12
|
require 'thinking_sphinx/real_time/callbacks/real_time_callbacks'
|
@@ -7,29 +7,18 @@ class ThinkingSphinx::RealTime::Callbacks::RealTimeCallbacks <
|
|
7
7
|
return unless real_time_indices?
|
8
8
|
|
9
9
|
real_time_indices.each do |index|
|
10
|
-
|
11
|
-
(index.fields + index.attributes).each do |property|
|
12
|
-
columns << property.name
|
13
|
-
values << property.translate(instance)
|
14
|
-
end
|
15
|
-
|
16
|
-
sphinxql = Riddle::Query::Insert.new(index.name, columns, values).replace!
|
17
|
-
connection.execute sphinxql.to_sql
|
10
|
+
ThinkingSphinx::RealTime::Transcriber.new(index).copy instance
|
18
11
|
end
|
19
12
|
end
|
20
13
|
|
21
14
|
private
|
22
15
|
|
23
|
-
def
|
16
|
+
def configuration
|
24
17
|
ThinkingSphinx::Configuration.instance
|
25
18
|
end
|
26
19
|
|
27
|
-
def connection
|
28
|
-
connection = ThinkingSphinx::Connection.new
|
29
|
-
end
|
30
|
-
|
31
20
|
def indices
|
32
|
-
@indices ||=
|
21
|
+
@indices ||= configuration.indices_for_references reference
|
33
22
|
end
|
34
23
|
|
35
24
|
def real_time_indices?
|
@@ -1,17 +1,40 @@
|
|
1
1
|
class ThinkingSphinx::RealTime::Index < Riddle::Configuration::RealtimeIndex
|
2
2
|
include ThinkingSphinx::Core::Index
|
3
3
|
|
4
|
-
|
4
|
+
attr_writer :fields, :attributes, :conditions
|
5
5
|
|
6
6
|
def initialize(reference, options = {})
|
7
7
|
@fields = []
|
8
8
|
@attributes = []
|
9
|
+
@conditions = []
|
9
10
|
|
10
11
|
Template.new(self).apply
|
11
12
|
|
12
13
|
super reference, options
|
13
14
|
end
|
14
15
|
|
16
|
+
def attributes
|
17
|
+
interpret_definition!
|
18
|
+
|
19
|
+
@attributes
|
20
|
+
end
|
21
|
+
|
22
|
+
def conditions
|
23
|
+
interpret_definition!
|
24
|
+
|
25
|
+
@conditions
|
26
|
+
end
|
27
|
+
|
28
|
+
def facets
|
29
|
+
properties.select(&:facet?)
|
30
|
+
end
|
31
|
+
|
32
|
+
def fields
|
33
|
+
interpret_definition!
|
34
|
+
|
35
|
+
@fields
|
36
|
+
end
|
37
|
+
|
15
38
|
def unique_attribute_names
|
16
39
|
attributes.collect(&:name)
|
17
40
|
end
|
@@ -38,10 +61,14 @@ class ThinkingSphinx::RealTime::Index < Riddle::Configuration::RealtimeIndex
|
|
38
61
|
when :float
|
39
62
|
@rt_attr_float << attribute.name unless @rt_attr_float.include?(attribute.name)
|
40
63
|
else
|
41
|
-
raise "Unknown attribute type '#{attribute.type
|
64
|
+
raise "Unknown attribute type '#{attribute.type}'"
|
42
65
|
end
|
43
66
|
end
|
44
67
|
end
|
68
|
+
|
69
|
+
def properties
|
70
|
+
fields + attributes
|
71
|
+
end
|
45
72
|
end
|
46
73
|
|
47
74
|
require 'thinking_sphinx/real_time/index/template'
|
@@ -6,18 +6,19 @@ class ThinkingSphinx::RealTime::Index::Template
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def apply
|
9
|
-
add_field class_column, :
|
9
|
+
add_field class_column, :sphinx_internal_class_name
|
10
10
|
|
11
|
-
add_attribute :id,
|
12
|
-
add_attribute
|
11
|
+
add_attribute :id, :sphinx_internal_id, :integer
|
12
|
+
add_attribute class_column, :sphinx_internal_class, :string, :facet => true
|
13
|
+
add_attribute 0, :sphinx_deleted, :integer
|
13
14
|
end
|
14
15
|
|
15
16
|
private
|
16
17
|
|
17
|
-
def add_attribute(column, name, type)
|
18
|
+
def add_attribute(column, name, type, options = {})
|
18
19
|
index.attributes << ThinkingSphinx::RealTime::Attribute.new(
|
19
20
|
ThinkingSphinx::ActiveRecord::Column.new(*column),
|
20
|
-
:as => name, :type => type
|
21
|
+
options.merge(:as => name, :type => type)
|
21
22
|
)
|
22
23
|
end
|
23
24
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class ThinkingSphinx::RealTime::Transcriber
|
2
|
+
def initialize(index)
|
3
|
+
@index = index
|
4
|
+
end
|
5
|
+
|
6
|
+
def copy(instance)
|
7
|
+
return unless copy? instance
|
8
|
+
|
9
|
+
columns, values = ['id'], [index.document_id_for_key(instance.id)]
|
10
|
+
(index.fields + index.attributes).each do |property|
|
11
|
+
columns << property.name
|
12
|
+
values << property.translate(instance)
|
13
|
+
end
|
14
|
+
|
15
|
+
sphinxql = Riddle::Query::Insert.new index.name, columns, values
|
16
|
+
ThinkingSphinx::Connection.pool.take do |connection|
|
17
|
+
connection.execute sphinxql.replace!.to_sql
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :index
|
24
|
+
|
25
|
+
def copy?(instance)
|
26
|
+
index.conditions.empty? || index.conditions.all? { |condition|
|
27
|
+
case condition
|
28
|
+
when Symbol
|
29
|
+
instance.send(condition)
|
30
|
+
when Proc
|
31
|
+
condition.call instance
|
32
|
+
else
|
33
|
+
"Unexpected condition: #{condition}. Expecting Symbol or Proc."
|
34
|
+
end
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
@@ -1,9 +1,4 @@
|
|
1
1
|
namespace :ts do
|
2
|
-
desc 'The current version of Thinking Sphinx'
|
3
|
-
task :version do
|
4
|
-
puts "Thinking Sphinx v#{ThinkingSphinx::VERSION}"
|
5
|
-
end
|
6
|
-
|
7
2
|
desc 'Generate the Sphinx configuration file'
|
8
3
|
task :configure => :environment do
|
9
4
|
interface.configure
|
@@ -14,8 +9,14 @@ namespace :ts do
|
|
14
9
|
interface.index(ENV['INDEX_ONLY'] != 'true')
|
15
10
|
end
|
16
11
|
|
12
|
+
desc 'Generate fresh index files for real-time indices'
|
13
|
+
task :generate => :environment do
|
14
|
+
interface.generate
|
15
|
+
end
|
16
|
+
|
17
17
|
desc 'Stop Sphinx, index and then restart Sphinx'
|
18
18
|
task :rebuild => [:stop, :index, :start]
|
19
|
+
|
19
20
|
desc 'Restart the Sphinx daemon'
|
20
21
|
task :restart => [:stop, :start]
|
21
22
|
|
@@ -23,10 +23,11 @@ describe 'Faceted searching', :live => true do
|
|
23
23
|
Tee.create!
|
24
24
|
Tee.create!
|
25
25
|
City.create!
|
26
|
+
Product.create!
|
26
27
|
index
|
27
28
|
|
28
29
|
ThinkingSphinx.facets.to_hash[:class].should == {
|
29
|
-
'Tee' => 2, 'City' => 1
|
30
|
+
'Tee' => 2, 'City' => 1, 'Product' => 1
|
30
31
|
}
|
31
32
|
end
|
32
33
|
|
@@ -84,4 +84,24 @@ describe 'Index options' do
|
|
84
84
|
index.sources.first.sql_attr_str2wordcount.should == ['content']
|
85
85
|
end
|
86
86
|
end
|
87
|
+
|
88
|
+
context 'respecting source options' do
|
89
|
+
before :each do
|
90
|
+
index.definition_block = Proc.new {
|
91
|
+
indexes title
|
92
|
+
|
93
|
+
set_property :sql_range_step => 5
|
94
|
+
set_property :disable_range? => true
|
95
|
+
}
|
96
|
+
index.render
|
97
|
+
end
|
98
|
+
|
99
|
+
it "allows for core source settings" do
|
100
|
+
index.sources.first.sql_range_step.should == 5
|
101
|
+
end
|
102
|
+
|
103
|
+
it "allows for source options" do
|
104
|
+
index.sources.first.disable_range?.should be_true
|
105
|
+
end
|
106
|
+
end
|
87
107
|
end
|
@@ -51,7 +51,6 @@ end
|
|
51
51
|
|
52
52
|
describe 'Searching within a model with a realtime index', :live => true do
|
53
53
|
it "returns results" do
|
54
|
-
pending "Sphinx bug on OS X means I can't currently test this."
|
55
54
|
product = Product.create! :name => 'Widget'
|
56
55
|
|
57
56
|
Product.search.first.should == product
|
@@ -15,6 +15,9 @@ RSpec.configure do |config|
|
|
15
15
|
config.include SphinxHelpers
|
16
16
|
|
17
17
|
config.before :all do |group|
|
18
|
+
FileUtils.rm_rf ThinkingSphinx::Configuration.instance.indices_location
|
19
|
+
FileUtils.rm_rf ThinkingSphinx::Configuration.instance.searchd.binlog_path
|
20
|
+
|
18
21
|
sphinx.setup && sphinx.start if group.class.metadata[:live]
|
19
22
|
end
|
20
23
|
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
ThinkingSphinx::Index.define :product, :with => :real_time do
|
2
|
+
indexes name
|
3
|
+
end
|
@@ -32,9 +32,19 @@ describe ThinkingSphinx::ActiveRecord::SQLSource do
|
|
32
32
|
source.attributes.collect(&:name).should include('sphinx_internal_id')
|
33
33
|
end
|
34
34
|
|
35
|
+
it "has the class name attribute by default" do
|
36
|
+
source.attributes.collect(&:name).should include('sphinx_internal_class')
|
37
|
+
end
|
38
|
+
|
35
39
|
it "has the internal deleted attribute by default" do
|
36
40
|
source.attributes.collect(&:name).should include('sphinx_deleted')
|
37
41
|
end
|
42
|
+
|
43
|
+
it "marks the internal class attribute as a facet" do
|
44
|
+
source.attributes.detect { |attribute|
|
45
|
+
attribute.name == 'sphinx_internal_class'
|
46
|
+
}.options[:facet].should be_true
|
47
|
+
end
|
38
48
|
end
|
39
49
|
|
40
50
|
describe '#delta_processor' do
|
@@ -77,12 +87,13 @@ describe ThinkingSphinx::ActiveRecord::SQLSource do
|
|
77
87
|
|
78
88
|
describe '#fields' do
|
79
89
|
it "has the internal class field by default" do
|
80
|
-
source.fields.collect(&:name).
|
90
|
+
source.fields.collect(&:name).
|
91
|
+
should include('sphinx_internal_class_name')
|
81
92
|
end
|
82
93
|
|
83
94
|
it "sets the sphinx class field to use a string of the class name" do
|
84
95
|
source.fields.detect { |field|
|
85
|
-
field.name == '
|
96
|
+
field.name == 'sphinx_internal_class_name'
|
86
97
|
}.columns.first.__name.should == "'User'"
|
87
98
|
end
|
88
99
|
|
@@ -94,16 +105,10 @@ describe ThinkingSphinx::ActiveRecord::SQLSource do
|
|
94
105
|
model.stub :column_names => ['type'], :sti_name => 'User'
|
95
106
|
|
96
107
|
source.fields.detect { |field|
|
97
|
-
field.name == '
|
108
|
+
field.name == 'sphinx_internal_class_name'
|
98
109
|
}.columns.first.__name.
|
99
110
|
should == "ifnull(\"users\".\"type\", 'User')"
|
100
111
|
end
|
101
|
-
|
102
|
-
it "marks the internal class field as a facet" do
|
103
|
-
source.fields.detect { |field|
|
104
|
-
field.name == 'sphinx_internal_class'
|
105
|
-
}.options[:facet].should be_true
|
106
|
-
end
|
107
112
|
end
|
108
113
|
|
109
114
|
describe '#name' do
|
@@ -102,7 +102,7 @@ describe ThinkingSphinx::Middlewares::SphinxQL do
|
|
102
102
|
search.options[:classes] = [submodel]
|
103
103
|
|
104
104
|
ThinkingSphinx::Search::Query.should_receive(:new).with(anything,
|
105
|
-
hash_including(:
|
105
|
+
hash_including(:sphinx_internal_class_name => '(Lion)'), anything).
|
106
106
|
and_return(query)
|
107
107
|
|
108
108
|
middleware.call [context]
|
@@ -44,11 +44,11 @@ describe ThinkingSphinx::RealTime::Attribute do
|
|
44
44
|
attribute.translate(object).should == 'the parent name'
|
45
45
|
end
|
46
46
|
|
47
|
-
it "returns
|
47
|
+
it "returns zero if any element in the object tree is nil" do
|
48
48
|
column.stub :__name => :name, :__stack => [:parent]
|
49
49
|
object.parent = nil
|
50
50
|
|
51
|
-
attribute.translate(object).should
|
51
|
+
attribute.translate(object).should be_zero
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -7,12 +7,13 @@ describe ThinkingSphinx::RealTime::Callbacks::RealTimeCallbacks do
|
|
7
7
|
let(:instance) { double('instance', :id => 12) }
|
8
8
|
let(:config) { double('config', :indices_for_references => [index]) }
|
9
9
|
let(:index) { double('index', :name => 'my_index', :is_a? => true,
|
10
|
-
:document_id_for_key => 123, :fields => [], :attributes => []
|
10
|
+
:document_id_for_key => 123, :fields => [], :attributes => [],
|
11
|
+
:conditions => []) }
|
11
12
|
let(:connection) { double('connection', :execute => true) }
|
12
13
|
|
13
14
|
before :each do
|
14
15
|
ThinkingSphinx::Configuration.stub :instance => config
|
15
|
-
ThinkingSphinx::Connection.
|
16
|
+
ThinkingSphinx::Connection.stub_chain(:pool, :take).and_yield connection
|
16
17
|
end
|
17
18
|
|
18
19
|
describe '.after_save' do
|
@@ -26,10 +26,10 @@ describe ThinkingSphinx::RealTime::Field do
|
|
26
26
|
field.translate(object).should == 'value'
|
27
27
|
end
|
28
28
|
|
29
|
-
it "returns the column's name if it's an integer" do
|
29
|
+
it "returns the column's name as a string if it's an integer" do
|
30
30
|
column.stub :__name => 404
|
31
31
|
|
32
|
-
field.translate(object).should == 404
|
32
|
+
field.translate(object).should == '404'
|
33
33
|
end
|
34
34
|
|
35
35
|
it "returns the object's method matching the column's name" do
|
@@ -44,11 +44,11 @@ describe ThinkingSphinx::RealTime::Field do
|
|
44
44
|
field.translate(object).should == 'the parent name'
|
45
45
|
end
|
46
46
|
|
47
|
-
it "returns
|
47
|
+
it "returns a blank string if any element in the object tree is nil" do
|
48
48
|
column.stub :__name => :name, :__stack => [:parent]
|
49
49
|
object.parent = nil
|
50
50
|
|
51
|
-
field.translate(object).should
|
51
|
+
field.translate(object).should == ''
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -15,6 +15,10 @@ describe ThinkingSphinx::RealTime::Index do
|
|
15
15
|
index.attributes.collect(&:name).should include('sphinx_internal_id')
|
16
16
|
end
|
17
17
|
|
18
|
+
it "has the class name attribute by default" do
|
19
|
+
index.attributes.collect(&:name).should include('sphinx_internal_class')
|
20
|
+
end
|
21
|
+
|
18
22
|
it "has the internal deleted attribute by default" do
|
19
23
|
index.attributes.collect(&:name).should include('sphinx_deleted')
|
20
24
|
end
|
@@ -37,7 +41,7 @@ describe ThinkingSphinx::RealTime::Index do
|
|
37
41
|
|
38
42
|
describe '#fields' do
|
39
43
|
it "has the internal class field by default" do
|
40
|
-
index.fields.collect(&:name).should include('
|
44
|
+
index.fields.collect(&:name).should include('sphinx_internal_class_name')
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
@@ -135,7 +139,7 @@ describe ThinkingSphinx::RealTime::Index do
|
|
135
139
|
|
136
140
|
describe '#render' do
|
137
141
|
it "interprets the provided definition" do
|
138
|
-
index.should_receive(:interpret_definition!)
|
142
|
+
index.should_receive(:interpret_definition!).at_least(:once)
|
139
143
|
|
140
144
|
begin
|
141
145
|
index.render
|
@@ -147,8 +151,9 @@ describe ThinkingSphinx::RealTime::Index do
|
|
147
151
|
|
148
152
|
describe '#unique_attribute_names' do
|
149
153
|
it "returns all attribute names" do
|
150
|
-
index.unique_attribute_names.
|
151
|
-
|
154
|
+
index.unique_attribute_names.should == [
|
155
|
+
'sphinx_internal_id', 'sphinx_internal_class', 'sphinx_deleted'
|
156
|
+
]
|
152
157
|
end
|
153
158
|
end
|
154
159
|
end
|
data/thinking-sphinx.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'thinking-sphinx'
|
6
|
-
s.version = '3.0.0
|
6
|
+
s.version = '3.0.0'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Pat Allan"]
|
9
9
|
s.email = ["pat@freelancing-gods.com"]
|
@@ -23,10 +23,11 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_runtime_dependency 'activerecord', '>= 3.1.0'
|
24
24
|
s.add_runtime_dependency 'builder', '>= 2.1.2'
|
25
25
|
s.add_runtime_dependency 'middleware', '>= 0.1.0'
|
26
|
-
s.add_runtime_dependency '
|
26
|
+
s.add_runtime_dependency 'innertube', '>= 1.0.2'
|
27
|
+
s.add_runtime_dependency 'riddle', '>= 1.5.4'
|
27
28
|
|
28
29
|
s.add_development_dependency 'appraisal', '~> 0.4.0'
|
29
|
-
|
30
|
+
s.add_development_dependency 'combustion', '~> 0.3.3'
|
30
31
|
s.add_development_dependency 'database_cleaner', '~> 0.7.1'
|
31
32
|
s.add_development_dependency 'rspec', '~> 2.11.0'
|
32
33
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thinking-sphinx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0
|
5
|
-
prerelease:
|
4
|
+
version: 3.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Pat Allan
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -59,6 +59,22 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.1.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: innertube
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.0.2
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.0.2
|
62
78
|
- !ruby/object:Gem::Dependency
|
63
79
|
name: riddle
|
64
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +82,7 @@ dependencies:
|
|
66
82
|
requirements:
|
67
83
|
- - ! '>='
|
68
84
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.5.
|
85
|
+
version: 1.5.4
|
70
86
|
type: :runtime
|
71
87
|
prerelease: false
|
72
88
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +90,7 @@ dependencies:
|
|
74
90
|
requirements:
|
75
91
|
- - ! '>='
|
76
92
|
- !ruby/object:Gem::Version
|
77
|
-
version: 1.5.
|
93
|
+
version: 1.5.4
|
78
94
|
- !ruby/object:Gem::Dependency
|
79
95
|
name: appraisal
|
80
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,6 +107,22 @@ dependencies:
|
|
91
107
|
- - ~>
|
92
108
|
- !ruby/object:Gem::Version
|
93
109
|
version: 0.4.0
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: combustion
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.3.3
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.3.3
|
94
126
|
- !ruby/object:Gem::Dependency
|
95
127
|
name: database_cleaner
|
96
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -181,6 +213,7 @@ files:
|
|
181
213
|
- lib/thinking_sphinx/core/field.rb
|
182
214
|
- lib/thinking_sphinx/core/index.rb
|
183
215
|
- lib/thinking_sphinx/core/interpreter.rb
|
216
|
+
- lib/thinking_sphinx/core/property.rb
|
184
217
|
- lib/thinking_sphinx/deltas.rb
|
185
218
|
- lib/thinking_sphinx/deltas/default_delta.rb
|
186
219
|
- lib/thinking_sphinx/excerpter.rb
|
@@ -221,6 +254,7 @@ files:
|
|
221
254
|
- lib/thinking_sphinx/real_time/index/template.rb
|
222
255
|
- lib/thinking_sphinx/real_time/interpreter.rb
|
223
256
|
- lib/thinking_sphinx/real_time/property.rb
|
257
|
+
- lib/thinking_sphinx/real_time/transcriber.rb
|
224
258
|
- lib/thinking_sphinx/scopes.rb
|
225
259
|
- lib/thinking_sphinx/search.rb
|
226
260
|
- lib/thinking_sphinx/search/batch_inquirer.rb
|
@@ -358,9 +392,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
358
392
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
359
393
|
none: false
|
360
394
|
requirements:
|
361
|
-
- - ! '
|
395
|
+
- - ! '>='
|
362
396
|
- !ruby/object:Gem::Version
|
363
|
-
version:
|
397
|
+
version: '0'
|
364
398
|
requirements: []
|
365
399
|
rubyforge_project: thinking-sphinx
|
366
400
|
rubygems_version: 1.8.23
|
@@ -476,3 +510,4 @@ test_files:
|
|
476
510
|
- spec/thinking_sphinx/search/query_spec.rb
|
477
511
|
- spec/thinking_sphinx/search_spec.rb
|
478
512
|
- spec/thinking_sphinx_spec.rb
|
513
|
+
has_rdoc:
|