thinking-sphinx 3.0.2 → 3.0.3
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.
- data/Appraisals +1 -1
- data/HISTORY +17 -0
- data/README.textile +1 -1
- data/gemfiles/rails_4_0.gemfile +1 -1
- data/lib/thinking_sphinx.rb +6 -0
- data/lib/thinking_sphinx/active_record/association_proxy.rb +6 -0
- data/lib/thinking_sphinx/active_record/associations.rb +4 -1
- data/lib/thinking_sphinx/active_record/base.rb +6 -0
- data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +4 -0
- data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +9 -1
- data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +14 -1
- data/lib/thinking_sphinx/active_record/sql_source.rb +9 -5
- data/lib/thinking_sphinx/capistrano.rb +1 -0
- data/lib/thinking_sphinx/core/index.rb +7 -7
- data/lib/thinking_sphinx/deltas.rb +3 -1
- data/lib/thinking_sphinx/deltas/default_delta.rb +4 -7
- data/lib/thinking_sphinx/deltas/delete_job.rb +15 -0
- data/lib/thinking_sphinx/deltas/index_job.rb +16 -0
- data/lib/thinking_sphinx/errors.rb +3 -0
- data/lib/thinking_sphinx/excerpter.rb +8 -2
- data/lib/thinking_sphinx/masks/pagination_mask.rb +3 -8
- data/lib/thinking_sphinx/middlewares.rb +3 -0
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +0 -4
- data/lib/thinking_sphinx/middlewares/utf8.rb +23 -0
- data/lib/thinking_sphinx/rake_interface.rb +1 -0
- data/lib/thinking_sphinx/real_time/index.rb +8 -0
- data/lib/thinking_sphinx/real_time/index/template.rb +2 -2
- data/lib/thinking_sphinx/search.rb +8 -2
- data/lib/thinking_sphinx/search/context.rb +1 -1
- data/lib/thinking_sphinx/search/merger.rb +2 -0
- data/spec/acceptance/excerpts_spec.rb +13 -0
- data/spec/acceptance/facets_spec.rb +4 -1
- data/spec/acceptance/index_options_spec.rb +40 -0
- data/spec/acceptance/searching_within_a_model_spec.rb +18 -0
- data/spec/internal/app/models/city.rb +1 -0
- data/spec/internal/app/models/user.rb +4 -1
- data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +6 -0
- data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +14 -1
- data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +17 -2
- data/spec/thinking_sphinx/configuration_spec.rb +3 -0
- data/spec/thinking_sphinx/deltas/default_delta_spec.rb +3 -1
- data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +6 -6
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +0 -11
- data/spec/thinking_sphinx/rake_interface_spec.rb +10 -0
- data/thinking-sphinx.gemspec +2 -2
- metadata +48 -19
- checksums.yaml +0 -7
data/Appraisals
CHANGED
data/HISTORY
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
2013-05-07: 3.0.3
|
2
|
+
* [CHANGE] Updating Riddle dependency to be >= 1.5.6
|
3
|
+
* [FEATURE] INDEX_ONLY environment flag is passed through when invoked through Capistrano (Demian Ferreiro).
|
4
|
+
* [FEATURE] use_64_bit option returns as cast_to_timestamp instead (Denis Abushaev).
|
5
|
+
* [FIX] Update to association handling for Rails/ActiveRecord 4.0.0.rc1.
|
6
|
+
* [CHANGE] Delta jobs get common classes to allow third-party delta behaviours to leverage Thinking Sphinx.
|
7
|
+
* [FEATURE] Collection of hooks (lambdas) that get called before indexing. Useful for delta libraries.
|
8
|
+
* [FIX] Cast and concatenate multi-column attributes correctly.
|
9
|
+
* [FIX] Don't load fields or attributes when building a real-time index - otherwise the index is translated before it has a chance to be built.
|
10
|
+
* [CHANGE] Raise ThinkingSphinx::MixedScopesError if a search is called through an ActiveRecord scope.
|
11
|
+
* [FIX] Default search panes are cloned for each search.
|
12
|
+
* [FIX] Index-level settings (via set_property) are now applied consistently after global settings (in thinking_sphinx.yml).
|
13
|
+
* [FIX] All string values returned from Sphinx are now properly converted to UTF8.
|
14
|
+
* [CHANGE] GroupEnumeratorsMask is now a default mask, as masks need to be in place before search results are populated/the middleware is called (and previously it was being added within a middleware call).
|
15
|
+
* [FIX] The default search masks are now cloned for each search, instead of referring to the constant (and potentially modifying it often).
|
16
|
+
* [CHANGE] The current_page method is now a part of ThinkingSphinx::Search, as it is used when populating results.
|
17
|
+
|
1
18
|
2013-03-23: 3.0.2
|
2
19
|
* [CHANGE] per_page now accepts an optional paging limit, to match WillPaginate's behaviour. If none is supplied, it just returns the page size.
|
3
20
|
* [FEATURE] Ruby 2.0 support.
|
data/README.textile
CHANGED
@@ -75,7 +75,7 @@ end</code></pre>
|
|
75
75
|
:skip_sti => true,
|
76
76
|
:classes => [User, AdminUser, SupportUser]</code></pre>
|
77
77
|
|
78
|
-
* The option @:rank_mode@ has now become @:ranker@ - and the options (as strings or symbols) are as follows: proximity_bm25, bm25, none, wordcount, proximity, matchany, and
|
78
|
+
* The option @:rank_mode@ has now become @:ranker@ - and the options (as strings or symbols) are as follows: proximity_bm25, bm25, none, wordcount, proximity, matchany, fieldmask, sph04 and expr.
|
79
79
|
* There are no explicit sorting modes - all sorting must be on attributes followed by ASC or DESC. For example: <code>:order => '@weight DESC, created_at ASC'</code>.
|
80
80
|
* If you specify just an attribute name as a symbol for the @:order@ option, it will be given the ascending direction by default. So, @:order => :created_at@ is equivalent to @:order => 'created_at ASC'@.
|
81
81
|
* If you want to use a calculated expression for sorting, you must specify the expression as a new attribute, then use that attribute in your @:order@ option. This is done using the @:select@ option to specify extra columns available in the underlying SphinxQL (_not_ ActiveRecord/SQL) query.
|
data/gemfiles/rails_4_0.gemfile
CHANGED
@@ -6,6 +6,6 @@ gem "mysql2", "~> 0.3.12b4", :platform=>:ruby
|
|
6
6
|
gem "pg", "~> 0.11.0", :platform=>:ruby
|
7
7
|
gem "activerecord-jdbcmysql-adapter", "~> 1.1.3", :platform=>:jruby
|
8
8
|
gem "activerecord-jdbcpostgresql-adapter", "~> 1.1.3", :platform=>:jruby
|
9
|
-
gem "rails", "~> 4.0.0.
|
9
|
+
gem "rails", "~> 4.0.0.rc1"
|
10
10
|
|
11
11
|
gemspec :path=>"../"
|
data/lib/thinking_sphinx.rb
CHANGED
@@ -28,6 +28,12 @@ module ThinkingSphinx
|
|
28
28
|
search = ThinkingSphinx::Search.new query, options
|
29
29
|
ThinkingSphinx::Search::Merger.new(search).merge! nil, :ids_only => true
|
30
30
|
end
|
31
|
+
|
32
|
+
def self.before_index_hooks
|
33
|
+
@before_index_hooks
|
34
|
+
end
|
35
|
+
|
36
|
+
@before_index_hooks = []
|
31
37
|
end
|
32
38
|
|
33
39
|
# Core
|
@@ -2,11 +2,17 @@ module ThinkingSphinx::ActiveRecord::AssociationProxy
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
def search(query = nil, options = {})
|
5
|
+
query, options = nil, query if query.is_a?(Hash)
|
6
|
+
options[:ignore_scopes] = true
|
7
|
+
|
5
8
|
ThinkingSphinx::Search::Merger.new(super).merge! nil,
|
6
9
|
:with => association_filter
|
7
10
|
end
|
8
11
|
|
9
12
|
def search_for_ids(query = nil, options = {})
|
13
|
+
query, options = nil, query if query.is_a?(Hash)
|
14
|
+
options[:ignore_scopes] = true
|
15
|
+
|
10
16
|
ThinkingSphinx::Search::Merger.new(super).merge! nil,
|
11
17
|
:with => association_filter
|
12
18
|
end
|
@@ -75,7 +75,10 @@ class ThinkingSphinx::ActiveRecord::Associations
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def reflection_for(stack)
|
78
|
-
parent_for(stack)
|
78
|
+
parent = parent_for(stack)
|
79
|
+
klass = parent.respond_to?(:base_klass) ? parent.base_klass :
|
80
|
+
parent.active_record
|
81
|
+
klass.reflections[stack.last]
|
79
82
|
end
|
80
83
|
|
81
84
|
def rewrite_conditions_for(join)
|
@@ -24,6 +24,12 @@ module ThinkingSphinx::ActiveRecord::Base
|
|
24
24
|
|
25
25
|
merger.merge! *default_sphinx_scope_response if default_sphinx_scope?
|
26
26
|
merger.merge! query, options
|
27
|
+
|
28
|
+
if current_scope && !merger.search.options[:ignore_scopes]
|
29
|
+
raise ThinkingSphinx::MixedScopesError,
|
30
|
+
'You cannot search with Sphinx through ActiveRecord scopes'
|
31
|
+
end
|
32
|
+
|
27
33
|
merger.merge! nil, :classes => [self]
|
28
34
|
end
|
29
35
|
|
@@ -5,8 +5,16 @@ class ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter <
|
|
5
5
|
value ? 'TRUE' : 'FALSE'
|
6
6
|
end
|
7
7
|
|
8
|
+
def cast_to_string(clause)
|
9
|
+
"#{clause}::varchar"
|
10
|
+
end
|
11
|
+
|
8
12
|
def cast_to_timestamp(clause)
|
9
|
-
|
13
|
+
if ThinkingSphinx::Configuration.instance.settings['64bit_timestamps']
|
14
|
+
"extract(epoch from #{clause})::bigint"
|
15
|
+
else
|
16
|
+
"extract(epoch from #{clause})::int"
|
17
|
+
end
|
10
18
|
end
|
11
19
|
|
12
20
|
def concatenate(clause, separator = ' ')
|
@@ -30,7 +30,7 @@ class ThinkingSphinx::ActiveRecord::PropertySQLPresenter
|
|
30
30
|
def casted_column_with_table
|
31
31
|
clause = columns_with_table
|
32
32
|
clause = adapter.cast_to_timestamp(clause) if property.type == :timestamp
|
33
|
-
clause =
|
33
|
+
clause = concatenate clause
|
34
34
|
if aggregate?
|
35
35
|
clause = adapter.group_concatenate(clause, aggregate_separator)
|
36
36
|
end
|
@@ -60,6 +60,19 @@ class ThinkingSphinx::ActiveRecord::PropertySQLPresenter
|
|
60
60
|
property.columns.length > 1
|
61
61
|
end
|
62
62
|
|
63
|
+
def concatenate(clause)
|
64
|
+
return clause unless concatenating?
|
65
|
+
|
66
|
+
if property.type.nil?
|
67
|
+
adapter.concatenate clause, ' '
|
68
|
+
else
|
69
|
+
clause = clause.split(', ').collect { |part|
|
70
|
+
adapter.cast_to_string part
|
71
|
+
}.join(', ')
|
72
|
+
adapter.concatenate clause, ','
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
63
76
|
def group?
|
64
77
|
!(aggregate? || property.columns.any?(&:string?))
|
65
78
|
end
|
@@ -25,6 +25,8 @@ class ThinkingSphinx::ActiveRecord::SQLSource < Riddle::Configuration::SQLSource
|
|
25
25
|
name = "#{options[:name] || model.name.downcase}_#{options[:position]}"
|
26
26
|
|
27
27
|
super name, type
|
28
|
+
|
29
|
+
apply_defaults
|
28
30
|
end
|
29
31
|
|
30
32
|
def adapter
|
@@ -57,11 +59,6 @@ class ThinkingSphinx::ActiveRecord::SQLSource < Riddle::Configuration::SQLSource
|
|
57
59
|
end
|
58
60
|
|
59
61
|
def render
|
60
|
-
self.class.settings.each do |setting|
|
61
|
-
value = config.settings[setting.to_s]
|
62
|
-
send("#{setting}=", value) unless value.nil?
|
63
|
-
end
|
64
|
-
|
65
62
|
prepare_for_render unless @prepared
|
66
63
|
|
67
64
|
super
|
@@ -80,6 +77,13 @@ class ThinkingSphinx::ActiveRecord::SQLSource < Riddle::Configuration::SQLSource
|
|
80
77
|
|
81
78
|
private
|
82
79
|
|
80
|
+
def apply_defaults
|
81
|
+
self.class.settings.each do |setting|
|
82
|
+
value = config.settings[setting.to_s]
|
83
|
+
send("#{setting}=", value) unless value.nil?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
83
87
|
def attribute_array_for(type)
|
84
88
|
instance_variable_get "@sql_attr_#{type}".to_sym
|
85
89
|
end
|
@@ -56,6 +56,7 @@ if you alter the structure of your indexes.
|
|
56
56
|
def rake(tasks)
|
57
57
|
rails_env = fetch(:rails_env, 'production')
|
58
58
|
rake = fetch(:rake, 'rake')
|
59
|
+
tasks += ' INDEX_ONLY=true' if ENV['INDEX_ONLY'] == 'true'
|
59
60
|
|
60
61
|
run "if [ -d #{release_path} ]; then cd #{release_path}; else cd #{current_path}; fi; if [ -f Rakefile ]; then #{rake} RAILS_ENV=#{rails_env} #{tasks}; fi;"
|
61
62
|
end
|
@@ -25,10 +25,15 @@ module ThinkingSphinx::Core::Index
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def interpret_definition!
|
28
|
-
return if @interpreted_definition
|
28
|
+
return if @interpreted_definition
|
29
|
+
|
30
|
+
self.class.settings.each do |setting|
|
31
|
+
value = config.settings[setting.to_s]
|
32
|
+
send("#{setting}=", value) unless value.nil?
|
33
|
+
end
|
29
34
|
|
30
35
|
@interpreted_definition = true
|
31
|
-
interpreter.translate! self, @definition_block
|
36
|
+
interpreter.translate! self, @definition_block if @definition_block
|
32
37
|
end
|
33
38
|
|
34
39
|
def model
|
@@ -59,11 +64,6 @@ module ThinkingSphinx::Core::Index
|
|
59
64
|
end
|
60
65
|
|
61
66
|
def pre_render
|
62
|
-
self.class.settings.each do |setting|
|
63
|
-
value = config.settings[setting.to_s]
|
64
|
-
send("#{setting}=", value) unless value.nil?
|
65
|
-
end
|
66
|
-
|
67
67
|
interpret_definition!
|
68
68
|
end
|
69
69
|
end
|
@@ -2,7 +2,7 @@ module ThinkingSphinx::Deltas
|
|
2
2
|
def self.config
|
3
3
|
ThinkingSphinx::Configuration.instance
|
4
4
|
end
|
5
|
-
|
5
|
+
|
6
6
|
def self.processor_for(delta)
|
7
7
|
case delta
|
8
8
|
when TrueClass
|
@@ -40,3 +40,5 @@ module ThinkingSphinx::Deltas
|
|
40
40
|
end
|
41
41
|
|
42
42
|
require 'thinking_sphinx/deltas/default_delta'
|
43
|
+
require 'thinking_sphinx/deltas/delete_job'
|
44
|
+
require 'thinking_sphinx/deltas/index_job'
|
@@ -10,16 +10,13 @@ class ThinkingSphinx::Deltas::DefaultDelta
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def delete(index, instance)
|
13
|
-
ThinkingSphinx::
|
14
|
-
index.name, index.document_id_for_key(instance.id)
|
15
|
-
|
16
|
-
)
|
17
|
-
rescue Mysql2::Error => error
|
18
|
-
# This isn't vital, so don't raise the error.
|
13
|
+
ThinkingSphinx::Deltas::DeleteJob.new(
|
14
|
+
index.name, index.document_id_for_key(instance.id)
|
15
|
+
).perform
|
19
16
|
end
|
20
17
|
|
21
18
|
def index(index)
|
22
|
-
|
19
|
+
ThinkingSphinx::Deltas::IndexJob.new(index.name).perform
|
23
20
|
end
|
24
21
|
|
25
22
|
def reset_query
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ThinkingSphinx::Deltas::DeleteJob
|
2
|
+
def initialize(index_name, document_id)
|
3
|
+
@index_name, @document_id = index_name, document_id
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform
|
7
|
+
ThinkingSphinx::Connection.pool.take do |connection|
|
8
|
+
connection.execute Riddle::Query.update(
|
9
|
+
@index_name, @document_id, :sphinx_deleted => true
|
10
|
+
)
|
11
|
+
end
|
12
|
+
rescue Mysql2::Error => error
|
13
|
+
# This isn't vital, so don't raise the error.
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class ThinkingSphinx::Deltas::IndexJob
|
2
|
+
def initialize(index_name)
|
3
|
+
@index_name = index_name
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform
|
7
|
+
configuration.controller.index @index_name,
|
8
|
+
:verbose => !configuration.settings['quiet_deltas']
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def configuration
|
14
|
+
@configuration ||= ThinkingSphinx::Configuration.instance
|
15
|
+
end
|
16
|
+
end
|
@@ -13,8 +13,10 @@ class ThinkingSphinx::Excerpter
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def excerpt!(text)
|
16
|
-
connection.query(
|
17
|
-
|
16
|
+
result = connection.query(statement_for(text)).first['snippet']
|
17
|
+
|
18
|
+
result.encode!("ISO-8859-1")
|
19
|
+
result.force_encoding("UTF-8")
|
18
20
|
end
|
19
21
|
|
20
22
|
private
|
@@ -22,4 +24,8 @@ class ThinkingSphinx::Excerpter
|
|
22
24
|
def connection
|
23
25
|
@connection ||= ThinkingSphinx::Connection.new
|
24
26
|
end
|
27
|
+
|
28
|
+
def statement_for(text)
|
29
|
+
Riddle::Query.snippets(text, index, words, options)
|
30
|
+
end
|
25
31
|
end
|
@@ -7,13 +7,8 @@ class ThinkingSphinx::Masks::PaginationMask
|
|
7
7
|
public_methods(false).include?(method)
|
8
8
|
end
|
9
9
|
|
10
|
-
def current_page
|
11
|
-
search.options[:page] = 1 if search.options[:page].blank?
|
12
|
-
search.options[:page].to_i
|
13
|
-
end
|
14
|
-
|
15
10
|
def first_page?
|
16
|
-
current_page == 1
|
11
|
+
search.current_page == 1
|
17
12
|
end
|
18
13
|
|
19
14
|
def last_page?
|
@@ -21,7 +16,7 @@ class ThinkingSphinx::Masks::PaginationMask
|
|
21
16
|
end
|
22
17
|
|
23
18
|
def next_page
|
24
|
-
current_page >= total_pages ? nil : current_page + 1
|
19
|
+
search.current_page >= total_pages ? nil : search.current_page + 1
|
25
20
|
end
|
26
21
|
|
27
22
|
def next_page?
|
@@ -39,7 +34,7 @@ class ThinkingSphinx::Masks::PaginationMask
|
|
39
34
|
end
|
40
35
|
|
41
36
|
def previous_page
|
42
|
-
current_page == 1 ? nil : current_page - 1
|
37
|
+
search.current_page == 1 ? nil : search.current_page - 1
|
43
38
|
end
|
44
39
|
|
45
40
|
def total_entries
|
@@ -11,12 +11,14 @@ require 'thinking_sphinx/middlewares/inquirer'
|
|
11
11
|
require 'thinking_sphinx/middlewares/sphinxql'
|
12
12
|
require 'thinking_sphinx/middlewares/stale_id_checker'
|
13
13
|
require 'thinking_sphinx/middlewares/stale_id_filter'
|
14
|
+
require 'thinking_sphinx/middlewares/utf8'
|
14
15
|
|
15
16
|
ThinkingSphinx::Middlewares::DEFAULT = ::Middleware::Builder.new do
|
16
17
|
use ThinkingSphinx::Middlewares::StaleIdFilter
|
17
18
|
use ThinkingSphinx::Middlewares::SphinxQL
|
18
19
|
use ThinkingSphinx::Middlewares::Geographer
|
19
20
|
use ThinkingSphinx::Middlewares::Inquirer
|
21
|
+
use ThinkingSphinx::Middlewares::UTF8
|
20
22
|
use ThinkingSphinx::Middlewares::ActiveRecordTranslator
|
21
23
|
use ThinkingSphinx::Middlewares::StaleIdChecker
|
22
24
|
use ThinkingSphinx::Middlewares::Glazier
|
@@ -26,6 +28,7 @@ ThinkingSphinx::Middlewares::RAW_ONLY = ::Middleware::Builder.new do
|
|
26
28
|
use ThinkingSphinx::Middlewares::SphinxQL
|
27
29
|
use ThinkingSphinx::Middlewares::Geographer
|
28
30
|
use ThinkingSphinx::Middlewares::Inquirer
|
31
|
+
use ThinkingSphinx::Middlewares::UTF8
|
29
32
|
end
|
30
33
|
|
31
34
|
ThinkingSphinx::Middlewares::IDS_ONLY = ::Middleware::Builder.new do
|
@@ -23,10 +23,6 @@ class ThinkingSphinx::Middlewares::SphinxQL <
|
|
23
23
|
def call
|
24
24
|
context[:indices] = indices
|
25
25
|
context[:sphinxql] = statement
|
26
|
-
|
27
|
-
if group_attribute.present?
|
28
|
-
context.search.masks << ThinkingSphinx::Masks::GroupEnumeratorsMask
|
29
|
-
end
|
30
26
|
end
|
31
27
|
|
32
28
|
private
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ThinkingSphinx::Middlewares::UTF8 <
|
2
|
+
ThinkingSphinx::Middlewares::Middleware
|
3
|
+
|
4
|
+
def call(contexts)
|
5
|
+
contexts.each do |context|
|
6
|
+
context[:results].each { |row| update_row row }
|
7
|
+
update_row context[:meta]
|
8
|
+
end
|
9
|
+
|
10
|
+
app.call contexts
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def update_row(row)
|
16
|
+
row.each do |key, value|
|
17
|
+
next unless value.is_a?(String)
|
18
|
+
|
19
|
+
value.encode!("ISO-8859-1")
|
20
|
+
row[key] = value.force_encoding("UTF-8")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -13,6 +13,14 @@ class ThinkingSphinx::RealTime::Index < Riddle::Configuration::RealtimeIndex
|
|
13
13
|
super reference, options
|
14
14
|
end
|
15
15
|
|
16
|
+
def add_attribute(attribute)
|
17
|
+
@attributes << attribute
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_field(field)
|
21
|
+
@fields << field
|
22
|
+
end
|
23
|
+
|
16
24
|
def attributes
|
17
25
|
interpret_definition!
|
18
26
|
|
@@ -16,14 +16,14 @@ class ThinkingSphinx::RealTime::Index::Template
|
|
16
16
|
private
|
17
17
|
|
18
18
|
def add_attribute(column, name, type, options = {})
|
19
|
-
index.
|
19
|
+
index.add_attribute ThinkingSphinx::RealTime::Attribute.new(
|
20
20
|
ThinkingSphinx::ActiveRecord::Column.new(*column),
|
21
21
|
options.merge(:as => name, :type => type)
|
22
22
|
)
|
23
23
|
end
|
24
24
|
|
25
25
|
def add_field(column, name)
|
26
|
-
index.
|
26
|
+
index.add_field ThinkingSphinx::RealTime::Field.new(
|
27
27
|
ThinkingSphinx::ActiveRecord::Column.new(*column), :as => name
|
28
28
|
)
|
29
29
|
end
|
@@ -8,7 +8,8 @@ class ThinkingSphinx::Search < Array
|
|
8
8
|
send class )
|
9
9
|
DEFAULT_MASKS = [
|
10
10
|
ThinkingSphinx::Masks::PaginationMask,
|
11
|
-
ThinkingSphinx::Masks::ScopesMask
|
11
|
+
ThinkingSphinx::Masks::ScopesMask,
|
12
|
+
ThinkingSphinx::Masks::GroupEnumeratorsMask
|
12
13
|
]
|
13
14
|
|
14
15
|
instance_methods.select { |method|
|
@@ -23,7 +24,7 @@ class ThinkingSphinx::Search < Array
|
|
23
24
|
def initialize(query = nil, options = {})
|
24
25
|
query, options = nil, query if query.is_a?(Hash)
|
25
26
|
@query, @options = query, options
|
26
|
-
@masks = @options.delete(:masks) || DEFAULT_MASKS
|
27
|
+
@masks = @options.delete(:masks) || DEFAULT_MASKS.clone
|
27
28
|
@middleware = @options.delete(:middleware)
|
28
29
|
|
29
30
|
populate if options[:populate]
|
@@ -34,6 +35,11 @@ class ThinkingSphinx::Search < Array
|
|
34
35
|
ThinkingSphinx::Configuration.instance
|
35
36
|
end
|
36
37
|
|
38
|
+
def current_page
|
39
|
+
options[:page] = 1 if options[:page].blank?
|
40
|
+
options[:page].to_i
|
41
|
+
end
|
42
|
+
|
37
43
|
def meta
|
38
44
|
populate
|
39
45
|
context[:meta]
|
@@ -6,7 +6,7 @@ class ThinkingSphinx::Search::Context
|
|
6
6
|
@configuration = configuration || ThinkingSphinx::Configuration.instance
|
7
7
|
@memory = {
|
8
8
|
:results => [],
|
9
|
-
:panes => ThinkingSphinx::Configuration::Defaults::PANES
|
9
|
+
:panes => ThinkingSphinx::Configuration::Defaults::PANES.clone
|
10
10
|
}
|
11
11
|
end
|
12
12
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'acceptance/spec_helper'
|
2
4
|
|
3
5
|
describe 'Accessing excerpts for methods on a search result', :live => true do
|
@@ -11,4 +13,15 @@ describe 'Accessing excerpts for methods on a search result', :live => true do
|
|
11
13
|
search.first.excerpts.title.
|
12
14
|
should == 'American <span class="match">Gods</span>'
|
13
15
|
end
|
16
|
+
|
17
|
+
it "handles UTF-8 text for excerpts" do
|
18
|
+
Book.create! :title => 'Война и миръ', :year => 1869
|
19
|
+
index
|
20
|
+
|
21
|
+
search = Book.search 'миръ'
|
22
|
+
search.context[:panes] << ThinkingSphinx::Panes::ExcerptsPane
|
23
|
+
|
24
|
+
search.first.excerpts.title.
|
25
|
+
should == 'Война и <span class="match">миръ</span>'
|
26
|
+
end
|
14
27
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'acceptance/spec_helper'
|
2
4
|
|
3
5
|
describe 'Faceted searching', :live => true do
|
@@ -35,10 +37,11 @@ describe 'Faceted searching', :live => true do
|
|
35
37
|
Book.create! :title => 'American Gods', :author => 'Neil Gaiman'
|
36
38
|
Book.create! :title => 'Anansi Boys', :author => 'Neil Gaiman'
|
37
39
|
Book.create! :title => 'Snuff', :author => 'Terry Pratchett'
|
40
|
+
Book.create! :title => '1Q84', :author => '村上 春樹'
|
38
41
|
index
|
39
42
|
|
40
43
|
Book.facets.to_hash[:author].should == {
|
41
|
-
'Neil Gaiman' => 2, 'Terry Pratchett' => 1
|
44
|
+
'Neil Gaiman' => 2, 'Terry Pratchett' => 1, '村上 春樹' => 1
|
42
45
|
}
|
43
46
|
end
|
44
47
|
|
@@ -109,4 +109,44 @@ describe 'Index options' do
|
|
109
109
|
index.sources.first.sql_query_pre.should == ["DO STUFF"]
|
110
110
|
end
|
111
111
|
end
|
112
|
+
|
113
|
+
context 'respecting index options over core configuration' do
|
114
|
+
before :each do
|
115
|
+
ThinkingSphinx::Configuration.instance.settings['min_infix_len'] = 2
|
116
|
+
ThinkingSphinx::Configuration.instance.settings['sql_range_step'] = 2
|
117
|
+
|
118
|
+
index.definition_block = Proc.new {
|
119
|
+
indexes title
|
120
|
+
|
121
|
+
set_property :min_infix_len => 1
|
122
|
+
set_property :sql_range_step => 20
|
123
|
+
}
|
124
|
+
index.render
|
125
|
+
end
|
126
|
+
|
127
|
+
after :each do
|
128
|
+
ThinkingSphinx::Configuration.instance.settings.delete 'min_infix_len'
|
129
|
+
ThinkingSphinx::Configuration.instance.settings.delete 'sql_range_step'
|
130
|
+
end
|
131
|
+
|
132
|
+
it "prioritises index-level options over YAML options" do
|
133
|
+
index.min_infix_len.should == 1
|
134
|
+
end
|
135
|
+
|
136
|
+
it "prioritises index-level source options" do
|
137
|
+
index.sources.first.sql_range_step.should == 20
|
138
|
+
end
|
139
|
+
|
140
|
+
it "keeps index-level options prioritised when rendered again" do
|
141
|
+
index.render
|
142
|
+
|
143
|
+
index.min_infix_len.should == 1
|
144
|
+
end
|
145
|
+
|
146
|
+
it "keeps index-level options prioritised when rendered again" do
|
147
|
+
index.render
|
148
|
+
|
149
|
+
index.sources.first.sql_range_step.should == 20
|
150
|
+
end
|
151
|
+
end
|
112
152
|
end
|
@@ -47,6 +47,24 @@ describe 'Searching within a model', :live => true do
|
|
47
47
|
|
48
48
|
Admin::Person.search('Bond').to_a.should == [person]
|
49
49
|
end
|
50
|
+
|
51
|
+
it "raises an error if searching through an ActiveRecord scope" do
|
52
|
+
lambda {
|
53
|
+
City.ordered.search
|
54
|
+
}.should raise_error(ThinkingSphinx::MixedScopesError)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "does not raise an error when searching with a default ActiveRecord scope" do
|
58
|
+
lambda {
|
59
|
+
User.search
|
60
|
+
}.should_not raise_error(ThinkingSphinx::MixedScopesError)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "raises an error when searching with default and applied AR scopes" do
|
64
|
+
lambda {
|
65
|
+
User.recent.search
|
66
|
+
}.should raise_error(ThinkingSphinx::MixedScopesError)
|
67
|
+
end
|
50
68
|
end
|
51
69
|
|
52
70
|
describe 'Searching within a model with a realtime index', :live => true do
|
@@ -14,6 +14,12 @@ describe ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter do
|
|
14
14
|
adapter.boolean_value(false).should == 0
|
15
15
|
end
|
16
16
|
|
17
|
+
describe '#cast_to_string' do
|
18
|
+
it "casts the clause to characters" do
|
19
|
+
adapter.cast_to_string('foo').should == "CAST(foo AS char)"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
17
23
|
describe '#cast_to_timestamp' do
|
18
24
|
it "converts to unix timestamps" do
|
19
25
|
adapter.cast_to_timestamp('created_at').
|
@@ -16,11 +16,24 @@ describe ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
describe '#cast_to_string' do
|
20
|
+
it "casts the clause to characters" do
|
21
|
+
adapter.cast_to_string('foo').should == 'foo::varchar'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
19
25
|
describe '#cast_to_timestamp' do
|
20
|
-
it "converts to unix timestamps" do
|
26
|
+
it "converts to int unix timestamps" do
|
21
27
|
adapter.cast_to_timestamp('created_at').
|
22
28
|
should == 'extract(epoch from created_at)::int'
|
23
29
|
end
|
30
|
+
|
31
|
+
it "converts to bigint unix timestamps" do
|
32
|
+
ThinkingSphinx::Configuration.instance.settings['64bit_timestamps'] = true
|
33
|
+
|
34
|
+
adapter.cast_to_timestamp('created_at').
|
35
|
+
should == 'extract(epoch from created_at)::bigint'
|
36
|
+
end
|
24
37
|
end
|
25
38
|
|
26
39
|
describe '#concatenate' do
|
@@ -174,12 +174,27 @@ describe ThinkingSphinx::ActiveRecord::PropertySQLPresenter do
|
|
174
174
|
adapter.stub :concatenate do |clause, separator|
|
175
175
|
"CONCAT_WS('#{separator}', #{clause})"
|
176
176
|
end
|
177
|
+
adapter.stub :cast_to_string do |clause|
|
178
|
+
"CAST(#{clause} AS varchar)"
|
179
|
+
end
|
177
180
|
|
178
181
|
attribute.stub!(:columns => [column, double('column',
|
179
182
|
:string? => false, :__stack => [], :__name => 'updated_at')])
|
180
183
|
|
181
|
-
presenter.to_select.
|
182
|
-
|
184
|
+
presenter.to_select.should == "CONCAT_WS(',', CAST(articles.created_at AS varchar)) AS created_at"
|
185
|
+
end
|
186
|
+
|
187
|
+
it "casts and concatenates multiple columns for attributes" do
|
188
|
+
adapter.stub :concatenate do |clause, separator|
|
189
|
+
"CONCAT_WS('#{separator}', #{clause})"
|
190
|
+
end
|
191
|
+
adapter.stub :cast_to_string do |clause|
|
192
|
+
"CAST(#{clause} AS varchar)"
|
193
|
+
end
|
194
|
+
|
195
|
+
attribute.stub!(:columns => [column, column])
|
196
|
+
|
197
|
+
presenter.to_select.should == "CONCAT_WS(',', CAST(articles.created_at AS varchar), CAST(articles.created_at AS varchar)) AS created_at"
|
183
198
|
end
|
184
199
|
end
|
185
200
|
end
|
@@ -82,6 +82,9 @@ describe ThinkingSphinx::Configuration do
|
|
82
82
|
|
83
83
|
describe '#indices_for_references' do
|
84
84
|
it "selects from the full index set those with matching references" do
|
85
|
+
config.preload_indices
|
86
|
+
config.indices.clear
|
87
|
+
|
85
88
|
config.indices << double('index', :reference => :article)
|
86
89
|
config.indices << double('index', :reference => :book)
|
87
90
|
config.indices << double('index', :reference => :page)
|
@@ -23,10 +23,12 @@ describe ThinkingSphinx::Deltas::DefaultDelta do
|
|
23
23
|
let(:index) { double('index', :name => 'foo_core',
|
24
24
|
:document_id_for_key => 14) }
|
25
25
|
let(:instance) { double('instance', :id => 7) }
|
26
|
+
let(:pool) { double }
|
26
27
|
|
27
28
|
before :each do
|
28
|
-
ThinkingSphinx::Connection.stub :
|
29
|
+
ThinkingSphinx::Connection.stub :pool => pool
|
29
30
|
Riddle::Query.stub :update => 'UPDATE STATEMENT'
|
31
|
+
pool.stub(:take).and_yield(connection)
|
30
32
|
end
|
31
33
|
|
32
34
|
it "updates the deleted flag to false" do
|
@@ -7,7 +7,7 @@ require 'thinking_sphinx/masks/pagination_mask'
|
|
7
7
|
|
8
8
|
describe ThinkingSphinx::Masks::PaginationMask do
|
9
9
|
let(:search) { double('search', :options => {}, :meta => {},
|
10
|
-
:per_page => 20) }
|
10
|
+
:per_page => 20, :current_page => 1) }
|
11
11
|
let(:mask) { ThinkingSphinx::Masks::PaginationMask.new search }
|
12
12
|
|
13
13
|
describe '#first_page?' do
|
@@ -16,7 +16,7 @@ describe ThinkingSphinx::Masks::PaginationMask do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "returns false on other pages" do
|
19
|
-
search.
|
19
|
+
search.stub :current_page => 2
|
20
20
|
|
21
21
|
mask.should_not be_first_page
|
22
22
|
end
|
@@ -28,7 +28,7 @@ describe ThinkingSphinx::Masks::PaginationMask do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "is true when there's no more pages" do
|
31
|
-
search.
|
31
|
+
search.stub :current_page => 3
|
32
32
|
|
33
33
|
mask.should be_last_page
|
34
34
|
end
|
@@ -48,7 +48,7 @@ describe ThinkingSphinx::Masks::PaginationMask do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "should return nil if on the last page" do
|
51
|
-
search.
|
51
|
+
search.stub :current_page => 3
|
52
52
|
|
53
53
|
mask.next_page.should be_nil
|
54
54
|
end
|
@@ -64,7 +64,7 @@ describe ThinkingSphinx::Masks::PaginationMask do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it "is false when there's no more pages" do
|
67
|
-
search.
|
67
|
+
search.stub :current_page => 3
|
68
68
|
|
69
69
|
mask.next_page?.should be_false
|
70
70
|
end
|
@@ -76,7 +76,7 @@ describe ThinkingSphinx::Masks::PaginationMask do
|
|
76
76
|
end
|
77
77
|
|
78
78
|
it "should return one less than the current page" do
|
79
|
-
search.
|
79
|
+
search.stub :current_page => 2
|
80
80
|
|
81
81
|
mask.previous_page.should == 1
|
82
82
|
end
|
@@ -26,7 +26,6 @@ describe ThinkingSphinx::Middlewares::SphinxQL do
|
|
26
26
|
before :each do
|
27
27
|
stub_const 'Riddle::Query::Select', double(:new => sphinx_sql)
|
28
28
|
stub_const 'ThinkingSphinx::Search::Query', double(:new => query)
|
29
|
-
stub_const 'ThinkingSphinx::Masks::GroupEnumeratorsMask', double
|
30
29
|
stub_const 'ThinkingSphinx::IndexSet', double(:new => index_set)
|
31
30
|
|
32
31
|
context.stub :search => search, :configuration => configuration
|
@@ -228,16 +227,6 @@ describe ThinkingSphinx::Middlewares::SphinxQL do
|
|
228
227
|
middleware.call [context]
|
229
228
|
end
|
230
229
|
|
231
|
-
it "adds the group enumerator mask when using :group_by" do
|
232
|
-
search.options[:group_by] = :foreign_id
|
233
|
-
search.stub :masks => []
|
234
|
-
sphinx_sql.stub :group_by => sphinx_sql, :values => sphinx_sql
|
235
|
-
|
236
|
-
middleware.call [context]
|
237
|
-
|
238
|
-
search.masks.should include(ThinkingSphinx::Masks::GroupEnumeratorsMask)
|
239
|
-
end
|
240
|
-
|
241
230
|
it "appends a sort within group clause to the query" do
|
242
231
|
search.options[:order_group_by] = :title
|
243
232
|
|
@@ -37,6 +37,7 @@ describe ThinkingSphinx::RakeInterface do
|
|
37
37
|
let(:controller) { double('controller', :index => true) }
|
38
38
|
|
39
39
|
before :each do
|
40
|
+
ThinkingSphinx.stub :before_index_hooks => []
|
40
41
|
configuration.stub(
|
41
42
|
:configuration_file => '/path/to/foo.conf',
|
42
43
|
:render_to_file => true,
|
@@ -64,6 +65,15 @@ describe ThinkingSphinx::RakeInterface do
|
|
64
65
|
interface.index
|
65
66
|
end
|
66
67
|
|
68
|
+
it "calls all registered hooks" do
|
69
|
+
called = false
|
70
|
+
ThinkingSphinx.before_index_hooks << Proc.new { called = true }
|
71
|
+
|
72
|
+
interface.index
|
73
|
+
|
74
|
+
called.should be_true
|
75
|
+
end
|
76
|
+
|
67
77
|
it "indexes all indices verbosely" do
|
68
78
|
controller.should_receive(:index).with(:verbose => true)
|
69
79
|
|
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.
|
6
|
+
s.version = '3.0.3'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Pat Allan"]
|
9
9
|
s.email = ["pat@freelancing-gods.com"]
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.add_runtime_dependency 'builder', '>= 2.1.2'
|
25
25
|
s.add_runtime_dependency 'middleware', '>= 0.1.0'
|
26
26
|
s.add_runtime_dependency 'innertube', '>= 1.0.2'
|
27
|
-
s.add_runtime_dependency 'riddle', '>= 1.5.
|
27
|
+
s.add_runtime_dependency 'riddle', '>= 1.5.6'
|
28
28
|
|
29
29
|
s.add_development_dependency 'appraisal', '~> 0.4.0'
|
30
30
|
s.add_development_dependency 'combustion', '~> 0.4.0'
|
metadata
CHANGED
@@ -1,88 +1,100 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thinking-sphinx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Pat Allan
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
+
date: 2013-05-08 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: activerecord
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- - '>='
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: 3.1.0
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- - '>='
|
27
|
+
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: 3.1.0
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: builder
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
|
-
- - '>='
|
35
|
+
- - ! '>='
|
32
36
|
- !ruby/object:Gem::Version
|
33
37
|
version: 2.1.2
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
|
-
- - '>='
|
43
|
+
- - ! '>='
|
39
44
|
- !ruby/object:Gem::Version
|
40
45
|
version: 2.1.2
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: middleware
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
|
-
- - '>='
|
51
|
+
- - ! '>='
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: 0.1.0
|
48
54
|
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
|
-
- - '>='
|
59
|
+
- - ! '>='
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: 0.1.0
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: innertube
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
|
-
- - '>='
|
67
|
+
- - ! '>='
|
60
68
|
- !ruby/object:Gem::Version
|
61
69
|
version: 1.0.2
|
62
70
|
type: :runtime
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
|
-
- - '>='
|
75
|
+
- - ! '>='
|
67
76
|
- !ruby/object:Gem::Version
|
68
77
|
version: 1.0.2
|
69
78
|
- !ruby/object:Gem::Dependency
|
70
79
|
name: riddle
|
71
80
|
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
72
82
|
requirements:
|
73
|
-
- - '>='
|
83
|
+
- - ! '>='
|
74
84
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.5.
|
85
|
+
version: 1.5.6
|
76
86
|
type: :runtime
|
77
87
|
prerelease: false
|
78
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
79
90
|
requirements:
|
80
|
-
- - '>='
|
91
|
+
- - ! '>='
|
81
92
|
- !ruby/object:Gem::Version
|
82
|
-
version: 1.5.
|
93
|
+
version: 1.5.6
|
83
94
|
- !ruby/object:Gem::Dependency
|
84
95
|
name: appraisal
|
85
96
|
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
86
98
|
requirements:
|
87
99
|
- - ~>
|
88
100
|
- !ruby/object:Gem::Version
|
@@ -90,6 +102,7 @@ dependencies:
|
|
90
102
|
type: :development
|
91
103
|
prerelease: false
|
92
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
93
106
|
requirements:
|
94
107
|
- - ~>
|
95
108
|
- !ruby/object:Gem::Version
|
@@ -97,6 +110,7 @@ dependencies:
|
|
97
110
|
- !ruby/object:Gem::Dependency
|
98
111
|
name: combustion
|
99
112
|
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
100
114
|
requirements:
|
101
115
|
- - ~>
|
102
116
|
- !ruby/object:Gem::Version
|
@@ -104,6 +118,7 @@ dependencies:
|
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
107
122
|
requirements:
|
108
123
|
- - ~>
|
109
124
|
- !ruby/object:Gem::Version
|
@@ -111,6 +126,7 @@ dependencies:
|
|
111
126
|
- !ruby/object:Gem::Dependency
|
112
127
|
name: database_cleaner
|
113
128
|
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
114
130
|
requirements:
|
115
131
|
- - ~>
|
116
132
|
- !ruby/object:Gem::Version
|
@@ -118,6 +134,7 @@ dependencies:
|
|
118
134
|
type: :development
|
119
135
|
prerelease: false
|
120
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
121
138
|
requirements:
|
122
139
|
- - ~>
|
123
140
|
- !ruby/object:Gem::Version
|
@@ -125,6 +142,7 @@ dependencies:
|
|
125
142
|
- !ruby/object:Gem::Dependency
|
126
143
|
name: rspec
|
127
144
|
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
128
146
|
requirements:
|
129
147
|
- - ~>
|
130
148
|
- !ruby/object:Gem::Version
|
@@ -132,6 +150,7 @@ dependencies:
|
|
132
150
|
type: :development
|
133
151
|
prerelease: false
|
134
152
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
135
154
|
requirements:
|
136
155
|
- - ~>
|
137
156
|
- !ruby/object:Gem::Version
|
@@ -202,6 +221,8 @@ files:
|
|
202
221
|
- lib/thinking_sphinx/core/property.rb
|
203
222
|
- lib/thinking_sphinx/deltas.rb
|
204
223
|
- lib/thinking_sphinx/deltas/default_delta.rb
|
224
|
+
- lib/thinking_sphinx/deltas/delete_job.rb
|
225
|
+
- lib/thinking_sphinx/deltas/index_job.rb
|
205
226
|
- lib/thinking_sphinx/errors.rb
|
206
227
|
- lib/thinking_sphinx/excerpter.rb
|
207
228
|
- lib/thinking_sphinx/facet.rb
|
@@ -226,6 +247,7 @@ files:
|
|
226
247
|
- lib/thinking_sphinx/middlewares/sphinxql.rb
|
227
248
|
- lib/thinking_sphinx/middlewares/stale_id_checker.rb
|
228
249
|
- lib/thinking_sphinx/middlewares/stale_id_filter.rb
|
250
|
+
- lib/thinking_sphinx/middlewares/utf8.rb
|
229
251
|
- lib/thinking_sphinx/panes.rb
|
230
252
|
- lib/thinking_sphinx/panes/attributes_pane.rb
|
231
253
|
- lib/thinking_sphinx/panes/distance_pane.rb
|
@@ -371,26 +393,33 @@ files:
|
|
371
393
|
- thinking-sphinx.gemspec
|
372
394
|
homepage: http://pat.github.com/ts/en
|
373
395
|
licenses: []
|
374
|
-
metadata: {}
|
375
396
|
post_install_message:
|
376
397
|
rdoc_options: []
|
377
398
|
require_paths:
|
378
399
|
- lib
|
379
400
|
required_ruby_version: !ruby/object:Gem::Requirement
|
401
|
+
none: false
|
380
402
|
requirements:
|
381
|
-
- - '>='
|
403
|
+
- - ! '>='
|
382
404
|
- !ruby/object:Gem::Version
|
383
405
|
version: '0'
|
406
|
+
segments:
|
407
|
+
- 0
|
408
|
+
hash: 4005802565131001666
|
384
409
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
410
|
+
none: false
|
385
411
|
requirements:
|
386
|
-
- - '>='
|
412
|
+
- - ! '>='
|
387
413
|
- !ruby/object:Gem::Version
|
388
414
|
version: '0'
|
415
|
+
segments:
|
416
|
+
- 0
|
417
|
+
hash: 4005802565131001666
|
389
418
|
requirements: []
|
390
419
|
rubyforge_project: thinking-sphinx
|
391
|
-
rubygems_version:
|
420
|
+
rubygems_version: 1.8.23
|
392
421
|
signing_key:
|
393
|
-
specification_version:
|
422
|
+
specification_version: 3
|
394
423
|
summary: A smart wrapper over Sphinx for ActiveRecord
|
395
424
|
test_files:
|
396
425
|
- spec/acceptance/association_scoping_spec.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 2825535169716d44b3c2a897d70bdd6c44638b17
|
4
|
-
data.tar.gz: 30d74a154abf22f00795be4eaae8cb69e16fff19
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 4f33cf2627e2944ecee27c689a60770a201a4eb54de9fd97354b3eec27cd07d0d847d79a003b4df8e188f5dc3ecdf2a36ac7003cb8cb63f158f4486f3f75f1cc
|
7
|
-
data.tar.gz: a66b7764fcb538650f61931d4a5bddaf9d708098db223606a120f503a1eecbbe533e6b048b942a10fe157b8a11b593b0ff4e27a80e7934378597cfe2f6fd284a
|