thinking-sphinx 3.1.4 → 6.0.0
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.
- checksums.yaml +5 -5
- data/.circleci/config.yml +99 -0
- data/.github/actions/test/action.yml +46 -0
- data/.github/workflows/ci.yml +75 -0
- data/.gitignore +7 -2
- data/.travis.yml +31 -16
- data/Appraisals +68 -12
- data/CHANGELOG.markdown +782 -0
- data/Gemfile +13 -4
- data/Procfile.support +2 -0
- data/README.textile +41 -27
- data/Rakefile +2 -0
- data/bin/console +15 -0
- data/bin/loadsphinx +99 -0
- data/bin/testmatrix +48 -0
- data/lib/thinking/sphinx.rb +2 -0
- data/lib/thinking-sphinx.rb +2 -0
- data/lib/thinking_sphinx/active_record/association.rb +2 -0
- data/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +3 -1
- data/lib/thinking_sphinx/active_record/association_proxy/attribute_matcher.rb +2 -0
- data/lib/thinking_sphinx/active_record/association_proxy.rb +3 -2
- data/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb +3 -1
- data/lib/thinking_sphinx/active_record/attribute/type.rb +20 -4
- data/lib/thinking_sphinx/active_record/attribute/values.rb +2 -0
- data/lib/thinking_sphinx/active_record/attribute.rb +2 -0
- data/lib/thinking_sphinx/active_record/base.rb +43 -11
- data/lib/thinking_sphinx/active_record/callbacks/association_delta_callbacks.rb +21 -0
- data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +15 -9
- data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +20 -5
- data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +18 -4
- data/lib/thinking_sphinx/active_record/column.rb +2 -0
- data/lib/thinking_sphinx/active_record/column_sql_presenter.rb +7 -1
- data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +2 -0
- data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +9 -1
- data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +2 -0
- data/lib/thinking_sphinx/active_record/database_adapters.rb +3 -1
- data/lib/thinking_sphinx/active_record/depolymorph/association_reflection.rb +32 -0
- data/lib/thinking_sphinx/active_record/depolymorph/base_reflection.rb +32 -0
- data/lib/thinking_sphinx/active_record/depolymorph/conditions_reflection.rb +40 -0
- data/lib/thinking_sphinx/active_record/depolymorph/overridden_reflection.rb +50 -0
- data/lib/thinking_sphinx/active_record/depolymorph/scoped_reflection.rb +26 -0
- data/lib/thinking_sphinx/active_record/field.rb +2 -0
- data/lib/thinking_sphinx/active_record/filter_reflection.rb +13 -71
- data/lib/thinking_sphinx/active_record/index.rb +7 -5
- data/lib/thinking_sphinx/active_record/interpreter.rb +6 -4
- data/lib/thinking_sphinx/active_record/join_association.rb +5 -1
- data/lib/thinking_sphinx/active_record/log_subscriber.rb +22 -3
- data/lib/thinking_sphinx/active_record/polymorpher.rb +2 -0
- data/lib/thinking_sphinx/active_record/property.rb +2 -0
- data/lib/thinking_sphinx/active_record/property_query.rb +4 -1
- data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +2 -0
- data/lib/thinking_sphinx/active_record/simple_many_query.rb +2 -0
- data/lib/thinking_sphinx/active_record/source_joins.rb +68 -0
- data/lib/thinking_sphinx/active_record/sql_builder/clause_builder.rb +2 -0
- data/lib/thinking_sphinx/active_record/sql_builder/query.rb +13 -0
- data/lib/thinking_sphinx/active_record/sql_builder/statement.rb +2 -0
- data/lib/thinking_sphinx/active_record/sql_builder.rb +5 -18
- data/lib/thinking_sphinx/active_record/sql_source/template.rb +5 -3
- data/lib/thinking_sphinx/active_record/sql_source.rb +35 -9
- data/lib/thinking_sphinx/active_record.rb +14 -1
- data/lib/thinking_sphinx/attribute_types.rb +72 -0
- data/lib/thinking_sphinx/batched_search.rb +2 -0
- data/lib/thinking_sphinx/callbacks/appender.rb +63 -0
- data/lib/thinking_sphinx/callbacks.rb +29 -0
- data/lib/thinking_sphinx/capistrano/v2.rb +2 -0
- data/lib/thinking_sphinx/capistrano/v3.rb +2 -0
- data/lib/thinking_sphinx/capistrano.rb +2 -0
- data/lib/thinking_sphinx/commander.rb +27 -0
- data/lib/thinking_sphinx/commands/base.rb +53 -0
- data/lib/thinking_sphinx/commands/clear_real_time.rb +22 -0
- data/lib/thinking_sphinx/commands/clear_sql.rb +18 -0
- data/lib/thinking_sphinx/commands/configure.rb +15 -0
- data/lib/thinking_sphinx/commands/index_real_time.rb +15 -0
- data/lib/thinking_sphinx/commands/index_sql.rb +25 -0
- data/lib/thinking_sphinx/commands/merge.rb +27 -0
- data/lib/thinking_sphinx/commands/merge_and_update.rb +57 -0
- data/lib/thinking_sphinx/commands/prepare.rb +15 -0
- data/lib/thinking_sphinx/commands/rotate.rb +13 -0
- data/lib/thinking_sphinx/commands/running.rb +15 -0
- data/lib/thinking_sphinx/commands/start_attached.rb +22 -0
- data/lib/thinking_sphinx/commands/start_detached.rb +21 -0
- data/lib/thinking_sphinx/commands/stop.rb +24 -0
- data/lib/thinking_sphinx/commands.rb +20 -0
- data/lib/thinking_sphinx/configuration/consistent_ids.rb +2 -0
- data/lib/thinking_sphinx/configuration/defaults.rb +2 -0
- data/lib/thinking_sphinx/configuration/distributed_indices.rb +3 -1
- data/lib/thinking_sphinx/configuration/duplicate_names.rb +36 -0
- data/lib/thinking_sphinx/configuration/minimum_fields.rb +17 -12
- data/lib/thinking_sphinx/configuration.rb +90 -74
- data/lib/thinking_sphinx/connection/client.rb +74 -0
- data/lib/thinking_sphinx/connection/jruby.rb +58 -0
- data/lib/thinking_sphinx/connection/mri.rb +26 -0
- data/lib/thinking_sphinx/connection.rb +13 -114
- data/lib/thinking_sphinx/core/field.rb +2 -0
- data/lib/thinking_sphinx/core/index.rb +22 -2
- data/lib/thinking_sphinx/core/interpreter.rb +2 -0
- data/lib/thinking_sphinx/core/property.rb +2 -0
- data/lib/thinking_sphinx/core/settings.rb +2 -0
- data/lib/thinking_sphinx/core.rb +2 -0
- data/lib/thinking_sphinx/deletion.rb +33 -13
- data/lib/thinking_sphinx/deltas/default_delta.rb +3 -1
- data/lib/thinking_sphinx/deltas/delete_job.rb +16 -4
- data/lib/thinking_sphinx/deltas/index_job.rb +14 -2
- data/lib/thinking_sphinx/deltas.rb +2 -0
- data/lib/thinking_sphinx/distributed/index.rb +25 -3
- data/lib/thinking_sphinx/distributed.rb +2 -0
- data/lib/thinking_sphinx/errors.rb +47 -3
- data/lib/thinking_sphinx/excerpter.rb +2 -0
- data/lib/thinking_sphinx/facet.rb +4 -3
- data/lib/thinking_sphinx/facet_search.rb +4 -2
- data/lib/thinking_sphinx/float_formatter.rb +2 -0
- data/lib/thinking_sphinx/frameworks/plain.rb +2 -0
- data/lib/thinking_sphinx/frameworks/rails.rb +2 -0
- data/lib/thinking_sphinx/frameworks.rb +2 -0
- data/lib/thinking_sphinx/guard/file.rb +3 -1
- data/lib/thinking_sphinx/guard/files.rb +2 -0
- data/lib/thinking_sphinx/guard/none.rb +7 -0
- data/lib/thinking_sphinx/guard.rb +3 -0
- data/lib/thinking_sphinx/hooks/guard_presence.rb +34 -0
- data/lib/thinking_sphinx/index.rb +2 -0
- data/lib/thinking_sphinx/index_set.rb +27 -4
- data/lib/thinking_sphinx/indexing_strategies/all_at_once.rb +9 -0
- data/lib/thinking_sphinx/indexing_strategies/one_at_a_time.rb +16 -0
- data/lib/thinking_sphinx/interfaces/base.rb +13 -0
- data/lib/thinking_sphinx/interfaces/daemon.rb +27 -0
- data/lib/thinking_sphinx/interfaces/real_time.rb +46 -0
- data/lib/thinking_sphinx/interfaces/sql.rb +53 -0
- data/lib/thinking_sphinx/interfaces.rb +10 -0
- data/lib/thinking_sphinx/logger.rb +2 -0
- data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +6 -4
- data/lib/thinking_sphinx/masks/pagination_mask.rb +2 -0
- data/lib/thinking_sphinx/masks/scopes_mask.rb +8 -0
- data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +3 -1
- data/lib/thinking_sphinx/masks.rb +2 -0
- data/lib/thinking_sphinx/middlewares/active_record_translator.rb +32 -9
- data/lib/thinking_sphinx/middlewares/geographer.rb +2 -0
- data/lib/thinking_sphinx/middlewares/glazier.rb +14 -1
- data/lib/thinking_sphinx/middlewares/ids_only.rb +2 -0
- data/lib/thinking_sphinx/middlewares/inquirer.rb +3 -1
- data/lib/thinking_sphinx/middlewares/middleware.rb +2 -0
- data/lib/thinking_sphinx/middlewares/sphinxql.rb +18 -16
- data/lib/thinking_sphinx/middlewares/stale_id_checker.rb +3 -1
- data/lib/thinking_sphinx/middlewares/stale_id_filter.rb +4 -2
- data/lib/thinking_sphinx/middlewares/valid_options.rb +25 -0
- data/lib/thinking_sphinx/middlewares.rb +7 -3
- data/lib/thinking_sphinx/panes/attributes_pane.rb +2 -0
- data/lib/thinking_sphinx/panes/distance_pane.rb +2 -0
- data/lib/thinking_sphinx/panes/excerpts_pane.rb +2 -0
- data/lib/thinking_sphinx/panes/weight_pane.rb +3 -1
- data/lib/thinking_sphinx/panes.rb +2 -0
- data/lib/thinking_sphinx/processor.rb +71 -0
- data/lib/thinking_sphinx/query.rb +2 -0
- data/lib/thinking_sphinx/railtie.rb +29 -2
- data/lib/thinking_sphinx/rake_interface.rb +14 -69
- data/lib/thinking_sphinx/real_time/attribute.rb +9 -1
- data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +17 -7
- data/lib/thinking_sphinx/real_time/field.rb +2 -0
- data/lib/thinking_sphinx/real_time/index/template.rb +19 -1
- data/lib/thinking_sphinx/real_time/index.rb +11 -5
- data/lib/thinking_sphinx/real_time/interpreter.rb +10 -6
- data/lib/thinking_sphinx/real_time/populator.rb +12 -14
- data/lib/thinking_sphinx/real_time/processor.rb +36 -0
- data/lib/thinking_sphinx/real_time/property.rb +3 -5
- data/lib/thinking_sphinx/real_time/transcribe_instance.rb +38 -0
- data/lib/thinking_sphinx/real_time/transcriber.rb +63 -15
- data/lib/thinking_sphinx/real_time/translator.rb +39 -0
- data/lib/thinking_sphinx/real_time.rb +22 -1
- data/lib/thinking_sphinx/scopes.rb +6 -0
- data/lib/thinking_sphinx/search/batch_inquirer.rb +2 -0
- data/lib/thinking_sphinx/search/context.rb +11 -0
- data/lib/thinking_sphinx/search/glaze.rb +2 -0
- data/lib/thinking_sphinx/search/merger.rb +2 -0
- data/lib/thinking_sphinx/search/query.rb +9 -1
- data/lib/thinking_sphinx/search/stale_ids_exception.rb +7 -3
- data/lib/thinking_sphinx/search.rb +30 -2
- data/lib/thinking_sphinx/settings.rb +128 -0
- data/lib/thinking_sphinx/sinatra.rb +3 -1
- data/lib/thinking_sphinx/subscribers/populator_subscriber.rb +19 -5
- data/lib/thinking_sphinx/tasks.rb +55 -28
- data/lib/thinking_sphinx/test.rb +3 -1
- data/lib/thinking_sphinx/utf8.rb +2 -0
- data/lib/thinking_sphinx/wildcard.rb +3 -1
- data/lib/thinking_sphinx/with_output.rb +13 -0
- data/lib/thinking_sphinx.rb +35 -4
- data/spec/acceptance/association_scoping_spec.rb +7 -5
- data/spec/acceptance/attribute_access_spec.rb +29 -12
- data/spec/acceptance/attribute_updates_spec.rb +5 -3
- data/spec/acceptance/batch_searching_spec.rb +6 -4
- data/spec/acceptance/big_integers_spec.rb +9 -7
- data/spec/acceptance/excerpts_spec.rb +11 -10
- data/spec/acceptance/facets_spec.rb +29 -16
- data/spec/acceptance/geosearching_spec.rb +22 -10
- data/spec/acceptance/grouping_by_attributes_spec.rb +30 -28
- data/spec/acceptance/index_options_spec.rb +18 -16
- data/spec/acceptance/indexing_spec.rb +5 -3
- data/spec/acceptance/merging_spec.rb +90 -0
- data/spec/acceptance/paginating_search_results_spec.rb +21 -3
- data/spec/acceptance/real_time_updates_spec.rb +103 -5
- data/spec/acceptance/remove_deleted_records_spec.rb +64 -8
- data/spec/acceptance/search_counts_spec.rb +4 -2
- data/spec/acceptance/search_for_just_ids_spec.rb +4 -2
- data/spec/acceptance/searching_across_models_spec.rb +15 -6
- data/spec/acceptance/searching_across_schemas_spec.rb +12 -10
- data/spec/acceptance/searching_on_fields_spec.rb +11 -9
- data/spec/acceptance/searching_with_filters_spec.rb +35 -20
- data/spec/acceptance/searching_with_sti_spec.rb +11 -9
- data/spec/acceptance/searching_within_a_model_spec.rb +44 -17
- data/spec/acceptance/sorting_search_results_spec.rb +21 -19
- data/spec/acceptance/spec_helper.rb +2 -13
- data/spec/acceptance/specifying_sql_spec.rb +118 -62
- data/spec/acceptance/sphinx_scopes_spec.rb +30 -21
- data/spec/acceptance/sql_deltas_spec.rb +35 -9
- data/spec/acceptance/support/database_cleaner.rb +3 -1
- data/spec/acceptance/support/sphinx_controller.rb +25 -9
- data/spec/acceptance/support/sphinx_helpers.rb +17 -2
- data/spec/acceptance/suspended_deltas_spec.rb +14 -12
- data/spec/fixtures/database.yml +1 -1
- data/spec/internal/app/indices/admin_person_index.rb +6 -0
- data/spec/internal/app/indices/album_index.rb +9 -0
- data/spec/internal/app/indices/animal_index.rb +2 -0
- data/spec/internal/app/indices/article_index.rb +10 -3
- data/spec/internal/app/indices/bird_index.rb +2 -0
- data/spec/internal/app/indices/book_index.rb +4 -1
- data/spec/internal/app/indices/car_index.rb +2 -0
- data/spec/internal/app/indices/city_index.rb +2 -0
- data/spec/internal/app/indices/colour_index.rb +7 -0
- data/spec/internal/app/indices/product_index.rb +3 -2
- data/spec/internal/app/indices/tee_index.rb +3 -1
- data/spec/internal/app/indices/user_index.rb +2 -0
- data/spec/internal/app/models/admin/person.rb +6 -0
- data/spec/internal/app/models/album.rb +25 -0
- data/spec/internal/app/models/animal.rb +3 -0
- data/spec/internal/app/models/article.rb +4 -0
- data/spec/internal/app/models/bird.rb +3 -0
- data/spec/internal/app/models/book.rb +9 -5
- data/spec/internal/app/models/car.rb +3 -1
- data/spec/internal/app/models/categorisation.rb +10 -1
- data/spec/internal/app/models/category.rb +2 -0
- data/spec/internal/app/models/city.rb +4 -0
- data/spec/internal/app/models/colour.rb +4 -0
- data/spec/internal/app/models/event.rb +2 -0
- data/spec/internal/app/models/flightless_bird.rb +2 -0
- data/spec/internal/app/models/genre.rb +2 -0
- data/spec/internal/app/models/hardcover.rb +2 -0
- data/spec/internal/app/models/mammal.rb +2 -0
- data/spec/internal/app/models/manufacturer.rb +2 -0
- data/spec/internal/app/models/product.rb +3 -1
- data/spec/internal/app/models/tag.rb +2 -0
- data/spec/internal/app/models/tagging.rb +2 -0
- data/spec/internal/app/models/tee.rb +7 -0
- data/spec/internal/app/models/tweet.rb +2 -0
- data/spec/internal/app/models/user.rb +4 -0
- data/spec/internal/config/database.yml +12 -1
- data/spec/internal/db/schema.rb +13 -1
- data/spec/spec_helper.rb +12 -1
- data/spec/support/json_column.rb +35 -0
- data/spec/support/multi_schema.rb +5 -1
- data/spec/support/mysql.rb +25 -0
- data/spec/support/sphinx_yaml_helpers.rb +8 -1
- data/spec/thinking_sphinx/active_record/association_spec.rb +3 -1
- data/spec/thinking_sphinx/active_record/attribute/type_spec.rb +43 -38
- data/spec/thinking_sphinx/active_record/base_spec.rb +31 -29
- data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +81 -10
- data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +56 -29
- data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +27 -10
- data/spec/thinking_sphinx/active_record/column_spec.rb +15 -13
- data/spec/thinking_sphinx/active_record/column_sql_presenter_spec.rb +39 -0
- data/spec/thinking_sphinx/active_record/database_adapters/abstract_adapter_spec.rb +7 -5
- data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +26 -12
- data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +15 -13
- data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +50 -48
- data/spec/thinking_sphinx/active_record/field_spec.rb +9 -7
- data/spec/thinking_sphinx/active_record/filter_reflection_spec.rb +113 -80
- data/spec/thinking_sphinx/active_record/index_spec.rb +41 -37
- data/spec/thinking_sphinx/active_record/interpreter_spec.rb +62 -59
- data/spec/thinking_sphinx/active_record/polymorpher_spec.rb +16 -14
- data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +69 -67
- data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +146 -154
- data/spec/thinking_sphinx/active_record/sql_source_spec.rb +185 -109
- data/spec/thinking_sphinx/attribute_types_spec.rb +52 -0
- data/spec/thinking_sphinx/commands/clear_real_time_spec.rb +46 -0
- data/spec/thinking_sphinx/commands/clear_sql_spec.rb +52 -0
- data/spec/thinking_sphinx/commands/configure_spec.rb +31 -0
- data/spec/thinking_sphinx/commands/index_real_time_spec.rb +33 -0
- data/spec/thinking_sphinx/commands/index_sql_spec.rb +86 -0
- data/spec/thinking_sphinx/commands/merge_and_update_spec.rb +106 -0
- data/spec/thinking_sphinx/commands/merge_spec.rb +48 -0
- data/spec/thinking_sphinx/commands/prepare_spec.rb +31 -0
- data/spec/thinking_sphinx/commands/running_spec.rb +30 -0
- data/spec/thinking_sphinx/commands/start_detached_spec.rb +67 -0
- data/spec/thinking_sphinx/commands/stop_spec.rb +63 -0
- data/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +60 -0
- data/spec/thinking_sphinx/configuration_spec.rb +247 -94
- data/spec/thinking_sphinx/connection/mri_spec.rb +49 -0
- data/spec/thinking_sphinx/connection_spec.rb +15 -13
- data/spec/thinking_sphinx/deletion_spec.rb +17 -17
- data/spec/thinking_sphinx/deltas/default_delta_spec.rb +28 -21
- data/spec/thinking_sphinx/deltas_spec.rb +14 -12
- data/spec/thinking_sphinx/errors_spec.rb +59 -27
- data/spec/thinking_sphinx/excerpter_spec.rb +12 -9
- data/spec/thinking_sphinx/facet_search_spec.rb +24 -22
- data/spec/thinking_sphinx/hooks/guard_presence_spec.rb +30 -0
- data/spec/thinking_sphinx/index_set_spec.rb +59 -18
- data/spec/thinking_sphinx/index_spec.rb +28 -26
- data/spec/thinking_sphinx/interfaces/daemon_spec.rb +60 -0
- data/spec/thinking_sphinx/interfaces/real_time_spec.rb +109 -0
- data/spec/thinking_sphinx/interfaces/sql_spec.rb +122 -0
- data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +22 -20
- data/spec/thinking_sphinx/masks/scopes_mask_spec.rb +20 -18
- data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +45 -21
- data/spec/thinking_sphinx/middlewares/geographer_spec.rb +11 -9
- data/spec/thinking_sphinx/middlewares/glazier_spec.rb +12 -9
- data/spec/thinking_sphinx/middlewares/inquirer_spec.rb +9 -7
- data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +60 -58
- data/spec/thinking_sphinx/middlewares/stale_id_checker_spec.rb +7 -4
- data/spec/thinking_sphinx/middlewares/stale_id_filter_spec.rb +39 -17
- data/spec/thinking_sphinx/middlewares/valid_options_spec.rb +51 -0
- data/spec/thinking_sphinx/panes/attributes_pane_spec.rb +3 -1
- data/spec/thinking_sphinx/panes/distance_pane_spec.rb +6 -4
- data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +8 -6
- data/spec/thinking_sphinx/panes/weight_pane_spec.rb +4 -2
- data/spec/thinking_sphinx/rake_interface_spec.rb +17 -235
- data/spec/thinking_sphinx/real_time/attribute_spec.rb +15 -13
- data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +114 -28
- data/spec/thinking_sphinx/real_time/field_spec.rb +16 -14
- data/spec/thinking_sphinx/real_time/index_spec.rb +83 -32
- data/spec/thinking_sphinx/real_time/interpreter_spec.rb +44 -42
- data/spec/thinking_sphinx/real_time/transcribe_instance_spec.rb +35 -0
- data/spec/thinking_sphinx/real_time/transcriber_spec.rb +109 -0
- data/spec/thinking_sphinx/real_time/translator_spec.rb +17 -0
- data/spec/thinking_sphinx/scopes_spec.rb +11 -5
- data/spec/thinking_sphinx/search/glaze_spec.rb +17 -15
- data/spec/thinking_sphinx/search/query_spec.rb +19 -10
- data/spec/thinking_sphinx/search_spec.rb +30 -28
- data/spec/thinking_sphinx/wildcard_spec.rb +18 -11
- data/spec/thinking_sphinx_spec.rb +10 -7
- data/thinking-sphinx.gemspec +17 -10
- metadata +157 -49
- data/HISTORY +0 -248
- data/gemfiles/.gitignore +0 -1
- data/gemfiles/rails_3_2.gemfile +0 -11
- data/gemfiles/rails_4_0.gemfile +0 -11
- data/gemfiles/rails_4_1.gemfile +0 -11
- data/gemfiles/rails_4_2.gemfile +0 -11
- data/lib/thinking_sphinx/controller.rb +0 -10
- data/lib/thinking_sphinx/middlewares/utf8.rb +0 -27
- data/lib/thinking_sphinx/sphinxql.rb +0 -23
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'acceptance/spec_helper'
|
|
2
4
|
|
|
3
5
|
describe 'specifying SQL for index definitions' do
|
|
@@ -8,7 +10,7 @@ describe 'specifying SQL for index definitions' do
|
|
|
8
10
|
join user
|
|
9
11
|
}
|
|
10
12
|
index.render
|
|
11
|
-
index.sources.first.sql_query.
|
|
13
|
+
expect(index.sources.first.sql_query).to match(/LEFT OUTER JOIN .users./)
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
it "handles deep joins" do
|
|
@@ -20,8 +22,8 @@ describe 'specifying SQL for index definitions' do
|
|
|
20
22
|
index.render
|
|
21
23
|
|
|
22
24
|
query = index.sources.first.sql_query
|
|
23
|
-
query.
|
|
24
|
-
query.
|
|
25
|
+
expect(query).to match(/LEFT OUTER JOIN .users./)
|
|
26
|
+
expect(query).to match(/LEFT OUTER JOIN .articles./)
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
it "handles has-many :through joins" do
|
|
@@ -32,8 +34,8 @@ describe 'specifying SQL for index definitions' do
|
|
|
32
34
|
index.render
|
|
33
35
|
|
|
34
36
|
query = index.sources.first.sql_query
|
|
35
|
-
query.
|
|
36
|
-
query.
|
|
37
|
+
expect(query).to match(/LEFT OUTER JOIN .taggings./)
|
|
38
|
+
expect(query).to match(/LEFT OUTER JOIN .tags./)
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
it "handles custom join SQL statements" do
|
|
@@ -45,7 +47,7 @@ describe 'specifying SQL for index definitions' do
|
|
|
45
47
|
index.render
|
|
46
48
|
|
|
47
49
|
query = index.sources.first.sql_query
|
|
48
|
-
query.
|
|
50
|
+
expect(query).to match(/INNER JOIN foo ON foo.x = bar.y/)
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
it "handles GROUP BY clauses" do
|
|
@@ -57,7 +59,7 @@ describe 'specifying SQL for index definitions' do
|
|
|
57
59
|
index.render
|
|
58
60
|
|
|
59
61
|
query = index.sources.first.sql_query
|
|
60
|
-
query.
|
|
62
|
+
expect(query).to match(/GROUP BY .articles.\..id., .?articles.?\..title., .?articles.?\..id., lat/)
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
it "handles WHERE clauses" do
|
|
@@ -69,7 +71,7 @@ describe 'specifying SQL for index definitions' do
|
|
|
69
71
|
index.render
|
|
70
72
|
|
|
71
73
|
query = index.sources.first.sql_query
|
|
72
|
-
query.
|
|
74
|
+
expect(query).to match(/WHERE .+title != 'secret'.+ GROUP BY/)
|
|
73
75
|
end
|
|
74
76
|
|
|
75
77
|
it "handles manual MVA declarations" do
|
|
@@ -81,7 +83,7 @@ describe 'specifying SQL for index definitions' do
|
|
|
81
83
|
}
|
|
82
84
|
index.render
|
|
83
85
|
|
|
84
|
-
index.sources.first.sql_attr_multi.
|
|
86
|
+
expect(index.sources.first.sql_attr_multi).to eq(['uint tag_ids from field'])
|
|
85
87
|
end
|
|
86
88
|
|
|
87
89
|
it "provides the sanitize_sql helper within the index definition block" do
|
|
@@ -93,7 +95,7 @@ describe 'specifying SQL for index definitions' do
|
|
|
93
95
|
index.render
|
|
94
96
|
|
|
95
97
|
query = index.sources.first.sql_query
|
|
96
|
-
query.
|
|
98
|
+
expect(query).to match(/WHERE .+title != 'secret'.+ GROUP BY/)
|
|
97
99
|
end
|
|
98
100
|
|
|
99
101
|
it "escapes new lines in SQL snippets" do
|
|
@@ -111,7 +113,7 @@ describe 'specifying SQL for index definitions' do
|
|
|
111
113
|
index.render
|
|
112
114
|
|
|
113
115
|
query = index.sources.first.sql_query
|
|
114
|
-
query.
|
|
116
|
+
expect(query).to match(/\\\n/)
|
|
115
117
|
end
|
|
116
118
|
|
|
117
119
|
it "joins each polymorphic relation" do
|
|
@@ -123,9 +125,9 @@ describe 'specifying SQL for index definitions' do
|
|
|
123
125
|
index.render
|
|
124
126
|
|
|
125
127
|
query = index.sources.first.sql_query
|
|
126
|
-
query.
|
|
127
|
-
query.
|
|
128
|
-
query.
|
|
128
|
+
expect(query).to match(/LEFT OUTER JOIN .articles. ON .articles.\..id. = .events.\..eventable_id. AND .events.\..eventable_type. = 'Article'/)
|
|
129
|
+
expect(query).to match(/LEFT OUTER JOIN .books. ON .books.\..id. = .events.\..eventable_id. AND .events.\..eventable_type. = 'Book'/)
|
|
130
|
+
expect(query).to match(/.articles.\..title., .books.\..title./)
|
|
129
131
|
end if ActiveRecord::VERSION::MAJOR > 3
|
|
130
132
|
|
|
131
133
|
it "concatenates references that have column" do
|
|
@@ -137,9 +139,9 @@ describe 'specifying SQL for index definitions' do
|
|
|
137
139
|
index.render
|
|
138
140
|
|
|
139
141
|
query = index.sources.first.sql_query
|
|
140
|
-
query.
|
|
141
|
-
query.
|
|
142
|
-
query.
|
|
142
|
+
expect(query).to match(/LEFT OUTER JOIN .articles. ON .articles.\..id. = .events.\..eventable_id. AND .events.\..eventable_type. = 'Article'/)
|
|
143
|
+
expect(query).not_to match(/articles\..title., users\..title./)
|
|
144
|
+
expect(query).to match(/.articles.\..title./)
|
|
143
145
|
end if ActiveRecord::VERSION::MAJOR > 3
|
|
144
146
|
|
|
145
147
|
it "respects deeper associations through polymorphic joins" do
|
|
@@ -151,13 +153,31 @@ describe 'specifying SQL for index definitions' do
|
|
|
151
153
|
index.render
|
|
152
154
|
|
|
153
155
|
query = index.sources.first.sql_query
|
|
154
|
-
query.
|
|
155
|
-
query.
|
|
156
|
-
query.
|
|
156
|
+
expect(query).to match(/LEFT OUTER JOIN .articles. ON .articles.\..id. = .events.\..eventable_id. AND .events.\..eventable_type. = 'Article'/)
|
|
157
|
+
expect(query).to match(/LEFT OUTER JOIN .users. ON .users.\..id. = .articles.\..user_id./)
|
|
158
|
+
expect(query).to match(/.users.\..name./)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "allows for STI mixed with polymorphic joins" do
|
|
162
|
+
index = ThinkingSphinx::ActiveRecord::Index.new(:event)
|
|
163
|
+
index.definition_block = Proc.new {
|
|
164
|
+
indexes eventable.name, :as => :name
|
|
165
|
+
polymorphs eventable, :to => %w(Bird Car)
|
|
166
|
+
}
|
|
167
|
+
index.render
|
|
168
|
+
|
|
169
|
+
query = index.sources.first.sql_query
|
|
170
|
+
expect(query).to match(/LEFT OUTER JOIN .animals. ON .animals.\..id. = .events.\..eventable_id. .* AND .events.\..eventable_type. = 'Animal'/)
|
|
171
|
+
expect(query).to match(/LEFT OUTER JOIN .cars. ON .cars.\..id. = .events.\..eventable_id. AND .events.\..eventable_type. = 'Car'/)
|
|
172
|
+
expect(query).to match(/.animals.\..name., .cars.\..name./)
|
|
157
173
|
end
|
|
158
174
|
end if ActiveRecord::VERSION::MAJOR > 3
|
|
159
175
|
|
|
160
176
|
describe 'separate queries for MVAs' do
|
|
177
|
+
def id_type
|
|
178
|
+
ActiveRecord::VERSION::STRING.to_f > 5.0 ? 'bigint' : 'uint'
|
|
179
|
+
end
|
|
180
|
+
|
|
161
181
|
let(:index) { ThinkingSphinx::ActiveRecord::Index.new(:article) }
|
|
162
182
|
let(:count) { ThinkingSphinx::Configuration.instance.indices.count }
|
|
163
183
|
let(:source) { index.sources.first }
|
|
@@ -174,8 +194,33 @@ describe 'separate queries for MVAs' do
|
|
|
174
194
|
}
|
|
175
195
|
declaration, query = attribute.split(/;\s+/)
|
|
176
196
|
|
|
177
|
-
declaration.
|
|
178
|
-
query.
|
|
197
|
+
expect(declaration).to eq("uint tag_ids from query")
|
|
198
|
+
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .taggings.\..tag_id. AS .tag_ids. FROM .taggings.\s? WHERE \(.taggings.\..article_id. IS NOT NULL\)$/)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it "does not include attributes sourced via separate queries" do
|
|
202
|
+
index.definition_block = Proc.new {
|
|
203
|
+
indexes title
|
|
204
|
+
has taggings.tag_id, :as => :tag_ids, :source => :query
|
|
205
|
+
}
|
|
206
|
+
index.render
|
|
207
|
+
|
|
208
|
+
# We don't want it in the SELECT, JOIN or GROUP clauses. This should catch
|
|
209
|
+
# them all.
|
|
210
|
+
expect(source.sql_query).not_to include('taggings')
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "keeps the joins in for separately queried tables if they're used elsewhere" do
|
|
214
|
+
index.definition_block = Proc.new {
|
|
215
|
+
indexes taggings.tag.name, :as => :tag_names
|
|
216
|
+
has taggings.tag.created_at, :as => :tag_dates, :source => :query
|
|
217
|
+
}
|
|
218
|
+
index.render
|
|
219
|
+
|
|
220
|
+
expect(source.sql_query).to include('taggings')
|
|
221
|
+
expect(source.sql_query).to include('tags')
|
|
222
|
+
expect(source.sql_query).to_not match(/.tags.\..created_at./)
|
|
223
|
+
expect(source.sql_query).to match(/.tags.\..name./)
|
|
179
224
|
end
|
|
180
225
|
|
|
181
226
|
it "generates a SQL query with joins when appropriate for MVAs" do
|
|
@@ -190,8 +235,8 @@ describe 'separate queries for MVAs' do
|
|
|
190
235
|
}
|
|
191
236
|
declaration, query = attribute.split(/;\s+/)
|
|
192
237
|
|
|
193
|
-
declaration.
|
|
194
|
-
query.
|
|
238
|
+
expect(declaration).to eq("#{id_type} tag_ids from query")
|
|
239
|
+
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..id. AS .tag_ids. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id. WHERE \(.taggings.\..article_id. IS NOT NULL\)\s?$/)
|
|
195
240
|
end
|
|
196
241
|
|
|
197
242
|
it "respects has_many :through joins for MVA queries" do
|
|
@@ -206,8 +251,8 @@ describe 'separate queries for MVAs' do
|
|
|
206
251
|
}
|
|
207
252
|
declaration, query = attribute.split(/;\s+/)
|
|
208
253
|
|
|
209
|
-
declaration.
|
|
210
|
-
query.
|
|
254
|
+
expect(declaration).to eq("#{id_type} tag_ids from query")
|
|
255
|
+
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..id. AS .tag_ids. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id. WHERE \(.taggings.\..article_id. IS NOT NULL\)\s?$/)
|
|
211
256
|
end
|
|
212
257
|
|
|
213
258
|
it "can handle multiple joins for MVA queries" do
|
|
@@ -224,8 +269,8 @@ describe 'separate queries for MVAs' do
|
|
|
224
269
|
}
|
|
225
270
|
declaration, query = attribute.split(/;\s+/)
|
|
226
271
|
|
|
227
|
-
declaration.
|
|
228
|
-
query.
|
|
272
|
+
expect(declaration).to eq("#{id_type} tag_ids from query")
|
|
273
|
+
expect(query).to match(/^SELECT .articles.\..user_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..id. AS .tag_ids. FROM .articles. INNER JOIN .taggings. ON .taggings.\..article_id. = .articles.\..id. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id. WHERE \(.articles.\..user_id. IS NOT NULL\)\s?$/)
|
|
229
274
|
end
|
|
230
275
|
|
|
231
276
|
it "can handle simple HABTM joins for MVA queries" do
|
|
@@ -242,8 +287,8 @@ describe 'separate queries for MVAs' do
|
|
|
242
287
|
}
|
|
243
288
|
declaration, query = attribute.split(/;\s+/)
|
|
244
289
|
|
|
245
|
-
declaration.
|
|
246
|
-
query.
|
|
290
|
+
expect(declaration).to eq("#{id_type} genre_ids from query")
|
|
291
|
+
expect(query).to match(/^SELECT .books_genres.\..book_id. \* #{count} \+ #{source.offset} AS .id., .books_genres.\..genre_id. AS .genre_ids. FROM .books_genres.\s?$/)
|
|
247
292
|
end if ActiveRecord::VERSION::MAJOR > 3
|
|
248
293
|
|
|
249
294
|
it "generates an appropriate range SQL queries for an MVA" do
|
|
@@ -258,9 +303,9 @@ describe 'separate queries for MVAs' do
|
|
|
258
303
|
}
|
|
259
304
|
declaration, query, range = attribute.split(/;\s+/)
|
|
260
305
|
|
|
261
|
-
declaration.
|
|
262
|
-
query.
|
|
263
|
-
range.
|
|
306
|
+
expect(declaration).to eq("uint tag_ids from ranged-query")
|
|
307
|
+
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .taggings.\..tag_id. AS .tag_ids. FROM .taggings. \s?WHERE \(.taggings.\..article_id. BETWEEN \$start AND \$end\) AND \(.taggings.\..article_id. IS NOT NULL\)$/)
|
|
308
|
+
expect(range).to match(/^SELECT MIN\(.taggings.\..article_id.\), MAX\(.taggings.\..article_id.\) FROM .taggings.\s?$/)
|
|
264
309
|
end
|
|
265
310
|
|
|
266
311
|
it "generates a SQL query with joins when appropriate for MVAs" do
|
|
@@ -275,9 +320,9 @@ describe 'separate queries for MVAs' do
|
|
|
275
320
|
}
|
|
276
321
|
declaration, query, range = attribute.split(/;\s+/)
|
|
277
322
|
|
|
278
|
-
declaration.
|
|
279
|
-
query.
|
|
280
|
-
range.
|
|
323
|
+
expect(declaration).to eq("#{id_type} tag_ids from ranged-query")
|
|
324
|
+
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..id. AS .tag_ids. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id. \s?WHERE \(.taggings.\..article_id. BETWEEN \$start AND \$end\) AND \(.taggings.\..article_id. IS NOT NULL\)$/)
|
|
325
|
+
expect(range).to match(/^SELECT MIN\(.taggings.\..article_id.\), MAX\(.taggings.\..article_id.\) FROM .taggings.\s?$/)
|
|
281
326
|
end
|
|
282
327
|
|
|
283
328
|
it "can handle ranged queries for simple HABTM joins for MVA queries" do
|
|
@@ -294,9 +339,9 @@ describe 'separate queries for MVAs' do
|
|
|
294
339
|
}
|
|
295
340
|
declaration, query, range = attribute.split(/;\s+/)
|
|
296
341
|
|
|
297
|
-
declaration.
|
|
298
|
-
query.
|
|
299
|
-
range.
|
|
342
|
+
expect(declaration).to eq("#{id_type} genre_ids from ranged-query")
|
|
343
|
+
expect(query).to match(/^SELECT .books_genres.\..book_id. \* #{count} \+ #{source.offset} AS .id., .books_genres.\..genre_id. AS .genre_ids. FROM .books_genres. WHERE \(.books_genres.\..book_id. BETWEEN \$start AND \$end\)$/)
|
|
344
|
+
expect(range).to match(/^SELECT MIN\(.books_genres.\..book_id.\), MAX\(.books_genres.\..book_id.\) FROM .books_genres.$/)
|
|
300
345
|
end if ActiveRecord::VERSION::MAJOR > 3
|
|
301
346
|
|
|
302
347
|
it "respects custom SQL snippets as the query value" do
|
|
@@ -312,8 +357,8 @@ describe 'separate queries for MVAs' do
|
|
|
312
357
|
}
|
|
313
358
|
declaration, query = attribute.split(/;\s+/)
|
|
314
359
|
|
|
315
|
-
declaration.
|
|
316
|
-
query.
|
|
360
|
+
expect(declaration).to eq('uint tag_ids from query')
|
|
361
|
+
expect(query).to eq('My Custom SQL Query')
|
|
317
362
|
end
|
|
318
363
|
|
|
319
364
|
it "respects custom SQL snippets as the ranged query value" do
|
|
@@ -329,9 +374,9 @@ describe 'separate queries for MVAs' do
|
|
|
329
374
|
}
|
|
330
375
|
declaration, query, range = attribute.split(/;\s+/)
|
|
331
376
|
|
|
332
|
-
declaration.
|
|
333
|
-
query.
|
|
334
|
-
range.
|
|
377
|
+
expect(declaration).to eq('uint tag_ids from ranged-query')
|
|
378
|
+
expect(query).to eq('My Custom SQL Query')
|
|
379
|
+
expect(range).to eq('And a Range')
|
|
335
380
|
end
|
|
336
381
|
|
|
337
382
|
it "escapes new lines in custom SQL snippets" do
|
|
@@ -349,8 +394,8 @@ SQL Query
|
|
|
349
394
|
}
|
|
350
395
|
declaration, query = attribute.split(/;\s+/)
|
|
351
396
|
|
|
352
|
-
declaration.
|
|
353
|
-
query.
|
|
397
|
+
expect(declaration).to eq('uint tag_ids from query')
|
|
398
|
+
expect(query).to eq("My Custom\\\nSQL Query")
|
|
354
399
|
end
|
|
355
400
|
end
|
|
356
401
|
|
|
@@ -368,8 +413,8 @@ describe 'separate queries for field' do
|
|
|
368
413
|
field = source.sql_joined_field.detect { |field| field[/tags/] }
|
|
369
414
|
declaration, query = field.split(/;\s+/)
|
|
370
415
|
|
|
371
|
-
declaration.
|
|
372
|
-
query.
|
|
416
|
+
expect(declaration).to eq('tags from query')
|
|
417
|
+
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id.\s? WHERE \(.taggings.\..article_id. IS NOT NULL\)\s? ORDER BY .taggings.\..article_id. ASC\s?$/)
|
|
373
418
|
end
|
|
374
419
|
|
|
375
420
|
it "respects has_many :through joins for MVF queries" do
|
|
@@ -381,8 +426,8 @@ describe 'separate queries for field' do
|
|
|
381
426
|
field = source.sql_joined_field.detect { |field| field[/tags/] }
|
|
382
427
|
declaration, query = field.split(/;\s+/)
|
|
383
428
|
|
|
384
|
-
declaration.
|
|
385
|
-
query.
|
|
429
|
+
expect(declaration).to eq('tags from query')
|
|
430
|
+
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id.\s? WHERE \(.taggings.\..article_id. IS NOT NULL\)\s? ORDER BY .taggings.\..article_id. ASC\s?$/)
|
|
386
431
|
end
|
|
387
432
|
|
|
388
433
|
it "can handle multiple joins for MVF queries" do
|
|
@@ -396,8 +441,8 @@ describe 'separate queries for field' do
|
|
|
396
441
|
field = source.sql_joined_field.detect { |field| field[/tags/] }
|
|
397
442
|
declaration, query = field.split(/;\s+/)
|
|
398
443
|
|
|
399
|
-
declaration.
|
|
400
|
-
query.
|
|
444
|
+
expect(declaration).to eq('tags from query')
|
|
445
|
+
expect(query).to match(/^SELECT .articles.\..user_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .articles. INNER JOIN .taggings. ON .taggings.\..article_id. = .articles.\..id. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id.\s? WHERE \(.articles.\..user_id. IS NOT NULL\)\s? ORDER BY .articles.\..user_id. ASC\s?$/)
|
|
401
446
|
end
|
|
402
447
|
|
|
403
448
|
it "generates a SQL query with joins when appropriate for MVFs" do
|
|
@@ -409,9 +454,20 @@ describe 'separate queries for field' do
|
|
|
409
454
|
field = source.sql_joined_field.detect { |field| field[/tags/] }
|
|
410
455
|
declaration, query, range = field.split(/;\s+/)
|
|
411
456
|
|
|
412
|
-
declaration.
|
|
413
|
-
query.
|
|
414
|
-
range.
|
|
457
|
+
expect(declaration).to eq('tags from ranged-query')
|
|
458
|
+
expect(query).to match(/^SELECT .taggings.\..article_id. \* #{count} \+ #{source.offset} AS .id., .tags.\..name. AS .tags. FROM .taggings. INNER JOIN .tags. ON .tags.\..id. = .taggings.\..tag_id. \s?WHERE \(.taggings.\..article_id. BETWEEN \$start AND \$end\) AND \(.taggings.\..article_id. IS NOT NULL\)\s? ORDER BY .taggings.\..article_id. ASC$/)
|
|
459
|
+
expect(range).to match(/^SELECT MIN\(.taggings.\..article_id.\), MAX\(.taggings.\..article_id.\) FROM .taggings.\s?$/)
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
it "does not include fields sourced via separate queries" do
|
|
463
|
+
index.definition_block = Proc.new {
|
|
464
|
+
indexes taggings.tag.name, :as => :tags, :source => :query
|
|
465
|
+
}
|
|
466
|
+
index.render
|
|
467
|
+
|
|
468
|
+
# We don't want it in the SELECT, JOIN or GROUP clauses. This should catch
|
|
469
|
+
# them all.
|
|
470
|
+
expect(source.sql_query).not_to include('tags')
|
|
415
471
|
end
|
|
416
472
|
|
|
417
473
|
it "respects custom SQL snippets as the query value" do
|
|
@@ -423,8 +479,8 @@ describe 'separate queries for field' do
|
|
|
423
479
|
field = source.sql_joined_field.detect { |field| field[/tags/] }
|
|
424
480
|
declaration, query = field.split(/;\s+/)
|
|
425
481
|
|
|
426
|
-
declaration.
|
|
427
|
-
query.
|
|
482
|
+
expect(declaration).to eq('tags from query')
|
|
483
|
+
expect(query).to eq('My Custom SQL Query')
|
|
428
484
|
end
|
|
429
485
|
|
|
430
486
|
it "respects custom SQL snippets as the ranged query value" do
|
|
@@ -437,9 +493,9 @@ describe 'separate queries for field' do
|
|
|
437
493
|
field = source.sql_joined_field.detect { |field| field[/tags/] }
|
|
438
494
|
declaration, query, range = field.split(/;\s+/)
|
|
439
495
|
|
|
440
|
-
declaration.
|
|
441
|
-
query.
|
|
442
|
-
range.
|
|
496
|
+
expect(declaration).to eq('tags from ranged-query')
|
|
497
|
+
expect(query).to eq('My Custom SQL Query')
|
|
498
|
+
expect(range).to eq('And a Range')
|
|
443
499
|
end
|
|
444
500
|
|
|
445
501
|
it "escapes new lines in custom SQL snippets" do
|
|
@@ -454,7 +510,7 @@ SQL Query
|
|
|
454
510
|
field = source.sql_joined_field.detect { |field| field[/tags/] }
|
|
455
511
|
declaration, query = field.split(/;\s+/)
|
|
456
512
|
|
|
457
|
-
declaration.
|
|
458
|
-
query.
|
|
513
|
+
expect(declaration).to eq('tags from query')
|
|
514
|
+
expect(query).to eq("My Custom\\\nSQL Query")
|
|
459
515
|
end
|
|
460
516
|
end
|
|
@@ -1,41 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'acceptance/spec_helper'
|
|
2
4
|
|
|
3
5
|
describe 'Sphinx scopes', :live => true do
|
|
4
6
|
it "allows calling sphinx scopes from models" do
|
|
5
|
-
gods = Book.create! :title => 'American Gods', :
|
|
6
|
-
boys = Book.create! :title => 'Anansi Boys', :
|
|
7
|
-
grave = Book.create! :title => 'The Graveyard Book', :
|
|
7
|
+
gods = Book.create! :title => 'American Gods', :publishing_year => 2001
|
|
8
|
+
boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005
|
|
9
|
+
grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009
|
|
8
10
|
index
|
|
9
11
|
|
|
10
|
-
Book.
|
|
12
|
+
expect(Book.by_publishing_year(2009).to_a).to eq([grave])
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
it "allows scopes to return both query and options" do
|
|
14
|
-
gods = Book.create! :title => 'American Gods', :
|
|
15
|
-
boys = Book.create! :title => 'Anansi Boys', :
|
|
16
|
-
grave = Book.create! :title => 'The Graveyard Book', :
|
|
16
|
+
gods = Book.create! :title => 'American Gods', :publishing_year => 2001
|
|
17
|
+
boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005
|
|
18
|
+
grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009
|
|
17
19
|
index
|
|
18
20
|
|
|
19
|
-
Book.
|
|
21
|
+
expect(Book.by_query_and_publishing_year('Graveyard', 2009).to_a).to eq([grave])
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
it "allows chaining of scopes" do
|
|
23
|
-
gods = Book.create! :title => 'American Gods', :
|
|
24
|
-
boys = Book.create! :title => 'Anansi Boys', :
|
|
25
|
-
grave = Book.create! :title => 'The Graveyard Book', :
|
|
25
|
+
gods = Book.create! :title => 'American Gods', :publishing_year => 2001
|
|
26
|
+
boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005
|
|
27
|
+
grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009
|
|
26
28
|
index
|
|
27
29
|
|
|
28
|
-
Book.
|
|
30
|
+
expect(Book.by_publishing_year(2001..2005).ordered.to_a).to eq([boys, gods])
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
it "allows chaining of scopes that include queries" do
|
|
32
|
-
gods = Book.create! :title => 'American Gods', :
|
|
33
|
-
boys = Book.create! :title => 'Anansi Boys', :
|
|
34
|
-
grave = Book.create! :title => 'The Graveyard Book', :
|
|
34
|
+
gods = Book.create! :title => 'American Gods', :publishing_year => 2001
|
|
35
|
+
boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005
|
|
36
|
+
grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009
|
|
35
37
|
index
|
|
36
38
|
|
|
37
|
-
Book.
|
|
38
|
-
|
|
39
|
+
expect(Book.by_publishing_year(2001).by_query_and_publishing_year('Graveyard', 2009).to_a).
|
|
40
|
+
to eq([grave])
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
it "allows further search calls on scopes" do
|
|
@@ -43,7 +45,7 @@ describe 'Sphinx scopes', :live => true do
|
|
|
43
45
|
pratchett = Book.create! :title => 'Small Gods'
|
|
44
46
|
index
|
|
45
47
|
|
|
46
|
-
Book.by_query('Gods').search('Small').to_a.
|
|
48
|
+
expect(Book.by_query('Gods').search('Small').to_a).to eq([pratchett])
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
it "allows facet calls on scopes" do
|
|
@@ -52,9 +54,9 @@ describe 'Sphinx scopes', :live => true do
|
|
|
52
54
|
Book.create! :title => 'Small Gods', :author => 'Terry Pratchett'
|
|
53
55
|
index
|
|
54
56
|
|
|
55
|
-
Book.by_query('Gods').facets.to_hash[:author].
|
|
57
|
+
expect(Book.by_query('Gods').facets.to_hash[:author]).to eq({
|
|
56
58
|
'Neil Gaiman' => 1, 'Terry Pratchett' => 1
|
|
57
|
-
}
|
|
59
|
+
})
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
it "allows accessing counts on scopes" do
|
|
@@ -64,7 +66,7 @@ describe 'Sphinx scopes', :live => true do
|
|
|
64
66
|
Book.create! :title => 'Night Watch'
|
|
65
67
|
index
|
|
66
68
|
|
|
67
|
-
Book.by_query('gods').count.
|
|
69
|
+
expect(Book.by_query('gods').count).to eq(2)
|
|
68
70
|
end
|
|
69
71
|
|
|
70
72
|
it 'raises an exception when trying to modify a populated request' do
|
|
@@ -75,4 +77,11 @@ describe 'Sphinx scopes', :live => true do
|
|
|
75
77
|
ThinkingSphinx::PopulatedResultsError
|
|
76
78
|
)
|
|
77
79
|
end
|
|
80
|
+
|
|
81
|
+
it "handles a chainable 'none' scope and returns nothing" do
|
|
82
|
+
Book.create! :title => 'Small Gods'
|
|
83
|
+
index
|
|
84
|
+
|
|
85
|
+
expect(Book.by_query('gods').none).to be_empty
|
|
86
|
+
end
|
|
78
87
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'acceptance/spec_helper'
|
|
2
4
|
|
|
3
5
|
describe 'SQL delta indexing', :live => true do
|
|
@@ -7,38 +9,50 @@ describe 'SQL delta indexing', :live => true do
|
|
|
7
9
|
)
|
|
8
10
|
index
|
|
9
11
|
|
|
10
|
-
Book.search('Terry Pratchett').to_a.
|
|
12
|
+
expect(Book.search('Terry Pratchett').to_a).to eq([guards])
|
|
11
13
|
|
|
12
14
|
men = Book.create(
|
|
13
15
|
:title => 'Men At Arms', :author => 'Terry Pratchett'
|
|
14
16
|
)
|
|
15
17
|
sleep 0.25
|
|
16
18
|
|
|
17
|
-
Book.search('Terry Pratchett').to_a.
|
|
19
|
+
expect(Book.search('Terry Pratchett').to_a).to match_array([guards, men])
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
it "automatically indexes updated records" do
|
|
21
23
|
book = Book.create :title => 'Night Watch', :author => 'Harry Pritchett'
|
|
22
24
|
index
|
|
23
25
|
|
|
24
|
-
Book.search('Harry').to_a.
|
|
26
|
+
expect(Book.search('Harry').to_a).to eq([book])
|
|
25
27
|
|
|
26
|
-
book.reload.
|
|
28
|
+
book.reload.update(:author => 'Terry Pratchett')
|
|
27
29
|
sleep 0.25
|
|
28
30
|
|
|
29
|
-
Book.search('Terry').to_a.
|
|
31
|
+
expect(Book.search('Terry').to_a).to eq([book])
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
it "does not match on old values" do
|
|
33
35
|
book = Book.create :title => 'Night Watch', :author => 'Harry Pritchett'
|
|
34
36
|
index
|
|
35
37
|
|
|
36
|
-
Book.search('Harry').to_a.
|
|
38
|
+
expect(Book.search('Harry').to_a).to eq([book])
|
|
39
|
+
|
|
40
|
+
book.reload.update(:author => 'Terry Pratchett')
|
|
41
|
+
sleep 0.25
|
|
42
|
+
|
|
43
|
+
expect(Book.search('Harry')).to be_empty
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "does not match on old values with alternative ids" do
|
|
47
|
+
album = Album.create :name => 'Eternal Nightcap', :artist => 'The Whitloms'
|
|
48
|
+
index
|
|
49
|
+
|
|
50
|
+
expect(Album.search('Whitloms').to_a).to eq([album])
|
|
37
51
|
|
|
38
|
-
|
|
52
|
+
album.reload.update(:artist => 'The Whitlams')
|
|
39
53
|
sleep 0.25
|
|
40
54
|
|
|
41
|
-
Book.search('
|
|
55
|
+
expect(Book.search('Whitloms')).to be_empty
|
|
42
56
|
end
|
|
43
57
|
|
|
44
58
|
it "automatically indexes new records of subclasses" do
|
|
@@ -47,6 +61,18 @@ describe 'SQL delta indexing', :live => true do
|
|
|
47
61
|
)
|
|
48
62
|
sleep 0.25
|
|
49
63
|
|
|
50
|
-
Book.search('Gaiman').to_a.
|
|
64
|
+
expect(Book.search('Gaiman').to_a).to eq([book])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "updates associated models" do
|
|
68
|
+
colour = Colour.create(:name => 'green')
|
|
69
|
+
sleep 0.25
|
|
70
|
+
|
|
71
|
+
expect(Colour.search('green').to_a).to eq([colour])
|
|
72
|
+
|
|
73
|
+
tee = colour.tees.create
|
|
74
|
+
sleep 0.25
|
|
75
|
+
|
|
76
|
+
expect(Colour.search(:with => {:tee_ids => tee.id}).to_a).to eq([colour])
|
|
51
77
|
end
|
|
52
78
|
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
RSpec.configure do |config|
|
|
2
4
|
config.before(:suite) do
|
|
3
5
|
DatabaseCleaner.strategy = :truncation
|
|
4
6
|
end
|
|
5
7
|
|
|
6
|
-
config.after(:each) do
|
|
8
|
+
config.after(:each) do |example|
|
|
7
9
|
if example.example_group_instance.class.metadata[:live]
|
|
8
10
|
DatabaseCleaner.clean
|
|
9
11
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
class SphinxController
|
|
2
4
|
def initialize
|
|
3
5
|
config.searchd.mysql41 = 9307
|
|
@@ -10,14 +12,12 @@ class SphinxController
|
|
|
10
12
|
|
|
11
13
|
ThinkingSphinx::Configuration.reset
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
ActiveSupport::Dependencies.clear
|
|
15
|
+
if Rails::VERSION::MAJOR < 7
|
|
16
|
+
ActiveSupport::Dependencies.loaded.each do |path|
|
|
17
|
+
$LOADED_FEATURES.delete "#{path}.rb"
|
|
18
|
+
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
ThinkingSphinx::Configuration.instance.settings['utf8'] = false
|
|
20
|
+
ActiveSupport::Dependencies.clear
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
config.searchd.mysql41 = 9307
|
|
@@ -28,14 +28,30 @@ class SphinxController
|
|
|
28
28
|
|
|
29
29
|
def start
|
|
30
30
|
config.controller.start
|
|
31
|
+
rescue Riddle::CommandFailedError => error
|
|
32
|
+
puts <<-TXT
|
|
33
|
+
|
|
34
|
+
The Sphinx start command failed:
|
|
35
|
+
Command: #{error.command_result.command}
|
|
36
|
+
Status: #{error.command_result.status}
|
|
37
|
+
Output: #{error.command_result.output}
|
|
38
|
+
TXT
|
|
39
|
+
raise error
|
|
31
40
|
end
|
|
32
41
|
|
|
33
42
|
def stop
|
|
34
|
-
config.controller.
|
|
43
|
+
while config.controller.running? do
|
|
44
|
+
config.controller.stop
|
|
45
|
+
sleep(0.1)
|
|
46
|
+
end
|
|
35
47
|
end
|
|
36
48
|
|
|
37
49
|
def index(*indices)
|
|
38
|
-
|
|
50
|
+
ThinkingSphinx::Commander.call :index_sql, config, :indices => indices
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def merge
|
|
54
|
+
ThinkingSphinx::Commander.call(:merge_and_update, config, {})
|
|
39
55
|
end
|
|
40
56
|
|
|
41
57
|
private
|