Permalink
Browse files

Can explicitly specify available types for STI tables instead of auto…

…matically discovering them with "SELECT DISTINCT type FROM <table>"

Example:

class Product < ActiveRecord::Base
  set_sphinx_types %w(ProductTypeA ProductTypeB)
  define_index do
    [...]
  end
end
  • Loading branch information...
1 parent f6299c5 commit 64ee2b25affb263d182c9b90fb8c6c29e6b0eecd @cmaion cmaion committed with pat Apr 15, 2012
Showing with 40 additions and 15 deletions.
  1. +1 −0 HISTORY
  2. +1 −0 README.textile
  3. +5 −1 lib/thinking_sphinx/active_record.rb
  4. +14 −14 lib/thinking_sphinx/source/sql.rb
  5. +19 −0 spec/thinking_sphinx/active_record_spec.rb
View
@@ -1,4 +1,5 @@
Edge:
+* Can explicitly specify available types for STI tables instead of automatically discovering them with "SELECT DISTINCT type FROM <table>" (Cedric Maion).
* Don't try to run rake tasks for Capistrano if there's no Rakefile - eg. on fresh deploys (Nathan Smith).
* Populate search results before comparing with #==.
* Can indicate whether Sphinx should use a socket for connections instead of TCP (Simon Hürlimann).
View
@@ -208,3 +208,4 @@ Since I first released this library, there's been quite a few people who have su
* Andrew Hunter
* Simon Hürlimann
* Nathan Smith
+* Cedric Maion
@@ -17,7 +17,7 @@ def self.included(base)
extend ThinkingSphinx::ActiveRecord::ClassMethods
class << self
- attr_accessor :sphinx_index_blocks
+ attr_accessor :sphinx_index_blocks, :sphinx_types
def set_sphinx_primary_key(attribute)
@sphinx_primary_key_attribute = attribute
@@ -49,6 +49,10 @@ def sphinx_index_options
sphinx_indexes.last.options
end
+ def set_sphinx_types(types)
+ @sphinx_types = types
+ end
+
# Generate a unique CRC value for the model's name, to use to
# determine which Sphinx documents belong to which AR records.
#
@@ -6,9 +6,9 @@ module SQL
# the version filtered for delta values, send through :delta => true in the
# options. Won't do much though if the index isn't set up to support a
# delta sibling.
- #
+ #
# Examples:
- #
+ #
# source.to_sql
# source.to_sql(:delta => true)
#
@@ -30,10 +30,10 @@ def to_sql(options={})
# Simple helper method for the query range SQL - which is a statement that
# returns minimum and maximum id values. These can be filtered by delta -
# so pass in :delta => true to get the delta version of the SQL.
- #
+ #
def to_sql_query_range(options={})
return nil if @index.options[:disable_range]
-
+
min_statement = adapter.convert_nulls(
"MIN(#{quote_column(@model.primary_key_for_sphinx)})", 1
)
@@ -52,7 +52,7 @@ def to_sql_query_range(options={})
# Simple helper method for the query info SQL - which is a statement that
# returns the single row for a corresponding id.
- #
+ #
def to_sql_query_info(offset)
"SELECT * FROM #{@model.quoted_table_name} WHERE " +
"#{quote_column(@model.primary_key_for_sphinx)} = (($id - #{offset}) / #{ThinkingSphinx.context.indexed_models.size})"
@@ -62,7 +62,7 @@ def sql_select_clause(offset)
unique_id_expr = ThinkingSphinx.unique_id_expression(adapter, offset)
(
- ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} #{unique_id_expr} AS #{quote_column(@model.primary_key_for_sphinx)} "] +
+ ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} #{unique_id_expr} AS #{quote_column(@model.primary_key_for_sphinx)} "] +
@fields.collect { |field| field.to_select_sql } +
@attributes.collect { |attribute| attribute.to_select_sql }
).compact.join(", ")
@@ -90,7 +90,7 @@ def sql_group_clause
end
(
- ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)}"] +
+ ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)}"] +
@fields.collect { |field| field.to_group_sql }.compact +
@attributes.collect { |attribute| attribute.to_group_sql }.compact +
@groupings + internal_groupings
@@ -116,18 +116,18 @@ def quote_column(column)
def crc_column
if @model.table_exists? &&
@model.column_names.include?(@model.inheritance_column)
-
+
types = types_to_crcs
return @model.to_crc32.to_s if types.empty?
-
+
adapter.case(adapter.convert_nulls(
adapter.quote_with_table(@model.inheritance_column)),
types, @model.to_crc32)
else
@model.to_crc32.to_s
end
end
-
+
def internal_class_column
if @model.table_exists? &&
@model.column_names.include?(@model.inheritance_column)
@@ -136,14 +136,14 @@ def internal_class_column
"'#{@model.name}'"
end
end
-
+
def type_values
- @model.connection.select_values <<-SQL
+ @model.sphinx_types.presence or @model.connection.select_values <<-SQL
SELECT DISTINCT #{@model.inheritance_column}
FROM #{@model.table_name}
SQL
end
-
+
def types_to_crcs
type_values.compact.inject({}) { |hash, type|
hash[type] = type.to_crc32
@@ -152,4 +152,4 @@ def types_to_crcs
end
end
end
-end
+end
@@ -419,6 +419,25 @@
end
end
+ describe '#types_for_sphinx' do
+ before :each do
+ @person = Person.find(:first)
+ end
+
+ after :each do
+ Person.set_sphinx_types nil
+ end
+
+ it "should return nil by default" do
+ @person.sphinx_types.should == nil
+ end
+
+ it "should return the specified value" do
+ Person.set_sphinx_types %w(Person Parent)
+ @person.sphinx_types.should == %w(Person Parent)
+ end
+ end
+
describe '.sphinx_index_names' do
it "should return the core index" do
Alpha.define_index { indexes :name }

0 comments on commit 64ee2b2

Please sign in to comment.