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.