lib/thinking_sphinx/index.rb in dpickett-thinking-sphinx-1.1.4 vs lib/thinking_sphinx/index.rb in dpickett-thinking-sphinx-1.1.12
- old
+ new
@@ -35,10 +35,23 @@
@groupings = []
@options = {}
@delta_object = nil
initialize_from_builder(&block) if block_given?
+
+ add_internal_attributes_and_facets
+
+ # We want to make sure that if the database doesn't exist, then Thinking
+ # Sphinx doesn't mind when running non-TS tasks (like db:create, db:drop
+ # and db:migrate). It's a bit hacky, but I can't think of a better way.
+ rescue StandardError => err
+ case err.class.name
+ when "Mysql::Error", "Java::JavaSql::SQLException", "ActiveRecord::StatementInvalid"
+ return
+ else
+ raise err
+ end
end
def name
self.class.name(@model)
end
@@ -46,36 +59,34 @@
def self.name(model)
model.name.underscore.tr(':/\\', '_')
end
def to_riddle_for_core(offset, index)
- add_internal_attributes
link!
source = Riddle::Configuration::SQLSource.new(
"#{name}_core_#{index}", adapter.sphinx_identifier
)
set_source_database_settings source
- set_source_attributes source
+ set_source_attributes source, offset
set_source_sql source, offset
set_source_settings source
source
end
def to_riddle_for_delta(offset, index)
- add_internal_attributes
link!
source = Riddle::Configuration::SQLSource.new(
"#{name}_delta_#{index}", adapter.sphinx_identifier
)
source.parent = "#{name}_core_#{index}"
set_source_database_settings source
- set_source_attributes source
+ set_source_attributes source, offset
set_source_sql source, offset, true
source
end
@@ -173,21 +184,10 @@
add_facet = Proc.new { |item| @model.sphinx_facets << item.to_facet }
@model.sphinx_facets ||= []
@fields.select( &is_faceted).each &add_facet
@attributes.select(&is_faceted).each &add_facet
-
- # We want to make sure that if the database doesn't exist, then Thinking
- # Sphinx doesn't mind when running non-TS tasks (like db:create, db:drop
- # and db:migrate). It's a bit hacky, but I can't think of a better way.
- rescue StandardError => err
- case err.class.name
- when "Mysql::Error", "ActiveRecord::StatementInvalid"
- return
- else
- raise err
- end
end
# Returns all associations used amongst all the fields and attributes.
# This includes all associations between the model and what the actual
# columns are from.
@@ -198,12 +198,12 @@
@fields.collect { |field|
field.associations.values
}.flatten +
# attribute associations
@attributes.collect { |attrib|
- attrib.associations.values
- }.flatten
+ attrib.associations.values if attrib.include_as_association?
+ }.compact.flatten
).uniq.collect { |assoc|
# get ancestors as well as column-level associations
assoc.ancestors
}.flatten.uniq
end
@@ -236,63 +236,58 @@
end
def crc_column
if @model.column_names.include?(@model.inheritance_column)
adapter.cast_to_unsigned(adapter.convert_nulls(
- adapter.crc(adapter.quote_with_table(@model.inheritance_column)),
+ adapter.crc(adapter.quote_with_table(@model.inheritance_column), true),
@model.to_crc32
))
else
@model.to_crc32.to_s
end
end
- def add_internal_attributes
- @attributes << Attribute.new(
- FauxColumn.new(@model.primary_key.to_sym),
- :type => :integer,
- :as => :sphinx_internal_id
- ) unless @attributes.detect { |attr| attr.alias == :sphinx_internal_id }
+ def add_internal_attributes_and_facets
+ add_internal_attribute :sphinx_internal_id, :integer, @model.primary_key.to_sym
+ add_internal_attribute :class_crc, :integer, crc_column, true
+ add_internal_attribute :subclass_crcs, :multi, subclasses_to_s
+ add_internal_attribute :sphinx_deleted, :integer, "0"
- unless @attributes.detect { |attr| attr.alias == :class_crc }
- @attributes << Attribute.new(
- FauxColumn.new(crc_column),
- :type => :integer,
- :as => :class_crc,
- :facet => true
- )
+ add_internal_facet :class_crc
+ end
+
+ def add_internal_attribute(name, type, contents, facet = false)
+ return unless attribute_by_alias(name).nil?
- @model.sphinx_facets << ThinkingSphinx::ClassFacet.new(@attributes.last)
- end
-
- if @model.column_names.include?(@model.inheritance_column)
- class_col = FauxColumn.new(
- adapter.convert_nulls(adapter.quote_with_table(@model.inheritance_column), @model.to_s)
- )
- else
- class_col = FauxColumn.new("'#{@model.to_s}'")
- end
-
- @attributes << Attribute.new(class_col,
- :type => :string,
- :as => :class
+ @attributes << Attribute.new(
+ FauxColumn.new(contents),
+ :type => type,
+ :as => name,
+ :facet => facet,
+ :admin => true
)
+ end
+
+ def add_internal_facet(name)
+ return unless facet_by_alias(name).nil?
- @attributes << Attribute.new(
- FauxColumn.new("'" + (@model.send(:subclasses).collect { |klass|
- klass.to_crc32.to_s
- } << @model.to_crc32.to_s).join(",") + "'"),
- :type => :multi,
- :as => :subclass_crcs
- ) unless @attributes.detect { |attr| attr.alias == :subclass_crcs }
-
- @attributes << Attribute.new(
- FauxColumn.new("0"),
- :type => :integer,
- :as => :sphinx_deleted
- ) unless @attributes.detect { |attr| attr.alias == :sphinx_deleted }
+ @model.sphinx_facets << ClassFacet.new(attribute_by_alias(name))
end
+
+ def attribute_by_alias(attr_alias)
+ @attributes.detect { |attrib| attrib.alias == attr_alias }
+ end
+
+ def facet_by_alias(name)
+ @model.sphinx_facets.detect { |facet| facet.name == name }
+ end
+
+ def subclasses_to_s
+ "'" + (@model.send(:subclasses).collect { |klass|
+ klass.to_crc32.to_s
+ } << @model.to_crc32.to_s).join(",") + "'"
+ end
def set_source_database_settings(source)
config = @model.connection.instance_variable_get(:@config)
source.sql_host = config[:host] || "localhost"
@@ -301,13 +296,13 @@
source.sql_db = config[:database]
source.sql_port = config[:port]
source.sql_sock = config[:socket]
end
- def set_source_attributes(source)
+ def set_source_attributes(source, offset = nil)
attributes.each do |attrib|
- source.send(attrib.type_to_config) << attrib.config_value
+ source.send(attrib.type_to_config) << attrib.config_value(offset)
end
end
def set_source_sql(source, offset, delta = false)
source.sql_query = to_sql(:offset => offset, :delta => delta).gsub(/\n/, ' ')
@@ -370,18 +365,18 @@
internal_groupings = []
if @model.column_names.include?(@model.inheritance_column)
internal_groupings << "#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)}"
end
- unique_id_expr = "* #{ThinkingSphinx.indexed_models.size} + #{options[:offset] || 0}"
+ unique_id_expr = ThinkingSphinx.unique_id_expression(options[:offset])
sql = <<-SQL
SELECT #{ (
["#{@model.quoted_table_name}.#{quote_column(@model.primary_key)} #{unique_id_expr} AS #{quote_column(@model.primary_key)} "] +
@fields.collect { |field| field.to_select_sql } +
@attributes.collect { |attribute| attribute.to_select_sql }
-).join(", ") }
+).compact.join(", ") }
FROM #{ @model.table_name }
#{ assocs.collect { |assoc| assoc.to_sql }.join(' ') }
WHERE #{@model.quoted_table_name}.#{quote_column(@model.primary_key)} >= $start
AND #{@model.quoted_table_name}.#{quote_column(@model.primary_key)} <= $end
#{ where_clause }
@@ -391,13 +386,10 @@
@attributes.collect { |attribute| attribute.to_group_sql }.compact +
@groupings + internal_groupings
).join(", ") }
SQL
- if @model.connection.class.name == "ActiveRecord::ConnectionAdapters::MysqlAdapter"
- sql += " ORDER BY NULL"
- end
-
+ sql += " ORDER BY NULL" if adapter.sphinx_identifier == "mysql"
sql
end
# Simple helper method for the query info SQL - which is a statement that
# returns the single row for a corresponding id.