thinking-sphinx 2.1.0 → 3.0.0.pre
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/.gitignore +8 -0
- data/.travis.yml +13 -0
- data/Appraisals +7 -0
- data/Gemfile +10 -0
- data/HISTORY +2 -267
- data/LICENCE +1 -1
- data/README.textile +194 -226
- data/Rakefile +24 -0
- data/gemfiles/.gitignore +1 -0
- data/gemfiles/rails_3_1.gemfile +11 -0
- data/gemfiles/rails_3_2.gemfile +11 -0
- data/lib/thinking-sphinx.rb +1 -1
- data/lib/thinking_sphinx.rb +34 -292
- data/lib/thinking_sphinx/active_record.rb +22 -383
- data/lib/thinking_sphinx/active_record/association.rb +9 -0
- data/lib/thinking_sphinx/active_record/association_proxy.rb +68 -0
- data/lib/thinking_sphinx/active_record/associations.rb +68 -0
- data/lib/thinking_sphinx/active_record/attribute.rb +20 -0
- data/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb +32 -0
- data/lib/thinking_sphinx/active_record/attribute/type.rb +79 -0
- data/lib/thinking_sphinx/active_record/attribute/values.rb +18 -0
- data/lib/thinking_sphinx/active_record/base.rb +36 -0
- data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +31 -0
- data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +55 -0
- data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +59 -0
- data/lib/thinking_sphinx/active_record/column.rb +30 -0
- data/lib/thinking_sphinx/active_record/database_adapters.rb +51 -0
- data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +13 -0
- data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +23 -0
- data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +25 -0
- data/lib/thinking_sphinx/active_record/field.rb +11 -0
- data/lib/thinking_sphinx/active_record/index.rb +55 -0
- data/lib/thinking_sphinx/active_record/interpreter.rb +47 -0
- data/lib/thinking_sphinx/active_record/log_subscriber.rb +10 -58
- data/lib/thinking_sphinx/active_record/property.rb +28 -0
- data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +60 -0
- data/lib/thinking_sphinx/active_record/sql_builder.rb +159 -0
- data/lib/thinking_sphinx/active_record/sql_source.rb +138 -0
- data/lib/thinking_sphinx/active_record/sql_source/template.rb +46 -0
- data/lib/thinking_sphinx/batched_search.rb +26 -0
- data/lib/thinking_sphinx/callbacks.rb +15 -0
- data/lib/thinking_sphinx/configuration.rb +80 -331
- data/lib/thinking_sphinx/configuration/consistent_ids.rb +31 -0
- data/lib/thinking_sphinx/configuration/defaults.rb +5 -0
- data/lib/thinking_sphinx/core.rb +6 -0
- data/lib/thinking_sphinx/core/index.rb +68 -0
- data/lib/thinking_sphinx/core/interpreter.rb +19 -0
- data/lib/thinking_sphinx/deltas.rb +35 -26
- data/lib/thinking_sphinx/deltas/default_delta.rb +56 -56
- data/lib/thinking_sphinx/excerpter.rb +23 -21
- data/lib/thinking_sphinx/facet.rb +22 -127
- data/lib/thinking_sphinx/facet_search.rb +95 -162
- data/lib/thinking_sphinx/index.rb +39 -143
- data/lib/thinking_sphinx/index_set.rb +51 -0
- data/lib/thinking_sphinx/masks.rb +8 -0
- data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +23 -0
- data/lib/thinking_sphinx/masks/pagination_mask.rb +60 -0
- data/lib/thinking_sphinx/masks/scopes_mask.rb +35 -0
- data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +11 -0
- data/lib/thinking_sphinx/middlewares.rb +36 -0
- data/lib/thinking_sphinx/middlewares/active_record_translator.rb +73 -0
- data/lib/thinking_sphinx/middlewares/geographer.rb +53 -0
- data/lib/thinking_sphinx/middlewares/glazier.rb +39 -0
- data/lib/thinking_sphinx/middlewares/ids_only.rb +13 -0
- data/lib/thinking_sphinx/middlewares/inquirer.rb +62 -0
- data/lib/thinking_sphinx/middlewares/middleware.rb +9 -0
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +149 -0
- data/lib/thinking_sphinx/middlewares/stale_id_checker.rb +45 -0
- data/lib/thinking_sphinx/middlewares/stale_id_filter.rb +46 -0
- data/lib/thinking_sphinx/panes.rb +8 -0
- data/lib/thinking_sphinx/panes/attributes_pane.rb +9 -0
- data/lib/thinking_sphinx/panes/distance_pane.rb +13 -0
- data/lib/thinking_sphinx/panes/excerpts_pane.rb +37 -0
- data/lib/thinking_sphinx/panes/weight_pane.rb +9 -0
- data/lib/thinking_sphinx/railtie.rb +6 -40
- data/lib/thinking_sphinx/rake_interface.rb +47 -0
- data/lib/thinking_sphinx/real_time.rb +11 -0
- data/lib/thinking_sphinx/real_time/attribute.rb +5 -0
- data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +48 -0
- data/lib/thinking_sphinx/real_time/field.rb +3 -0
- data/lib/thinking_sphinx/real_time/index.rb +47 -0
- data/lib/thinking_sphinx/real_time/index/template.rb +33 -0
- data/lib/thinking_sphinx/real_time/interpreter.rb +23 -0
- data/lib/thinking_sphinx/real_time/property.rb +16 -0
- data/lib/thinking_sphinx/scopes.rb +22 -0
- data/lib/thinking_sphinx/search.rb +90 -1028
- data/lib/thinking_sphinx/search/batch_inquirer.rb +27 -0
- data/lib/thinking_sphinx/search/context.rb +26 -0
- data/lib/thinking_sphinx/search/glaze.rb +32 -0
- data/lib/thinking_sphinx/search/merger.rb +24 -0
- data/lib/thinking_sphinx/search/query.rb +43 -0
- data/lib/thinking_sphinx/search/stale_ids_exception.rb +11 -0
- data/lib/thinking_sphinx/search/translator.rb +50 -0
- data/lib/thinking_sphinx/tasks.rb +22 -125
- data/lib/thinking_sphinx/test.rb +9 -19
- data/sketchpad.rb +58 -0
- data/spec/acceptance/association_scoping_spec.rb +23 -0
- data/spec/acceptance/attribute_access_spec.rb +39 -0
- data/spec/acceptance/attribute_updates_spec.rb +16 -0
- data/spec/acceptance/batch_searching_spec.rb +21 -0
- data/spec/acceptance/big_integers_spec.rb +27 -0
- data/spec/acceptance/excerpts_spec.rb +14 -0
- data/spec/acceptance/facets_spec.rb +122 -0
- data/spec/acceptance/geosearching_spec.rb +39 -0
- data/spec/acceptance/grouping_by_attributes_spec.rb +77 -0
- data/spec/acceptance/paginating_search_results_spec.rb +24 -0
- data/spec/acceptance/remove_deleted_records_spec.rb +23 -0
- data/spec/acceptance/search_counts_spec.rb +18 -0
- data/spec/acceptance/search_for_just_ids_spec.rb +19 -0
- data/spec/acceptance/searching_across_models_spec.rb +28 -0
- data/spec/acceptance/searching_on_fields_spec.rb +56 -0
- data/spec/acceptance/searching_with_filters_spec.rb +109 -0
- data/spec/acceptance/searching_with_sti_spec.rb +55 -0
- data/spec/acceptance/searching_within_a_model_spec.rb +52 -0
- data/spec/acceptance/sorting_search_results_spec.rb +41 -0
- data/spec/acceptance/spec_helper.rb +4 -0
- data/spec/acceptance/specifying_sql_spec.rb +62 -0
- data/spec/acceptance/sphinx_scopes_spec.rb +49 -0
- data/spec/acceptance/sql_deltas_spec.rb +43 -0
- data/spec/acceptance/support/database_cleaner.rb +11 -0
- data/spec/acceptance/support/sphinx_controller.rb +39 -0
- data/spec/acceptance/support/sphinx_helpers.rb +24 -0
- data/spec/acceptance/suspended_deltas_spec.rb +20 -0
- data/spec/internal/.gitignore +1 -0
- data/spec/internal/app/indices/animal_index.rb +3 -0
- data/spec/internal/app/indices/article_index.rb +24 -0
- data/spec/internal/app/indices/book_index.rb +8 -0
- data/spec/internal/app/indices/city_index.rb +6 -0
- data/spec/internal/app/indices/product_index.rb +3 -0
- data/spec/internal/app/indices/tee_index.rb +4 -0
- data/spec/internal/app/indices/user_index.rb +5 -0
- data/spec/internal/app/models/animal.rb +2 -0
- data/spec/internal/app/models/article.rb +5 -0
- data/spec/internal/app/models/bird.rb +2 -0
- data/spec/internal/app/models/book.rb +11 -0
- data/spec/internal/app/models/city.rb +2 -0
- data/spec/internal/app/models/colour.rb +3 -0
- data/spec/internal/app/models/flightless_bird.rb +2 -0
- data/spec/internal/app/models/mammal.rb +2 -0
- data/spec/internal/app/models/product.rb +3 -0
- data/spec/internal/app/models/tag.rb +4 -0
- data/{features/thinking_sphinx → spec/internal/app}/models/tagging.rb +1 -1
- data/spec/internal/app/models/tee.rb +3 -0
- data/spec/internal/app/models/tweet.rb +3 -0
- data/spec/internal/app/models/user.rb +3 -0
- data/spec/internal/config/database.yml +5 -0
- data/spec/internal/db/schema.rb +65 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/spec_helper.rb +8 -49
- data/spec/support/sphinx_yaml_helpers.rb +9 -0
- data/spec/thinking_sphinx/active_record/association_spec.rb +12 -0
- data/spec/thinking_sphinx/active_record/associations_spec.rb +184 -0
- data/spec/thinking_sphinx/active_record/attribute/type_spec.rb +147 -0
- data/spec/thinking_sphinx/active_record/base_spec.rb +61 -0
- data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +80 -0
- data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +147 -0
- data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +69 -0
- data/spec/thinking_sphinx/active_record/column_spec.rb +47 -0
- data/spec/thinking_sphinx/active_record/database_adapters/abstract_adapter_spec.rb +31 -0
- data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +43 -0
- data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +45 -0
- data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +108 -0
- data/spec/thinking_sphinx/active_record/field_spec.rb +36 -0
- data/spec/thinking_sphinx/active_record/index_spec.rb +208 -0
- data/spec/thinking_sphinx/active_record/interpreter_spec.rb +293 -0
- data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +162 -0
- data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +666 -0
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +401 -0
- data/spec/thinking_sphinx/configuration_spec.rb +264 -171
- data/spec/thinking_sphinx/deltas/default_delta_spec.rb +116 -0
- data/spec/thinking_sphinx/deltas_spec.rb +58 -0
- data/spec/thinking_sphinx/excerpter_spec.rb +40 -38
- data/spec/thinking_sphinx/facet_search_spec.rb +49 -151
- data/spec/thinking_sphinx/index_set_spec.rb +68 -0
- data/spec/thinking_sphinx/index_spec.rb +91 -155
- data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +121 -0
- data/spec/thinking_sphinx/masks/scopes_mask_spec.rb +68 -0
- data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +132 -0
- data/spec/thinking_sphinx/middlewares/geographer_spec.rb +89 -0
- data/spec/thinking_sphinx/middlewares/glazier_spec.rb +62 -0
- data/spec/thinking_sphinx/middlewares/inquirer_spec.rb +55 -0
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +271 -0
- data/spec/thinking_sphinx/middlewares/stale_id_checker_spec.rb +47 -0
- data/spec/thinking_sphinx/middlewares/stale_id_filter_spec.rb +91 -0
- data/spec/thinking_sphinx/panes/attributes_pane_spec.rb +21 -0
- data/spec/thinking_sphinx/panes/distance_pane_spec.rb +41 -0
- data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +53 -0
- data/spec/thinking_sphinx/panes/weight_pane_spec.rb +20 -0
- data/spec/thinking_sphinx/rake_interface_spec.rb +147 -0
- data/spec/thinking_sphinx/real_time/attribute_spec.rb +62 -0
- data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +76 -0
- data/spec/thinking_sphinx/real_time/field_spec.rb +54 -0
- data/spec/thinking_sphinx/real_time/index_spec.rb +154 -0
- data/spec/thinking_sphinx/real_time/interpreter_spec.rb +147 -0
- data/spec/thinking_sphinx/scopes_spec.rb +38 -0
- data/spec/thinking_sphinx/search/glaze_spec.rb +55 -0
- data/spec/thinking_sphinx/search/query_spec.rb +46 -0
- data/spec/thinking_sphinx/search_spec.rb +65 -1357
- data/spec/thinking_sphinx_spec.rb +19 -182
- data/thinking-sphinx.gemspec +33 -0
- metadata +318 -431
- data/features/abstract_inheritance.feature +0 -10
- data/features/alternate_primary_key.feature +0 -27
- data/features/attribute_transformation.feature +0 -22
- data/features/attribute_updates.feature +0 -79
- data/features/deleting_instances.feature +0 -70
- data/features/direct_attributes.feature +0 -11
- data/features/excerpts.feature +0 -21
- data/features/extensible_delta_indexing.feature +0 -9
- data/features/facets.feature +0 -88
- data/features/facets_across_model.feature +0 -29
- data/features/field_sorting.feature +0 -18
- data/features/handling_edits.feature +0 -97
- data/features/retry_stale_indexes.feature +0 -24
- data/features/searching_across_models.feature +0 -20
- data/features/searching_by_index.feature +0 -41
- data/features/searching_by_model.feature +0 -175
- data/features/searching_with_find_arguments.feature +0 -56
- data/features/sphinx_detection.feature +0 -25
- data/features/sphinx_scopes.feature +0 -68
- data/features/step_definitions/alpha_steps.rb +0 -16
- data/features/step_definitions/beta_steps.rb +0 -7
- data/features/step_definitions/common_steps.rb +0 -205
- data/features/step_definitions/extensible_delta_indexing_steps.rb +0 -7
- data/features/step_definitions/facet_steps.rb +0 -96
- data/features/step_definitions/find_arguments_steps.rb +0 -36
- data/features/step_definitions/gamma_steps.rb +0 -15
- data/features/step_definitions/scope_steps.rb +0 -19
- data/features/step_definitions/search_steps.rb +0 -94
- data/features/step_definitions/sphinx_steps.rb +0 -35
- data/features/sti_searching.feature +0 -19
- data/features/support/env.rb +0 -24
- data/features/support/lib/generic_delta_handler.rb +0 -8
- data/features/thinking_sphinx/database.example.yml +0 -3
- data/features/thinking_sphinx/db/.gitignore +0 -1
- data/features/thinking_sphinx/db/fixtures/alphas.rb +0 -8
- data/features/thinking_sphinx/db/fixtures/authors.rb +0 -1
- data/features/thinking_sphinx/db/fixtures/betas.rb +0 -11
- data/features/thinking_sphinx/db/fixtures/boxes.rb +0 -9
- data/features/thinking_sphinx/db/fixtures/categories.rb +0 -1
- data/features/thinking_sphinx/db/fixtures/cats.rb +0 -3
- data/features/thinking_sphinx/db/fixtures/comments.rb +0 -24
- data/features/thinking_sphinx/db/fixtures/developers.rb +0 -31
- data/features/thinking_sphinx/db/fixtures/dogs.rb +0 -3
- data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +0 -10
- data/features/thinking_sphinx/db/fixtures/foxes.rb +0 -3
- data/features/thinking_sphinx/db/fixtures/gammas.rb +0 -10
- data/features/thinking_sphinx/db/fixtures/music.rb +0 -4
- data/features/thinking_sphinx/db/fixtures/people.rb +0 -1001
- data/features/thinking_sphinx/db/fixtures/post_keywords.txt +0 -1
- data/features/thinking_sphinx/db/fixtures/posts.rb +0 -10
- data/features/thinking_sphinx/db/fixtures/robots.rb +0 -8
- data/features/thinking_sphinx/db/fixtures/tags.rb +0 -27
- data/features/thinking_sphinx/db/migrations/create_alphas.rb +0 -8
- data/features/thinking_sphinx/db/migrations/create_animals.rb +0 -5
- data/features/thinking_sphinx/db/migrations/create_authors.rb +0 -3
- data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +0 -6
- data/features/thinking_sphinx/db/migrations/create_betas.rb +0 -5
- data/features/thinking_sphinx/db/migrations/create_boxes.rb +0 -5
- data/features/thinking_sphinx/db/migrations/create_categories.rb +0 -3
- data/features/thinking_sphinx/db/migrations/create_comments.rb +0 -10
- data/features/thinking_sphinx/db/migrations/create_developers.rb +0 -7
- data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +0 -5
- data/features/thinking_sphinx/db/migrations/create_gammas.rb +0 -3
- data/features/thinking_sphinx/db/migrations/create_genres.rb +0 -3
- data/features/thinking_sphinx/db/migrations/create_music.rb +0 -6
- data/features/thinking_sphinx/db/migrations/create_people.rb +0 -13
- data/features/thinking_sphinx/db/migrations/create_posts.rb +0 -6
- data/features/thinking_sphinx/db/migrations/create_robots.rb +0 -4
- data/features/thinking_sphinx/db/migrations/create_taggings.rb +0 -5
- data/features/thinking_sphinx/db/migrations/create_tags.rb +0 -4
- data/features/thinking_sphinx/models/alpha.rb +0 -23
- data/features/thinking_sphinx/models/andrew.rb +0 -17
- data/features/thinking_sphinx/models/animal.rb +0 -5
- data/features/thinking_sphinx/models/author.rb +0 -3
- data/features/thinking_sphinx/models/beta.rb +0 -13
- data/features/thinking_sphinx/models/box.rb +0 -8
- data/features/thinking_sphinx/models/cat.rb +0 -3
- data/features/thinking_sphinx/models/category.rb +0 -4
- data/features/thinking_sphinx/models/comment.rb +0 -10
- data/features/thinking_sphinx/models/developer.rb +0 -21
- data/features/thinking_sphinx/models/dog.rb +0 -3
- data/features/thinking_sphinx/models/extensible_beta.rb +0 -9
- data/features/thinking_sphinx/models/fox.rb +0 -5
- data/features/thinking_sphinx/models/gamma.rb +0 -5
- data/features/thinking_sphinx/models/genre.rb +0 -3
- data/features/thinking_sphinx/models/medium.rb +0 -5
- data/features/thinking_sphinx/models/music.rb +0 -10
- data/features/thinking_sphinx/models/person.rb +0 -24
- data/features/thinking_sphinx/models/post.rb +0 -22
- data/features/thinking_sphinx/models/robot.rb +0 -12
- data/features/thinking_sphinx/models/tag.rb +0 -3
- data/lib/cucumber/thinking_sphinx/external_world.rb +0 -12
- data/lib/cucumber/thinking_sphinx/internal_world.rb +0 -137
- data/lib/cucumber/thinking_sphinx/sql_logger.rb +0 -28
- data/lib/thinking_sphinx/action_controller.rb +0 -31
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +0 -54
- data/lib/thinking_sphinx/active_record/collection_proxy.rb +0 -47
- data/lib/thinking_sphinx/active_record/collection_proxy_with_scopes.rb +0 -27
- data/lib/thinking_sphinx/active_record/delta.rb +0 -67
- data/lib/thinking_sphinx/active_record/has_many_association.rb +0 -44
- data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +0 -21
- data/lib/thinking_sphinx/active_record/scopes.rb +0 -110
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +0 -94
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +0 -62
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +0 -188
- data/lib/thinking_sphinx/association.rb +0 -230
- data/lib/thinking_sphinx/attribute.rb +0 -405
- data/lib/thinking_sphinx/auto_version.rb +0 -40
- data/lib/thinking_sphinx/bundled_search.rb +0 -40
- data/lib/thinking_sphinx/class_facet.rb +0 -20
- data/lib/thinking_sphinx/connection.rb +0 -71
- data/lib/thinking_sphinx/context.rb +0 -81
- data/lib/thinking_sphinx/core/string.rb +0 -15
- data/lib/thinking_sphinx/deltas/delete_job.rb +0 -16
- data/lib/thinking_sphinx/deltas/index_job.rb +0 -17
- data/lib/thinking_sphinx/deploy/capistrano.rb +0 -99
- data/lib/thinking_sphinx/field.rb +0 -98
- data/lib/thinking_sphinx/index/builder.rb +0 -315
- data/lib/thinking_sphinx/index/faux_column.rb +0 -118
- data/lib/thinking_sphinx/join.rb +0 -37
- data/lib/thinking_sphinx/property.rb +0 -187
- data/lib/thinking_sphinx/search_methods.rb +0 -439
- data/lib/thinking_sphinx/sinatra.rb +0 -7
- data/lib/thinking_sphinx/source.rb +0 -194
- data/lib/thinking_sphinx/source/internal_properties.rb +0 -51
- data/lib/thinking_sphinx/source/sql.rb +0 -174
- data/spec/fixtures/data.sql +0 -32
- data/spec/fixtures/database.yml.default +0 -3
- data/spec/fixtures/models.rb +0 -164
- data/spec/fixtures/structure.sql +0 -146
- data/spec/sphinx_helper.rb +0 -60
- data/spec/support/rails.rb +0 -25
- data/spec/thinking_sphinx/active_record/delta_spec.rb +0 -123
- data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +0 -173
- data/spec/thinking_sphinx/active_record/scopes_spec.rb +0 -177
- data/spec/thinking_sphinx/active_record_spec.rb +0 -573
- data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +0 -163
- data/spec/thinking_sphinx/association_spec.rb +0 -250
- data/spec/thinking_sphinx/attribute_spec.rb +0 -552
- data/spec/thinking_sphinx/auto_version_spec.rb +0 -103
- data/spec/thinking_sphinx/connection_spec.rb +0 -77
- data/spec/thinking_sphinx/context_spec.rb +0 -127
- data/spec/thinking_sphinx/core/array_spec.rb +0 -9
- data/spec/thinking_sphinx/core/string_spec.rb +0 -9
- data/spec/thinking_sphinx/facet_spec.rb +0 -359
- data/spec/thinking_sphinx/field_spec.rb +0 -127
- data/spec/thinking_sphinx/index/builder_spec.rb +0 -532
- data/spec/thinking_sphinx/index/faux_column_spec.rb +0 -36
- data/spec/thinking_sphinx/search_methods_spec.rb +0 -156
- data/spec/thinking_sphinx/source_spec.rb +0 -267
- data/spec/thinking_sphinx/test_spec.rb +0 -20
data/Rakefile
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
require 'appraisal'
|
|
3
|
+
|
|
4
|
+
Bundler::GemHelper.install_tasks
|
|
5
|
+
|
|
6
|
+
require 'rspec/core/rake_task'
|
|
7
|
+
|
|
8
|
+
RSpec::Core::RakeTask.new
|
|
9
|
+
|
|
10
|
+
namespace :spec do
|
|
11
|
+
desc 'Run unit specs only'
|
|
12
|
+
RSpec::Core::RakeTask.new(:unit) do |task|
|
|
13
|
+
task.pattern = 'spec'
|
|
14
|
+
task.rspec_opts = '--tag "~live"'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc 'Run acceptance specs only'
|
|
18
|
+
RSpec::Core::RakeTask.new(:acceptance) do |task|
|
|
19
|
+
task.pattern = 'spec'
|
|
20
|
+
task.rspec_opts = '--tag "live"'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
task :default => :spec
|
data/gemfiles/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.gemfile.lock
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source :rubygems
|
|
4
|
+
|
|
5
|
+
gem "riddle", "1.5.3"
|
|
6
|
+
gem "combustion", :git=>"git://github.com/pat/combustion.git", :ref=>"45f50e64c3"
|
|
7
|
+
gem "pg", "~> 0.11.0", :platform=>:ruby
|
|
8
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 1.1.3", :platform=>:jruby
|
|
9
|
+
gem "rails", "~> 3.1.0"
|
|
10
|
+
|
|
11
|
+
gemspec :path=>"../"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source :rubygems
|
|
4
|
+
|
|
5
|
+
gem "riddle", "1.5.3"
|
|
6
|
+
gem "combustion", :git=>"git://github.com/pat/combustion.git", :ref=>"45f50e64c3"
|
|
7
|
+
gem "pg", "~> 0.11.0", :platform=>:ruby
|
|
8
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 1.1.3", :platform=>:jruby
|
|
9
|
+
gem "rails", "~> 3.2.0"
|
|
10
|
+
|
|
11
|
+
gemspec :path=>"../"
|
data/lib/thinking-sphinx.rb
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
require 'thinking_sphinx'
|
|
1
|
+
require 'thinking_sphinx'
|
data/lib/thinking_sphinx.rb
CHANGED
|
@@ -1,304 +1,46 @@
|
|
|
1
|
-
require 'thread'
|
|
2
|
-
require 'active_record'
|
|
3
|
-
require 'innertube'
|
|
4
|
-
require 'yaml'
|
|
5
1
|
require 'riddle'
|
|
6
|
-
|
|
7
|
-
require '
|
|
8
|
-
require 'thinking_sphinx/core/string'
|
|
9
|
-
require 'thinking_sphinx/property'
|
|
10
|
-
require 'thinking_sphinx/active_record'
|
|
11
|
-
require 'thinking_sphinx/association'
|
|
12
|
-
require 'thinking_sphinx/attribute'
|
|
13
|
-
require 'thinking_sphinx/bundled_search'
|
|
14
|
-
require 'thinking_sphinx/configuration'
|
|
15
|
-
require 'thinking_sphinx/connection'
|
|
16
|
-
require 'thinking_sphinx/context'
|
|
17
|
-
require 'thinking_sphinx/excerpter'
|
|
18
|
-
require 'thinking_sphinx/facet'
|
|
19
|
-
require 'thinking_sphinx/class_facet'
|
|
20
|
-
require 'thinking_sphinx/facet_search'
|
|
21
|
-
require 'thinking_sphinx/field'
|
|
22
|
-
require 'thinking_sphinx/index'
|
|
23
|
-
require 'thinking_sphinx/join'
|
|
24
|
-
require 'thinking_sphinx/source'
|
|
25
|
-
require 'thinking_sphinx/search'
|
|
26
|
-
require 'thinking_sphinx/search_methods'
|
|
27
|
-
require 'thinking_sphinx/deltas'
|
|
28
|
-
|
|
29
|
-
require 'thinking_sphinx/adapters/abstract_adapter'
|
|
30
|
-
require 'thinking_sphinx/adapters/mysql_adapter'
|
|
31
|
-
require 'thinking_sphinx/adapters/postgresql_adapter'
|
|
32
|
-
|
|
33
|
-
require 'thinking_sphinx/railtie' if defined?(Rails)
|
|
2
|
+
require 'middleware'
|
|
3
|
+
require 'active_record'
|
|
34
4
|
|
|
35
5
|
module ThinkingSphinx
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# A ConnectionError will get thrown when a connection to Sphinx can't be
|
|
39
|
-
# made.
|
|
40
|
-
class ConnectionError < StandardError
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# A StaleIdsException is thrown by Collection.instances_from_matches if there
|
|
44
|
-
# are records in Sphinx but not in the database, so the search can be retried.
|
|
45
|
-
class StaleIdsException < StandardError
|
|
46
|
-
attr_accessor :ids
|
|
47
|
-
def initialize(ids)
|
|
48
|
-
self.ids = ids
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# A SphinxError occurs when Sphinx responds with an error due to problematic
|
|
53
|
-
# queries or indexes.
|
|
54
|
-
class SphinxError < RuntimeError
|
|
55
|
-
attr_accessor :results
|
|
56
|
-
def initialize(message = nil, results = nil)
|
|
57
|
-
super(message)
|
|
58
|
-
self.results = results
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# The collection of indexed models. Keep in mind that Rails lazily loads
|
|
63
|
-
# its classes, so this may not actually be populated with _all_ the models
|
|
64
|
-
# that have Sphinx indexes.
|
|
65
|
-
@@sphinx_mutex = Mutex.new
|
|
66
|
-
@@context = nil
|
|
67
|
-
@@define_indexes = true
|
|
68
|
-
@@deltas_enabled = nil
|
|
69
|
-
@@updates_enabled = nil
|
|
70
|
-
@@suppress_delta_output = false
|
|
71
|
-
@@remote_sphinx = false
|
|
72
|
-
@@use_group_by_shortcut = nil
|
|
73
|
-
|
|
74
|
-
def self.mutex
|
|
75
|
-
@@sphinx_mutex
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def self.context
|
|
79
|
-
if @@context.nil?
|
|
80
|
-
mutex.synchronize do
|
|
81
|
-
if @@context.nil?
|
|
82
|
-
@@context = ThinkingSphinx::Context.new
|
|
83
|
-
@@context.prepare
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
@@context
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def self.reset_context!(context = nil)
|
|
92
|
-
mutex.synchronize do
|
|
93
|
-
@@context = context
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def self.unique_id_expression(adapter, offset = nil)
|
|
98
|
-
"* #{adapter.cast_to_int context.indexed_models.size} + #{offset || 0}"
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Check if index definition is disabled.
|
|
102
|
-
#
|
|
103
|
-
def self.define_indexes?
|
|
104
|
-
@@define_indexes
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
# Enable/disable indexes - you may want to do this while migrating data.
|
|
108
|
-
#
|
|
109
|
-
# ThinkingSphinx.define_indexes = false
|
|
110
|
-
#
|
|
111
|
-
def self.define_indexes=(value)
|
|
112
|
-
mutex.synchronize do
|
|
113
|
-
@@define_indexes = value
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# Check if delta indexing is enabled/disabled.
|
|
118
|
-
#
|
|
119
|
-
def self.deltas_enabled?
|
|
120
|
-
if @@deltas_enabled.nil?
|
|
121
|
-
mutex.synchronize do
|
|
122
|
-
if @@deltas_enabled.nil?
|
|
123
|
-
@@deltas_enabled = (
|
|
124
|
-
ThinkingSphinx::Configuration.environment != "test"
|
|
125
|
-
)
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
@@deltas_enabled && !deltas_suspended?
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# Enable/disable delta indexing.
|
|
134
|
-
#
|
|
135
|
-
# ThinkingSphinx.deltas_enabled = false
|
|
136
|
-
#
|
|
137
|
-
def self.deltas_enabled=(value)
|
|
138
|
-
mutex.synchronize do
|
|
139
|
-
@@deltas_enabled = value
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# Check if delta indexing is suspended.
|
|
144
|
-
#
|
|
145
|
-
def self.deltas_suspended?
|
|
146
|
-
if Thread.current[:thinking_sphinx_deltas_suspended].nil?
|
|
147
|
-
Thread.current[:thinking_sphinx_deltas_suspended] = false
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
Thread.current[:thinking_sphinx_deltas_suspended]
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# Suspend/resume delta indexing.
|
|
154
|
-
#
|
|
155
|
-
# ThinkingSphinx.deltas_suspended = false
|
|
156
|
-
#
|
|
157
|
-
def self.deltas_suspended=(value)
|
|
158
|
-
Thread.current[:thinking_sphinx_deltas_suspended] = value
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Check if updates are enabled. True by default, unless within the test
|
|
162
|
-
# environment.
|
|
163
|
-
#
|
|
164
|
-
def self.updates_enabled?
|
|
165
|
-
if @@updates_enabled.nil?
|
|
166
|
-
mutex.synchronize do
|
|
167
|
-
if @@updates_enabled.nil?
|
|
168
|
-
@@updates_enabled = (
|
|
169
|
-
ThinkingSphinx::Configuration.environment != "test"
|
|
170
|
-
)
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
@@updates_enabled
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
# Enable/disable updates to Sphinx
|
|
179
|
-
#
|
|
180
|
-
# ThinkingSphinx.updates_enabled = false
|
|
181
|
-
#
|
|
182
|
-
def self.updates_enabled=(value)
|
|
183
|
-
mutex.synchronize do
|
|
184
|
-
@@updates_enabled = value
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
def self.suppress_delta_output?
|
|
189
|
-
@@suppress_delta_output
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def self.suppress_delta_output=(value)
|
|
193
|
-
mutex.synchronize do
|
|
194
|
-
@@suppress_delta_output = value
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
# Checks to see if MySQL will allow simplistic GROUP BY statements. If not,
|
|
199
|
-
# or if not using MySQL, this will return false.
|
|
200
|
-
#
|
|
201
|
-
def self.use_group_by_shortcut?
|
|
202
|
-
if @@use_group_by_shortcut.nil?
|
|
203
|
-
mutex.synchronize do
|
|
204
|
-
if @@use_group_by_shortcut.nil?
|
|
205
|
-
@@use_group_by_shortcut = !!(
|
|
206
|
-
mysql? && ::ActiveRecord::Base.connection.select_all(
|
|
207
|
-
"SELECT @@global.sql_mode, @@session.sql_mode;"
|
|
208
|
-
).all? { |key, value|
|
|
209
|
-
value.nil? || value[/ONLY_FULL_GROUP_BY/].nil?
|
|
210
|
-
}
|
|
211
|
-
)
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
@@use_group_by_shortcut
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
def self.reset_use_group_by_shortcut
|
|
220
|
-
mutex.synchronize do
|
|
221
|
-
@@use_group_by_shortcut = nil
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
# An indication of whether Sphinx is running on a remote machine instead of
|
|
226
|
-
# the same machine.
|
|
227
|
-
#
|
|
228
|
-
def self.remote_sphinx?
|
|
229
|
-
@@remote_sphinx
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
# Tells Thinking Sphinx that Sphinx is running on a different machine, and
|
|
233
|
-
# thus it can't reliably guess whether it is running or not (ie: the
|
|
234
|
-
# #sphinx_running? method), and so just assumes it is.
|
|
235
|
-
#
|
|
236
|
-
# Useful for multi-machine deployments. Set it in your production.rb file.
|
|
237
|
-
#
|
|
238
|
-
# ThinkingSphinx.remote_sphinx = true
|
|
239
|
-
#
|
|
240
|
-
def self.remote_sphinx=(value)
|
|
241
|
-
mutex.synchronize do
|
|
242
|
-
@@remote_sphinx = value
|
|
243
|
-
end
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
# Check if Sphinx is running. If remote_sphinx is set to true (indicating
|
|
247
|
-
# Sphinx is on a different machine), this will always return true, and you
|
|
248
|
-
# will have to handle any connection errors yourself.
|
|
249
|
-
#
|
|
250
|
-
def self.sphinx_running?
|
|
251
|
-
remote_sphinx? || sphinx_running_by_pid?
|
|
6
|
+
def self.count(query = '', options = {})
|
|
7
|
+
search(query, options).total_entries
|
|
252
8
|
end
|
|
253
9
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
#
|
|
257
|
-
def self.sphinx_running_by_pid?
|
|
258
|
-
!!sphinx_pid && pid_active?(sphinx_pid)
|
|
10
|
+
def self.facets(query = '', options = {})
|
|
11
|
+
ThinkingSphinx::FacetSearch.new query, options
|
|
259
12
|
end
|
|
260
13
|
|
|
261
|
-
def self.
|
|
262
|
-
|
|
263
|
-
File.read(ThinkingSphinx::Configuration.instance.pid_file)[/\d+/]
|
|
264
|
-
else
|
|
265
|
-
nil
|
|
266
|
-
end
|
|
14
|
+
def self.search(query = '', options = {})
|
|
15
|
+
ThinkingSphinx::Search.new query, options
|
|
267
16
|
end
|
|
268
17
|
|
|
269
|
-
def self.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
true
|
|
273
|
-
rescue Exception => e
|
|
274
|
-
false
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
def self.microsoft?
|
|
278
|
-
RUBY_PLATFORM =~ /mswin/
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
def self.jruby?
|
|
282
|
-
defined?(JRUBY_VERSION)
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
def self.mysql?
|
|
286
|
-
::ActiveRecord::Base.connection.class.name.demodulize == "MysqlAdapter" ||
|
|
287
|
-
::ActiveRecord::Base.connection.class.name.demodulize == "Mysql2Adapter" ||
|
|
288
|
-
::ActiveRecord::Base.connection.class.name.demodulize == "MysqlplusAdapter" || (
|
|
289
|
-
jruby? && ::ActiveRecord::Base.connection.config[:adapter] == "jdbcmysql"
|
|
290
|
-
)
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
def self.rails_3_1?
|
|
294
|
-
!!defined?(::ActiveRecord::Associations::CollectionProxy)
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
def self.before_index_hooks
|
|
298
|
-
@before_index_hooks
|
|
18
|
+
def self.search_for_ids(query = '', options = {})
|
|
19
|
+
search = ThinkingSphinx::Search.new query, options
|
|
20
|
+
ThinkingSphinx::Search::Merger.new(search).merge! nil, :ids_only => true
|
|
299
21
|
end
|
|
22
|
+
end
|
|
300
23
|
|
|
301
|
-
|
|
24
|
+
# Core
|
|
25
|
+
require 'thinking_sphinx/batched_search'
|
|
26
|
+
require 'thinking_sphinx/callbacks'
|
|
27
|
+
require 'thinking_sphinx/core'
|
|
28
|
+
require 'thinking_sphinx/configuration'
|
|
29
|
+
require 'thinking_sphinx/excerpter'
|
|
30
|
+
require 'thinking_sphinx/facet'
|
|
31
|
+
require 'thinking_sphinx/facet_search'
|
|
32
|
+
require 'thinking_sphinx/index'
|
|
33
|
+
require 'thinking_sphinx/index_set'
|
|
34
|
+
require 'thinking_sphinx/masks'
|
|
35
|
+
require 'thinking_sphinx/middlewares'
|
|
36
|
+
require 'thinking_sphinx/panes'
|
|
37
|
+
require 'thinking_sphinx/rake_interface'
|
|
38
|
+
require 'thinking_sphinx/scopes'
|
|
39
|
+
require 'thinking_sphinx/search'
|
|
40
|
+
require 'thinking_sphinx/test'
|
|
41
|
+
# Extended
|
|
42
|
+
require 'thinking_sphinx/active_record'
|
|
43
|
+
require 'thinking_sphinx/deltas'
|
|
44
|
+
require 'thinking_sphinx/real_time'
|
|
302
45
|
|
|
303
|
-
|
|
304
|
-
end
|
|
46
|
+
require 'thinking_sphinx/railtie' if defined?(Rails)
|
|
@@ -1,386 +1,25 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require 'thinking_sphinx/active_record/collection_proxy'
|
|
3
|
-
require 'thinking_sphinx/active_record/collection_proxy_with_scopes'
|
|
4
|
-
require 'thinking_sphinx/active_record/delta'
|
|
5
|
-
require 'thinking_sphinx/active_record/has_many_association'
|
|
6
|
-
require 'thinking_sphinx/active_record/log_subscriber'
|
|
7
|
-
require 'thinking_sphinx/active_record/has_many_association_with_scopes'
|
|
8
|
-
require 'thinking_sphinx/active_record/scopes'
|
|
9
|
-
|
|
10
|
-
module ThinkingSphinx
|
|
11
|
-
# Core additions to ActiveRecord models - define_index for creating indexes
|
|
12
|
-
# for models. If you want to interrogate the index objects created for the
|
|
13
|
-
# model, you can use the class-level accessor :sphinx_indexes.
|
|
14
|
-
#
|
|
15
|
-
module ActiveRecord
|
|
16
|
-
def self.included(base)
|
|
17
|
-
base.class_eval do
|
|
18
|
-
if defined?(class_attribute)
|
|
19
|
-
class_attribute :sphinx_indexes, :sphinx_facets
|
|
20
|
-
else
|
|
21
|
-
class_inheritable_array :sphinx_indexes, :sphinx_facets
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
extend ThinkingSphinx::ActiveRecord::ClassMethods
|
|
25
|
-
|
|
26
|
-
class << self
|
|
27
|
-
attr_accessor :sphinx_index_blocks, :sphinx_types
|
|
28
|
-
|
|
29
|
-
def set_sphinx_primary_key(attribute)
|
|
30
|
-
@sphinx_primary_key_attribute = attribute
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def primary_key_for_sphinx
|
|
34
|
-
@primary_key_for_sphinx ||= begin
|
|
35
|
-
if custom_primary_key_for_sphinx?
|
|
36
|
-
@sphinx_primary_key_attribute ||
|
|
37
|
-
superclass.primary_key_for_sphinx
|
|
38
|
-
else
|
|
39
|
-
primary_key || 'id'
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def custom_primary_key_for_sphinx?
|
|
45
|
-
(
|
|
46
|
-
superclass.respond_to?(:custom_primary_key_for_sphinx?) &&
|
|
47
|
-
superclass.custom_primary_key_for_sphinx?
|
|
48
|
-
) || !@sphinx_primary_key_attribute.nil?
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def clear_primary_key_for_sphinx
|
|
52
|
-
@primary_key_for_sphinx = nil
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def sphinx_index_options
|
|
56
|
-
sphinx_indexes.last.options
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def set_sphinx_types(types)
|
|
60
|
-
@sphinx_types = types
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Generate a unique CRC value for the model's name, to use to
|
|
64
|
-
# determine which Sphinx documents belong to which AR records.
|
|
65
|
-
#
|
|
66
|
-
# Really only written for internal use - but hey, if it's useful to
|
|
67
|
-
# you in some other way, awesome.
|
|
68
|
-
#
|
|
69
|
-
def to_crc32
|
|
70
|
-
self.name.to_crc32
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def to_crc32s
|
|
74
|
-
(descendants << self).collect { |klass| klass.to_crc32 }
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def sphinx_database_adapter
|
|
78
|
-
ThinkingSphinx::AbstractAdapter.detect(self)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def sphinx_name
|
|
82
|
-
self.name.underscore.tr(':/\\', '_')
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
private
|
|
86
|
-
|
|
87
|
-
def defined_indexes?
|
|
88
|
-
@defined_indexes
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def defined_indexes=(value)
|
|
92
|
-
@defined_indexes = value
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def sphinx_delta?
|
|
96
|
-
self.sphinx_indexes.any? { |index| index.delta? }
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
if ThinkingSphinx.rails_3_1?
|
|
102
|
-
assoc_mixin = ThinkingSphinx::ActiveRecord::CollectionProxy
|
|
103
|
-
::ActiveRecord::Associations::CollectionProxy.send(:include, assoc_mixin)
|
|
104
|
-
else
|
|
105
|
-
assoc_mixin = ThinkingSphinx::ActiveRecord::HasManyAssociation
|
|
106
|
-
::ActiveRecord::Associations::HasManyAssociation.send(:include, assoc_mixin)
|
|
107
|
-
::ActiveRecord::Associations::HasManyThroughAssociation.send(:include, assoc_mixin)
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
module ClassMethods
|
|
112
|
-
# Allows creation of indexes for Sphinx. If you don't do this, there
|
|
113
|
-
# isn't much point trying to search (or using this plugin at all,
|
|
114
|
-
# really).
|
|
115
|
-
#
|
|
116
|
-
# An example or two:
|
|
117
|
-
#
|
|
118
|
-
# define_index
|
|
119
|
-
# indexes :id, :as => :model_id
|
|
120
|
-
# indexes name
|
|
121
|
-
# end
|
|
122
|
-
#
|
|
123
|
-
# You can also grab fields from associations - multiple levels deep
|
|
124
|
-
# if necessary.
|
|
125
|
-
#
|
|
126
|
-
# define_index do
|
|
127
|
-
# indexes tags.name, :as => :tag
|
|
128
|
-
# indexes articles.content
|
|
129
|
-
# indexes orders.line_items.product.name, :as => :product
|
|
130
|
-
# end
|
|
131
|
-
#
|
|
132
|
-
# And it will automatically concatenate multiple fields:
|
|
133
|
-
#
|
|
134
|
-
# define_index do
|
|
135
|
-
# indexes [author.first_name, author.last_name], :as => :author
|
|
136
|
-
# end
|
|
137
|
-
#
|
|
138
|
-
# The #indexes method is for fields - if you want attributes, use
|
|
139
|
-
# #has instead. All the same rules apply - but keep in mind that
|
|
140
|
-
# attributes are for sorting, grouping and filtering, not searching.
|
|
141
|
-
#
|
|
142
|
-
# define_index do
|
|
143
|
-
# # fields ...
|
|
144
|
-
#
|
|
145
|
-
# has created_at, updated_at
|
|
146
|
-
# end
|
|
147
|
-
#
|
|
148
|
-
# One last feature is the delta index. This requires the model to
|
|
149
|
-
# have a boolean field named 'delta', and is enabled as follows:
|
|
150
|
-
#
|
|
151
|
-
# define_index do
|
|
152
|
-
# # fields ...
|
|
153
|
-
# # attributes ...
|
|
154
|
-
#
|
|
155
|
-
# set_property :delta => true
|
|
156
|
-
# end
|
|
157
|
-
#
|
|
158
|
-
# Check out the more detailed documentation for each of these methods
|
|
159
|
-
# at ThinkingSphinx::Index::Builder.
|
|
160
|
-
#
|
|
161
|
-
def define_index(name = nil, &block)
|
|
162
|
-
self.sphinx_index_blocks ||= []
|
|
163
|
-
self.sphinx_indexes ||= []
|
|
164
|
-
self.sphinx_facets ||= []
|
|
165
|
-
|
|
166
|
-
ThinkingSphinx.context.add_indexed_model self
|
|
167
|
-
|
|
168
|
-
if sphinx_index_blocks.empty?
|
|
169
|
-
before_validation :define_indexes
|
|
170
|
-
before_destroy :define_indexes
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
self.sphinx_index_blocks << lambda {
|
|
174
|
-
add_sphinx_index name, &block
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
include ThinkingSphinx::ActiveRecord::Scopes
|
|
178
|
-
include ThinkingSphinx::SearchMethods
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def define_indexes
|
|
182
|
-
superclass.define_indexes unless superclass == ::ActiveRecord::Base
|
|
183
|
-
|
|
184
|
-
return if sphinx_index_blocks.nil? ||
|
|
185
|
-
defined_indexes? ||
|
|
186
|
-
!ThinkingSphinx.define_indexes?
|
|
187
|
-
|
|
188
|
-
sphinx_index_blocks.each do |block|
|
|
189
|
-
block.call
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
self.defined_indexes = true
|
|
193
|
-
|
|
194
|
-
# We want to make sure that if the database doesn't exist, then Thinking
|
|
195
|
-
# Sphinx doesn't mind when running non-TS tasks (like db:create, db:drop
|
|
196
|
-
# and db:migrate). It's a bit hacky, but I can't think of a better way.
|
|
197
|
-
rescue StandardError => err
|
|
198
|
-
case err.class.name
|
|
199
|
-
when "Mysql::Error", "Mysql2::Error", "Java::JavaSql::SQLException", "ActiveRecord::StatementInvalid"
|
|
200
|
-
return
|
|
201
|
-
else
|
|
202
|
-
raise err
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
def add_sphinx_index(name, &block)
|
|
207
|
-
index = ThinkingSphinx::Index::Builder.generate self, name, &block
|
|
208
|
-
|
|
209
|
-
unless sphinx_indexes.any? { |i| i.name == index.name }
|
|
210
|
-
add_sphinx_callbacks_and_extend(index.delta?)
|
|
211
|
-
insert_sphinx_index index
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
def insert_sphinx_index(index)
|
|
216
|
-
self.sphinx_indexes += [index]
|
|
217
|
-
end
|
|
1
|
+
require 'active_record'
|
|
218
2
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
(sphinx_indexes.length > 0 || sphinx_index_blocks.length > 0)
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def indexed_by_sphinx?
|
|
226
|
-
sphinx_indexes && sphinx_indexes.length > 0
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
def delta_indexed_by_sphinx?
|
|
230
|
-
sphinx_indexes && sphinx_indexes.any? { |index| index.delta? }
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
def sphinx_index_names
|
|
234
|
-
define_indexes
|
|
235
|
-
sphinx_indexes.collect(&:all_names).flatten
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def core_index_names
|
|
239
|
-
define_indexes
|
|
240
|
-
sphinx_indexes.collect(&:core_name)
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def delta_index_names
|
|
244
|
-
define_indexes
|
|
245
|
-
sphinx_indexes.select(&:delta?).collect(&:delta_name)
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
def to_riddle
|
|
249
|
-
define_indexes
|
|
250
|
-
sphinx_database_adapter.setup
|
|
251
|
-
|
|
252
|
-
local_sphinx_indexes.collect { |index|
|
|
253
|
-
index.to_riddle(sphinx_offset)
|
|
254
|
-
}.flatten
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
def source_of_sphinx_index
|
|
258
|
-
define_indexes
|
|
259
|
-
possible_models = self.sphinx_indexes.collect { |index| index.model }
|
|
260
|
-
return self if possible_models.include?(self)
|
|
261
|
-
|
|
262
|
-
parent = self.superclass
|
|
263
|
-
while !possible_models.include?(parent) && parent != ::ActiveRecord::Base
|
|
264
|
-
parent = parent.superclass
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
return parent
|
|
268
|
-
end
|
|
269
|
-
|
|
270
|
-
def delete_in_index(index, document_id)
|
|
271
|
-
return unless ThinkingSphinx.sphinx_running?
|
|
272
|
-
|
|
273
|
-
ThinkingSphinx::Connection.take do |client|
|
|
274
|
-
client.update index, ['sphinx_deleted'], {document_id => [1]}
|
|
275
|
-
end
|
|
276
|
-
rescue Riddle::ConnectionError, Riddle::ResponseError,
|
|
277
|
-
ThinkingSphinx::SphinxError, Errno::ETIMEDOUT, Timeout::Error
|
|
278
|
-
# Not the end of the world if Sphinx isn't running.
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
def sphinx_offset
|
|
282
|
-
ThinkingSphinx.context.superclass_indexed_models.
|
|
283
|
-
index eldest_indexed_ancestor
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
# Temporarily disable delta indexing inside a block, then perform a
|
|
287
|
-
# single rebuild of index at the end.
|
|
288
|
-
#
|
|
289
|
-
# Useful when performing updates to batches of models to prevent
|
|
290
|
-
# the delta index being rebuilt after each individual update.
|
|
291
|
-
#
|
|
292
|
-
# In the following example, the delta index will only be rebuilt
|
|
293
|
-
# once, not 10 times.
|
|
294
|
-
#
|
|
295
|
-
# SomeModel.suspended_delta do
|
|
296
|
-
# 10.times do
|
|
297
|
-
# SomeModel.create( ... )
|
|
298
|
-
# end
|
|
299
|
-
# end
|
|
300
|
-
#
|
|
301
|
-
def suspended_delta(reindex_after = true, &block)
|
|
302
|
-
define_indexes
|
|
303
|
-
original_setting = ThinkingSphinx.deltas_suspended?
|
|
304
|
-
ThinkingSphinx.deltas_suspended = true
|
|
305
|
-
begin
|
|
306
|
-
yield
|
|
307
|
-
ensure
|
|
308
|
-
ThinkingSphinx.deltas_suspended = original_setting
|
|
309
|
-
self.index_delta if reindex_after && !original_setting
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
private
|
|
314
|
-
|
|
315
|
-
def local_sphinx_indexes
|
|
316
|
-
(sphinx_indexes || []).select { |index|
|
|
317
|
-
index.model == self
|
|
318
|
-
}
|
|
319
|
-
end
|
|
320
|
-
|
|
321
|
-
def add_sphinx_callbacks_and_extend(delta = false)
|
|
322
|
-
unless indexed_by_sphinx?
|
|
323
|
-
after_destroy :toggle_deleted
|
|
324
|
-
|
|
325
|
-
include ThinkingSphinx::ActiveRecord::AttributeUpdates
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
if delta && !delta_indexed_by_sphinx?
|
|
329
|
-
include ThinkingSphinx::ActiveRecord::Delta
|
|
330
|
-
|
|
331
|
-
before_save :toggle_delta
|
|
332
|
-
after_commit :index_delta
|
|
333
|
-
end
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
def eldest_indexed_ancestor
|
|
337
|
-
ancestors.reverse.detect { |ancestor|
|
|
338
|
-
ThinkingSphinx.context.indexed_models.include?(ancestor.name)
|
|
339
|
-
}.name
|
|
340
|
-
end
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
attr_accessor :excerpts
|
|
344
|
-
attr_accessor :sphinx_attributes
|
|
345
|
-
attr_accessor :matching_fields
|
|
346
|
-
|
|
347
|
-
def toggle_deleted
|
|
348
|
-
return unless ThinkingSphinx.updates_enabled?
|
|
349
|
-
|
|
350
|
-
self.class.core_index_names.each do |index_name|
|
|
351
|
-
self.class.delete_in_index index_name, self.sphinx_document_id
|
|
352
|
-
end
|
|
353
|
-
self.class.delta_index_names.each do |index_name|
|
|
354
|
-
self.class.delete_in_index index_name, self.sphinx_document_id
|
|
355
|
-
end if self.class.delta_indexed_by_sphinx? && toggled_delta?
|
|
356
|
-
|
|
357
|
-
rescue ::ThinkingSphinx::ConnectionError
|
|
358
|
-
# nothing
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
# Returns the unique integer id for the object. This method uses the
|
|
362
|
-
# attribute hash to get around ActiveRecord always mapping the #id method
|
|
363
|
-
# to whatever the real primary key is (which may be a unique string hash).
|
|
364
|
-
#
|
|
365
|
-
# @return [Integer] Unique record id for the purposes of Sphinx.
|
|
366
|
-
#
|
|
367
|
-
def primary_key_for_sphinx
|
|
368
|
-
read_attribute(self.class.primary_key_for_sphinx)
|
|
369
|
-
end
|
|
370
|
-
|
|
371
|
-
def sphinx_document_id
|
|
372
|
-
primary_key_for_sphinx * ThinkingSphinx.context.indexed_models.size +
|
|
373
|
-
self.class.sphinx_offset
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
private
|
|
3
|
+
module ThinkingSphinx::ActiveRecord
|
|
4
|
+
module Callbacks; end
|
|
5
|
+
end
|
|
377
6
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
7
|
+
require 'thinking_sphinx/active_record/property'
|
|
8
|
+
require 'thinking_sphinx/active_record/association'
|
|
9
|
+
require 'thinking_sphinx/active_record/association_proxy'
|
|
10
|
+
require 'thinking_sphinx/active_record/associations'
|
|
11
|
+
require 'thinking_sphinx/active_record/attribute'
|
|
12
|
+
require 'thinking_sphinx/active_record/base'
|
|
13
|
+
require 'thinking_sphinx/active_record/column'
|
|
14
|
+
require 'thinking_sphinx/active_record/database_adapters'
|
|
15
|
+
require 'thinking_sphinx/active_record/field'
|
|
16
|
+
require 'thinking_sphinx/active_record/index'
|
|
17
|
+
require 'thinking_sphinx/active_record/interpreter'
|
|
18
|
+
require 'thinking_sphinx/active_record/log_subscriber'
|
|
19
|
+
require 'thinking_sphinx/active_record/property_sql_presenter'
|
|
20
|
+
require 'thinking_sphinx/active_record/sql_builder'
|
|
21
|
+
require 'thinking_sphinx/active_record/sql_source'
|
|
381
22
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
end
|
|
386
|
-
end
|
|
23
|
+
require 'thinking_sphinx/active_record/callbacks/delete_callbacks'
|
|
24
|
+
require 'thinking_sphinx/active_record/callbacks/delta_callbacks'
|
|
25
|
+
require 'thinking_sphinx/active_record/callbacks/update_callbacks'
|