lib/thinking_sphinx/attribute.rb in ebeigarts-thinking-sphinx-1.1.22 vs lib/thinking_sphinx/attribute.rb in ebeigarts-thinking-sphinx-1.2.10
- old
+ new
@@ -73,11 +73,13 @@
@type = options[:type]
@query_source = options[:source]
@crc = options[:crc]
@type ||= :multi unless @query_source.nil?
- @type = :integer if @type == :string && @crc
+ if @type == :string && @crc
+ @type = is_many? ? :multi : :integer
+ end
source.attributes << self
end
# Get the part of the SELECT clause related to this attribute. Don't forget
@@ -87,18 +89,25 @@
# datetimes to timestamps, as needed.
#
def to_select_sql
return nil unless include_as_association?
- separator = all_ints? || @crc ? ',' : ' '
+ separator = all_ints? || all_datetimes? || @crc ? ',' : ' '
clause = @columns.collect { |column|
part = column_with_prefix(column)
- type == :string ? adapter.convert_nulls(part) : part
+ case type
+ when :string
+ adapter.convert_nulls(part)
+ when :datetime
+ adapter.cast_to_datetime(part)
+ else
+ part
+ end
}.join(', ')
- clause = adapter.cast_to_datetime(clause) if type == :datetime
+ # clause = adapter.cast_to_datetime(clause) if type == :datetime
clause = adapter.crc(clause) if @crc
clause = adapter.concatenate(clause, separator) if concat_ws?
clause = adapter.group_concatenate(clause, separator) if is_many?
"#{clause} AS #{quote_column(unique_name)}"
@@ -123,14 +132,14 @@
# Returns the configuration value that should be used for
# the attribute.
# Special case is the multi-valued attribute that needs some
# extra configuration.
#
- def config_value(offset = nil)
+ def config_value(offset = nil, delta = false)
if type == :multi && ThinkingSphinx::Configuration.instance.type != "xml"
multi_config = include_as_association? ? "field" :
- source_value(offset).gsub(/\s+/m, " ").strip
+ source_value(offset, delta).gsub(/\s+/m, " ").strip
"uint #{unique_name} from #{multi_config}"
else
unique_name
end
end
@@ -141,10 +150,12 @@
# actual column's datatype is and returns that.
#
def type
@type ||= begin
base_type = case
+ when is_many_datetimes?
+ :datetime
when is_many?, is_many_ints?
:multi
when @associations.values.flatten.length > 1
:string
else
@@ -170,29 +181,33 @@
column.__stack.each { |method| object = object.send(method) }
object.send(column.__name)
end
def all_ints?
- @columns.all? { |col|
- klasses = @associations[col].empty? ? [@model] :
- @associations[col].collect { |assoc| assoc.reflection.klass }
- klasses.all? { |klass|
- column = klass.columns.detect { |column| column.name == col.__name.to_s }
- !column.nil? && column.type == :integer
- }
- }
+ all_of_type?(:integer)
end
+ def all_datetimes?
+ all_of_type?(:datetime, :date, :timestamp)
+ end
+
private
- def source_value(offset)
+ def source_value(offset, delta)
if is_string?
- "#{query_source.to_s.dasherize}; #{columns.first.__name}"
- elsif query_source == :ranged_query
- "ranged-query; #{query offset} #{query_clause}; #{range_query}"
+ return "#{query_source.to_s.dasherize}; #{columns.first.__name}"
+ end
+
+ query = query(offset)
+
+ if query_source == :ranged_query
+ query += query_clause
+ query += " AND #{query_delta.strip}" if delta
+ "ranged-query; #{query}; #{range_query}"
else
- "query; #{query offset}"
+ query += "WHERE #{query_delta.strip}" if delta
+ "query; #{query}"
end
end
def query(offset)
base_assoc = base_association_for_mva
@@ -210,10 +225,19 @@
def query_clause
foreign_key = foreign_key_for_mva base_association_for_mva
"WHERE #{foreign_key} >= $start AND #{foreign_key} <= $end"
end
+ def query_delta
+ foreign_key = foreign_key_for_mva base_association_for_mva
+ <<-SQL
+#{foreign_key} IN (SELECT #{quote_column model.primary_key}
+FROM #{model.quoted_table_name}
+WHERE #{@source.index.delta_object.clause(model, true)})
+ SQL
+ end
+
def range_query
assoc = base_association_for_mva
foreign_key = foreign_key_for_mva assoc
"SELECT MIN(#{foreign_key}), MAX(#{foreign_key}) FROM #{quote_table_name assoc.table}"
end
@@ -257,18 +281,23 @@
end
def is_many_ints?
concat_ws? && all_ints?
end
-
+
+ def is_many_datetimes?
+ is_many? && all_datetimes?
+ end
+
def type_from_database
klass = @associations.values.flatten.first ?
@associations.values.flatten.first.reflection.klass : @model
- klass.columns.detect { |col|
+ column = klass.columns.detect { |col|
@columns.collect { |c| c.__name.to_s }.include? col.name
- }.type
+ }
+ column.nil? ? nil : column.type
end
def translated_type_from_database
case type_from_db = type_from_database
when :datetime, :string, :float, :boolean, :integer
@@ -285,8 +314,19 @@
You could try to explicitly convert the column's value in your define_index
block:
has "CAST(column AS INT)", :type => :integer, :as => :column
MESSAGE
end
+ end
+
+ def all_of_type?(*column_types)
+ @columns.all? { |col|
+ klasses = @associations[col].empty? ? [@model] :
+ @associations[col].collect { |assoc| assoc.reflection.klass }
+ klasses.all? { |klass|
+ column = klass.columns.detect { |column| column.name == col.__name.to_s }
+ !column.nil? && column_types.include?(column.type)
+ }
+ }
end
end
end
\ No newline at end of file