From 3c6f899fd3dc8ec59da5a60d1f66d803c605162b Mon Sep 17 00:00:00 2001 From: Merkushin Date: Tue, 12 Mar 2013 16:01:43 +0600 Subject: [PATCH] refactor spec, finish specs for active_record --- .../extensions/active_record.rb | 13 ++--- .../extensions/thinking_sphinx.rb | 6 +++ .../models/{post.rb => model_with_disk.rb} | 4 +- .../app/models/model_with_disk_rubrics.rb | 5 ++ spec/internal/app/models/model_with_rt.rb | 17 ++++++ .../app/models/model_with_second_disk.rb | 14 +++++ spec/internal/app/models/rubric.rb | 4 ++ spec/internal/db/schema.rb | 25 ++++++++- .../extensions/active_record_spec.rb | 29 ++++++++-- .../extensions/attribute_spec.rb | 6 ++- .../extensions/index_spec.rb | 4 +- .../extensions/source/sql_spec.rb | 54 +++++++++---------- sphinx-integration.gemspec | 15 +++--- 13 files changed, 144 insertions(+), 52 deletions(-) rename spec/internal/app/models/{post.rb => model_with_disk.rb} (61%) create mode 100644 spec/internal/app/models/model_with_disk_rubrics.rb create mode 100644 spec/internal/app/models/model_with_rt.rb create mode 100644 spec/internal/app/models/model_with_second_disk.rb create mode 100644 spec/internal/app/models/rubric.rb diff --git a/lib/sphinx_integration/extensions/active_record.rb b/lib/sphinx_integration/extensions/active_record.rb index 4b1236d..b71c697 100644 --- a/lib/sphinx_integration/extensions/active_record.rb +++ b/lib/sphinx_integration/extensions/active_record.rb @@ -26,9 +26,11 @@ def max_matches @ts_max_matches ||= ThinkingSphinx::Configuration.instance.configuration.searchd.max_matches || 5000 end - def define_secondary_index(args = {}, &block) - args ||= {} - define_index(args[:name], &block) + def define_secondary_index(*args, &block) + options = args.extract_options! + name = args.first || options[:name] + raise ArgumentError unless name + define_index(name, &block) self.sphinx_index_blocks << lambda { self.sphinx_indexes.last.merged_with_core = true @@ -42,11 +44,6 @@ def reset_indexes self.defined_indexes = false end - def rt_index_names - define_indexes - sphinx_indexes.collect(&:rt_name) - end - def rt_indexed_by_sphinx? sphinx_indexes && sphinx_indexes.any? { |index| index.rt? } end diff --git a/lib/sphinx_integration/extensions/thinking_sphinx.rb b/lib/sphinx_integration/extensions/thinking_sphinx.rb index 3935956..638afe4 100644 --- a/lib/sphinx_integration/extensions/thinking_sphinx.rb +++ b/lib/sphinx_integration/extensions/thinking_sphinx.rb @@ -13,6 +13,12 @@ def max_matches @ts_max_matches ||= ThinkingSphinx::Configuration.instance.configuration.searchd.max_matches || 5000 end + def reset_indexed_models + context.indexed_models.each do |model| + model.constantize.reset_indexes + end + end + def take_connection SphinxIntegration::Mysql::ConnectionPool.take do |connection| yield connection diff --git a/spec/internal/app/models/post.rb b/spec/internal/app/models/model_with_disk.rb similarity index 61% rename from spec/internal/app/models/post.rb rename to spec/internal/app/models/model_with_disk.rb index 61a2014..c5b20d6 100644 --- a/spec/internal/app/models/post.rb +++ b/spec/internal/app/models/model_with_disk.rb @@ -1,7 +1,7 @@ # coding: utf-8 -class Post < ActiveRecord::Base +class ModelWithDisk < ActiveRecord::Base - define_index('post') do + define_index('model_with_disk') do indexes 'content', :as => :content has 'region_id', :type => :integer, :as => :region_id end diff --git a/spec/internal/app/models/model_with_disk_rubrics.rb b/spec/internal/app/models/model_with_disk_rubrics.rb new file mode 100644 index 0000000..292ac96 --- /dev/null +++ b/spec/internal/app/models/model_with_disk_rubrics.rb @@ -0,0 +1,5 @@ +# coding: utf-8 +class ModelWithDiskRubrics < ActiveRecord::Base + belongs_to :model_with_disk + belongs_to :rubrics +end \ No newline at end of file diff --git a/spec/internal/app/models/model_with_rt.rb b/spec/internal/app/models/model_with_rt.rb new file mode 100644 index 0000000..92c27fd --- /dev/null +++ b/spec/internal/app/models/model_with_rt.rb @@ -0,0 +1,17 @@ +# coding: utf-8 +class ModelWithRt < ActiveRecord::Base + has_many :model_with_rt_rubrics + has_many :rubrics, :through => :model_with_rt_rubrics + + define_index('model_with_rt') do + indexes 'name', :as => :name + has 'region_id', :type => :integer, :as => :region_id + has :rubrics, :type => :multi, :source => :ranged_query, :query => "SELECT {{model_with_rt_id}} AS id, rubric_id AS rubrics FROM model_with_rt_rubrics WHERE id>=$start AND id<=$end; SELECT MIN(id), MAX(id) FROM model_with_rt_rubrics" + set_property :rt => true + end + + def mva_sphinx_attributes_for_rubrics + model_with_rt_rubrics.map(&:rubric_id) + end + +end \ No newline at end of file diff --git a/spec/internal/app/models/model_with_second_disk.rb b/spec/internal/app/models/model_with_second_disk.rb new file mode 100644 index 0000000..97d8bae --- /dev/null +++ b/spec/internal/app/models/model_with_second_disk.rb @@ -0,0 +1,14 @@ +# coding: utf-8 +class ModelWithSecondDisk < ActiveRecord::Base + + define_index('model_with_second_disk') do + indexes 'content', :as => :content + has 'region_id', :type => :integer, :as => :region_id + end + + define_secondary_index('model_with_second_disk_delta') do + indexes 'content', :as => :content + has 'region_id', :type => :integer, :as => :region_id + end + +end \ No newline at end of file diff --git a/spec/internal/app/models/rubric.rb b/spec/internal/app/models/rubric.rb new file mode 100644 index 0000000..2f9134b --- /dev/null +++ b/spec/internal/app/models/rubric.rb @@ -0,0 +1,4 @@ +# coding: utf-8 +class Rubric < ActiveRecord::Base + +end \ No newline at end of file diff --git a/spec/internal/db/schema.rb b/spec/internal/db/schema.rb index 9563ab1..99c6c8a 100644 --- a/spec/internal/db/schema.rb +++ b/spec/internal/db/schema.rb @@ -1,7 +1,30 @@ ActiveRecord::Schema.define do - create_table(:posts, :force => true) do |t| + create_table(:model_with_disks, :force => true) do |t| t.string :content t.integer :region_id t.timestamps end + + create_table(:model_with_second_disks, :force => true) do |t| + t.string :content + t.integer :region_id + t.timestamps + end + + create_table(:model_with_rts, :force => true) do |t| + t.string :content + t.integer :region_id + t.timestamps + end + + create_table(:model_with_rt_rubrics, :force => true) do |t| + t.string :model_with_rt_id + t.integer :rubric_id + t.timestamps + end + + create_table(:rubrics, :force => true) do |t| + t.string :name + t.timestamps + end end diff --git a/spec/sphinx_integration/extensions/active_record_spec.rb b/spec/sphinx_integration/extensions/active_record_spec.rb index 6006c86..ca5f55d 100644 --- a/spec/sphinx_integration/extensions/active_record_spec.rb +++ b/spec/sphinx_integration/extensions/active_record_spec.rb @@ -1,16 +1,39 @@ # coding: utf-8 require 'spec_helper' -describe 'ActiveRecord::Base extensions' do +describe 'ActiveRecord::Base extension' do + + before(:all){ ThinkingSphinx.context.define_indexes } describe '.max_matches' do - subject { Post.max_matches } + subject { ActiveRecord::Base.max_matches } it { should be_a(Integer) } it { should eq 5000 } end describe '.define_secondary_index' do - + subject { ModelWithSecondDisk.sphinx_indexes.detect{ |x| x.name == 'model_with_second_disk_delta' } } + it { should_not be_nil } + its(:merged_with_core) { should be_true } + end + + describe '.reset_indexes' do + before { ModelWithDisk.reset_indexes } + after { ModelWithDisk.define_indexes } + + subject { ModelWithDisk } + its(:sphinx_index_blocks) { should be_empty } + its(:sphinx_indexes) { should be_empty } + its(:sphinx_facets) { should be_empty } + its(:defined_indexes?) { should be_false } + end + + describe '.rt_indexed_by_sphinx?' do + it { ModelWithRt.rt_indexed_by_sphinx?.should be_true } + end + + describe '.methods_for_mva_attributes' do + it { ModelWithRt.methods_for_mva_attributes.should eq [:mva_sphinx_attributes_for_rubrics] } end end \ No newline at end of file diff --git a/spec/sphinx_integration/extensions/attribute_spec.rb b/spec/sphinx_integration/extensions/attribute_spec.rb index c63688a..036096d 100644 --- a/spec/sphinx_integration/extensions/attribute_spec.rb +++ b/spec/sphinx_integration/extensions/attribute_spec.rb @@ -5,11 +5,13 @@ describe '#source_value' do it 'generate custom sql' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content has :regions, :type => :multi, :source => :ranged_query, :query => "SELECT {{post_id}} AS id, region_id AS regions FROM post_regions WHERE id>=$start AND id<=$end; SELECT MIN(id), MAX(id) FROM post_regions", :as => :regions end - exptected_sql = 'query; SELECT post_id * 1::INT8 + 0 AS id, region_id AS regions FROM post_regions WHERE id>=$start AND id<=$end; SELECT MIN(id), MAX(id) FROM post_regions' + + id_expr = ThinkingSphinx.unique_id_expression(index.send(:adapter), 0) + exptected_sql = %{query; SELECT post_id #{id_expr} AS id, region_id AS regions FROM post_regions WHERE id>=$start AND id<=$end; SELECT MIN(id), MAX(id) FROM post_regions} index.sources.first.attributes.detect{ |x| x.unique_name == :regions }.send(:source_value, 0, false).should eql exptected_sql end end diff --git a/spec/sphinx_integration/extensions/index_spec.rb b/spec/sphinx_integration/extensions/index_spec.rb index 25c41c0..ca121fd 100644 --- a/spec/sphinx_integration/extensions/index_spec.rb +++ b/spec/sphinx_integration/extensions/index_spec.rb @@ -4,7 +4,7 @@ describe 'ThinkingSphinx Index extension' do let(:index) do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content has 'region_id', :type => :integer, :as => :region_id set_property :rt => true @@ -35,7 +35,7 @@ describe '#to_riddle_for_rt' do subject { index.to_riddle_for_rt } - its(:name){ should eql 'post_rt' } + its(:name){ should eql 'model_with_disk_rt' } its(:rt_field){ should have(1).item } its(:rt_attr_uint){ should eql [:sphinx_internal_id, :sphinx_deleted, :class_crc, :region_id] } end diff --git a/spec/sphinx_integration/extensions/source/sql_spec.rb b/spec/sphinx_integration/extensions/source/sql_spec.rb index 4c97f31..c5a4644 100644 --- a/spec/sphinx_integration/extensions/source/sql_spec.rb +++ b/spec/sphinx_integration/extensions/source/sql_spec.rb @@ -5,46 +5,46 @@ describe '#sql_query_info' do it 'generate default table name' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content end - index.sources.first.to_sql_query_info(0).should include('"posts"') + index.sources.first.to_sql_query_info(0).should include('"model_with_disks"') end it 'generate custom table name' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content - set_property :source_table => 'custom_posts' + set_property :source_table => 'custom_table_name' end - index.sources.first.to_sql_query_info(0).should include('"custom_posts"') + index.sources.first.to_sql_query_info(0).should include('"custom_table_name"') end end describe '#to_sql' do it 'generate cte' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content set_property :source_cte => { - :post_cte => 'select id from temp_table where {{where}}' + :cte_table => 'select id from temp_table where {{where}}' } end - expected_sql = 'WITH post_cte AS (select id from temp_table where "posts"."id" >= $start AND "posts"."id" <= $end)' + expected_sql = 'WITH cte_table AS (select id from temp_table where "model_with_disks"."id" >= $start AND "model_with_disks"."id" <= $end)' index.sources.first.to_sql(:offset => 0).should include(expected_sql) end it 'generate joins' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content set_property :source_joins => { - :rubrics => {:type => :left, :on => 'posts.rubric_id = rubrics.id'}, + :rubrics => {:type => :left, :on => 'model_with_disks.rubric_id = rubrics.id'}, } end - expected_sql = 'LEFT JOIN rubrics AS rubrics ON posts.rubric_id = rubrics.id' + expected_sql = 'LEFT JOIN rubrics AS rubrics ON model_with_disks.rubric_id = rubrics.id' index.sources.first.to_sql(:offset => 0).should include(expected_sql) end it 'generate no groupping' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content set_property :source_no_grouping => true end @@ -52,7 +52,7 @@ end it 'generate limit' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content set_property :sql_query_limit => 1000 end @@ -63,7 +63,7 @@ describe '#to_sql_query_range' do it 'generate custom query range' do expected_sql = 'SELECT 1::int, COALESCE(MAX(id), 1::int) FROM products' - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content set_property :sql_query_range => expected_sql end @@ -71,7 +71,7 @@ end it 'no generate query range' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content set_property :disable_range => true end @@ -81,41 +81,41 @@ describe '#to_sql_query_info' do it 'generate default table name' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content end - index.sources.first.to_sql_query_info(0).should include('"posts"') + index.sources.first.to_sql_query_info(0).should include('"model_with_disks"') end it 'generate custom table name' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content - set_property :source_table => 'custom_posts' + set_property :source_table => 'custom_table_name' end - index.sources.first.to_sql_query_info(0).should include('"custom_posts"') + index.sources.first.to_sql_query_info(0).should include('"custom_table_name"') end end describe '#sql_select_clause' do it 'generate default table name' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content end - index.sources.first.sql_select_clause(0).should include('"posts"."id"') + index.sources.first.sql_select_clause(0).should include('"model_with_disks"."id"') end it 'generate custom table name' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content - set_property :source_table => 'custom_posts' + set_property :source_table => 'custom_table_name' end - index.sources.first.sql_select_clause(0).should include('"custom_posts"."id"') + index.sources.first.sql_select_clause(0).should include('"custom_table_name"."id"') end end describe '#sql_where_clause' do it 'generate without range' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content set_property :use_own_sql_query_range => true end @@ -125,7 +125,7 @@ describe '#sql_group_clause' do it 'generate custom groupings' do - index = ThinkingSphinx::Index::Builder.generate(Post, nil) do + index = ThinkingSphinx::Index::Builder.generate(ModelWithDisk, nil) do indexes 'content', :as => :content group_by! :id, :region_id end diff --git a/sphinx-integration.gemspec b/sphinx-integration.gemspec index 4a43629..7c440e2 100644 --- a/sphinx-integration.gemspec +++ b/sphinx-integration.gemspec @@ -4,13 +4,13 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'sphinx_integration/version' Gem::Specification.new do |gem| - gem.name = "sphinx-integration" + gem.name = 'sphinx-integration' gem.version = SphinxIntegration::VERSION gem.authors = ["merkushin"] gem.email = ["merkushin.m.s@gmail.com"] gem.description = %q{Sphinx Integration} gem.summary = %{sphinx-integration-#{SphinxIntegration::VERSION}} - gem.homepage = "" + gem.homepage = '' gem.files = `git ls-files`.split($/) gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } @@ -23,11 +23,12 @@ Gem::Specification.new do |gem| gem.add_runtime_dependency 'innertube' gem.add_runtime_dependency 'thinking-sphinx', '= 2.0.14' - gem.add_development_dependency "rake" - gem.add_development_dependency "bundler" - gem.add_development_dependency "rspec" + gem.add_development_dependency 'rake' + gem.add_development_dependency 'bundler' + gem.add_development_dependency 'rspec' gem.add_development_dependency 'rails', '~> 3.0.19' - gem.add_development_dependency "rspec-rails" + gem.add_development_dependency 'rspec-rails' gem.add_development_dependency 'combustion' - gem.add_development_dependency "mock_redis" + gem.add_development_dependency 'mock_redis' + gem.add_development_dependency 'database_cleaner' end