<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/thinking_sphinx/collection.rb</filename>
    </added>
    <added>
      <filename>spec/fixtures/sphinx/.gitignore</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -4,4 +4,5 @@ coverage
 *.tmproj
 rdoc
 spec/fixtures/database.yml
-.svn
\ No newline at end of file
+.svn
+tmp</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -54,4 +54,12 @@ Since I first released this library, there's been quite a few people who have su
 - Andrew Bennett
 - Jordan Fowler
 - Seth Walker
-- Joe Noon
\ No newline at end of file
+- Joe Noon
+- Wolfgang Postler
+- Rick Olson
+- Killian Murphy
+- Morten Primdahl
+- Ryan Bates
+- David Eisinger
+- Shay Arnett
+- Minh Tran</diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -54,4 +54,12 @@ Since I first released this library, there's been quite a few people who have su
 * Andrew Bennett
 * Jordan Fowler
 * Seth Walker
-* Joe Noon
\ No newline at end of file
+* Joe Noon
+* Wolfgang Postler
+* Rick Olson
+* Killian Murphy
+* Morten Primdahl
+* Ryan Bates
+* David Eisinger
+* Shay Arnett
+* Minh Tran</diff>
      <filename>README.textile</filename>
    </modified>
    <modified>
      <diff>@@ -27,6 +27,7 @@ end
 desc &quot;Run the specs under spec&quot;
 Spec::Rake::SpecTask.new do |t|
   t.spec_files = FileList['spec/**/*_spec.rb']
+  t.spec_opts &lt;&lt; &quot;-c&quot;
 end
 
 desc &quot;Generate RCov reports&quot;
@@ -38,7 +39,7 @@ Spec::Rake::SpecTask.new(:rcov) do |t|
 end
 
 spec = Gem::Specification.new do |s|
-  s.name              = &quot;thinking_sphinx&quot;
+  s.name              = &quot;thinking-sphinx&quot;
   s.version           = ThinkingSphinx::Version::String
   s.summary           = &quot;A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.&quot;
   s.description       = &quot;A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.&quot;
@@ -63,4 +64,9 @@ Rake::GemPackageTask.new(spec) do |p|
   p.gem_spec = spec
   p.need_tar = true
   p.need_zip = true
-end
\ No newline at end of file
+end
+
+desc &quot;Build gemspec file&quot;
+task :build do
+  File.open('thinking-sphinx.gemspec', 'w') { |f| f.write spec.to_ruby }
+end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1,3 @@
-require 'thinking_sphinx'
\ No newline at end of file
+require 'thinking_sphinx'
+
+ThinkingSphinx::Configuration.new.load_models
\ No newline at end of file</diff>
      <filename>init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -179,12 +179,12 @@ module Riddle
     # Example:
     #   client.set_anchor('lat', -0.6591741, 'long', 2.530770)
     #
-    def set_anchor(lat_attr, lat, long_attr, long)
+    def set_anchor(lat_attr, lat, long_attr, long, units='')
       @anchor = {
         :latitude_attribute   =&gt; lat_attr,
-        :latitude             =&gt; lat,
+        :latitude             =&gt; (units == 'degrees' ? lat * Math::PI / 180 : lat),
         :longitude_attribute  =&gt; long_attr,
-        :longitude            =&gt; long
+        :longitude            =&gt; (units == 'degrees' ? long * Math::PI / 180 : long)
       }
     end
     </diff>
      <filename>lib/riddle/client.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,6 +4,7 @@ require 'riddle'
 require 'thinking_sphinx/active_record'
 require 'thinking_sphinx/association'
 require 'thinking_sphinx/attribute'
+require 'thinking_sphinx/collection'
 require 'thinking_sphinx/configuration'
 require 'thinking_sphinx/field'
 require 'thinking_sphinx/index'
@@ -20,7 +21,7 @@ module ThinkingSphinx
   module Version #:nodoc:
     Major = 0
     Minor = 9
-    Tiny  = 8
+    Tiny  = 9
     
     String = [Major, Minor, Tiny].join('.')
   end</diff>
      <filename>lib/thinking_sphinx.rb</filename>
    </modified>
    <modified>
      <diff>@@ -99,6 +99,10 @@ module ThinkingSphinx
             end
             result ^ 0xFFFFFFFF
           end
+          
+          def to_crc32s
+            (subclasses &lt;&lt; self).collect { |klass| klass.to_crc32 }
+          end
         end
       end
       </diff>
      <filename>lib/thinking_sphinx/active_record.rb</filename>
    </modified>
    <modified>
      <diff>@@ -28,7 +28,14 @@ module ThinkingSphinx
               args &lt;&lt; options
               ThinkingSphinx::Search.search(*args)
             end
-            
+
+            def search_count(*args)
+              options = args.extract_options!
+              options[:class] = self
+              args &lt;&lt; options
+              ThinkingSphinx::Search.count(*args)
+            end
+
             def search_for_id(*args)
               options = args.extract_options!
               options[:class] = self</diff>
      <filename>lib/thinking_sphinx/active_record/search.rb</filename>
    </modified>
    <modified>
      <diff>@@ -29,10 +29,9 @@ module ThinkingSphinx
   # config/sphinx.yml with settings for each environment, in a similar
   # fashion to database.yml - using the following keys: config_file,
   # searchd_log_file, query_log_file, pid_file, searchd_file_path, port,
-  # allow_star, min_prefix_len, min_infix_len, mem_limit, max_matches,
-  # morphology, charset_type, charset_table, ignore_chars, html_strip,
-  # html_remove_elements. I think you've got
-  # the idea.
+  # allow_star, enable_star, min_prefix_len, min_infix_len, mem_limit,
+  # max_matches, # morphology, charset_type, charset_table, ignore_chars,
+  # html_strip, # html_remove_elements. I think you've got the idea.
   # 
   # Each setting in the YAML file is optional - so only put in the ones you
   # want to change.
@@ -43,10 +42,10 @@ module ThinkingSphinx
   # 
   class Configuration
     attr_accessor :config_file, :searchd_log_file, :query_log_file,
-      :pid_file, :searchd_file_path, :address, :port, :allow_star,
-      :min_prefix_len, :min_infix_len, :mem_limit, :max_matches, :morphology,
-      :charset_type, :charset_table, :ignore_chars, :html_strip,
-      :html_remove_elements, :app_root
+      :pid_file, :searchd_file_path, :address, :port, :enable_star,
+      :allow_star, :min_prefix_len, :min_infix_len, :mem_limit, :max_matches,
+      :morphology, :charset_type, :charset_table, :ignore_chars, :html_strip,
+      :html_remove_elements, :database_yml_file, :app_root
     
     attr_reader :environment
     
@@ -58,6 +57,7 @@ module ThinkingSphinx
       self.app_root          = Merb.root  if defined?(Merb)
       self.app_root        ||= app_root
       
+      self.database_yml_file    = &quot;#{self.app_root}/config/database.yml&quot;
       self.config_file          = &quot;#{self.app_root}/config/#{environment}.sphinx.conf&quot;
       self.searchd_log_file     = &quot;#{self.app_root}/log/searchd.log&quot;
       self.query_log_file       = &quot;#{self.app_root}/log/searchd.query.log&quot;
@@ -66,8 +66,9 @@ module ThinkingSphinx
       self.address              = &quot;127.0.0.1&quot;
       self.port                 = 3312
       self.allow_star           = false
-      self.min_prefix_len       = 1
-      self.min_infix_len        = 1
+      self.enable_star          = false
+      self.min_prefix_len       = nil
+      self.min_infix_len        = nil
       self.mem_limit            = &quot;64M&quot;
       self.max_matches          = 1000
       self.morphology           = &quot;stem_en&quot;
@@ -97,7 +98,7 @@ module ThinkingSphinx
     def build(file_path=nil)
       load_models
       file_path ||= &quot;#{self.config_file}&quot;
-      database_confs = YAML::load(ERB.new(IO.read(&quot;#{app_root}/config/database.yml&quot;)).result)
+      database_confs = YAML::load(ERB.new(IO.read(&quot;#{self.database_yml_file}&quot;)).result)
       database_confs.symbolize_keys!
       database_conf  = database_confs[environment.to_sym]
       database_conf.symbolize_keys!
@@ -122,22 +123,24 @@ searchd
 }
         CONFIG
         
-        ThinkingSphinx.indexed_models.each do |model|
+        ThinkingSphinx.indexed_models.each_with_index do |model, model_index|
           model           = model.constantize
           sources         = []
           delta_sources   = []
           prefixed_fields = []
           infixed_fields  = []
           
-          model.indexes.each_with_index do |index, i|
-            file.write index.to_config(i, database_conf, charset_type)
+          model.indexes.select { |index| index.model == model }.each_with_index do |index, i|
+            file.write index.to_config(model, i, database_conf, charset_type, model_index)
             
             create_array_accum if index.adapter == :postgres
-            sources &lt;&lt; &quot;#{model.indexes.first.name}_#{i}_core&quot;
-            delta_sources &lt;&lt; &quot;#{model.indexes.first.name}_#{i}_delta&quot; if index.delta?
+            sources &lt;&lt; &quot;#{ThinkingSphinx::Index.name(model)}_#{i}_core&quot;
+            delta_sources &lt;&lt; &quot;#{ThinkingSphinx::Index.name(model)}_#{i}_delta&quot; if index.delta?
           end
           
-          source_list = sources.collect { |s| &quot;source = #{s}&quot; }.join(&quot;\n&quot;)
+          next if sources.empty?
+          
+          source_list = sources.collect       { |s| &quot;source = #{s}&quot; }.join(&quot;\n&quot;)
           delta_list  = delta_sources.collect { |s| &quot;source = #{s}&quot; }.join(&quot;\n&quot;)
           
           file.write core_index_for_model(model, source_list)
@@ -167,8 +170,7 @@ searchd
         begin
           model_name.camelize.constantize
         rescue LoadError
-          model_name.gsub!(/.*[\/\\]/, '')
-          retry
+          model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry
         rescue NameError
           next
         end
@@ -194,10 +196,10 @@ searchd
     def core_index_for_model(model, sources)
       output = &lt;&lt;-INDEX
 
-index #{model.indexes.first.name}_core
+index #{ThinkingSphinx::Index.name(model)}_core
 {
 #{sources}
-path = #{self.searchd_file_path}/#{model.indexes.first.name}_core
+path = #{self.searchd_file_path}/#{ThinkingSphinx::Index.name(model)}_core
 charset_type = #{self.charset_type}
 INDEX
       
@@ -209,20 +211,30 @@ INDEX
       output += &quot;  ignore_chars   = #{self.ignore_chars}\n&quot;  unless self.ignore_chars.nil?
       
       if self.allow_star
+        # Ye Olde way of turning on enable_star
         output += &quot;  enable_star    = 1\n&quot;
         output += &quot;  min_prefix_len = #{self.min_prefix_len}\n&quot;
-        output += &quot;  min_infix_len  = #{self.min_infix_len}\n&quot;
+      else
+        # New, better way of turning on enable_star - thanks to James Healy
+        output += &quot;  enable_star    = 1\n&quot; if self.enable_star
+        output += &quot;  min_prefix_len = #{self.min_prefix_len}\n&quot; unless self.min_prefix_len.nil?
+        output += &quot;  min_infix_len  = #{self.min_infix_len}\n&quot; unless self.min_infix_len.nil?
       end
       
+
       output += &quot;  html_strip     = 1\n&quot; if self.html_strip
       output += &quot;  html_remove_elements = #{self.html_remove_elements}\n&quot; unless self.html_remove_elements.blank?
 
       unless model.indexes.collect(&amp;:prefix_fields).flatten.empty?
-        output += &quot;  prefix_fields = #{model.indexes.collect(&amp;:prefix_fields).flatten.join(', ')}\n&quot;
+        output += &quot;  prefix_fields = #{model.indexes.collect(&amp;:prefix_fields).flatten.map(&amp;:unique_name).join(', ')}\n&quot;
+      else
+        output += &quot; prefix_fields = _\n&quot; unless model.indexes.collect(&amp;:infix_fields).flatten.empty?
       end
       
       unless model.indexes.collect(&amp;:infix_fields).flatten.empty?
-        output += &quot;  infix_fields  = #{model.indexes.collect(&amp;:infix_fields).flatten.join(', ')}\n&quot;
+        output += &quot;  infix_fields  = #{model.indexes.collect(&amp;:infix_fields).flatten.map(&amp;:unique_name).join(', ')}\n&quot;
+      else
+        output += &quot; infix_fields = -\n&quot; unless model.indexes.collect(&amp;:prefix_fields).flatten.empty?
       end
       
       output + &quot;}\n&quot;
@@ -230,22 +242,22 @@ INDEX
     
     def delta_index_for_model(model, sources)
       &lt;&lt;-INDEX
-index #{model.indexes.first.name}_delta : #{model.indexes.first.name}_core
+index #{ThinkingSphinx::Index.name(model)}_delta : #{ThinkingSphinx::Index.name(model)}_core
 {
   #{sources}
-  path = #{self.searchd_file_path}/#{model.indexes.first.name}_delta
+  path = #{self.searchd_file_path}/#{ThinkingSphinx::Index.name(model)}_delta
 }
       INDEX
     end
     
     def distributed_index_for_model(model)
-      sources = [&quot;local = #{model.indexes.first.name}_core&quot;]
+      sources = [&quot;local = #{ThinkingSphinx::Index.name(model)}_core&quot;]
       if model.indexes.any? { |index| index.delta? }
-        sources &lt;&lt; &quot;local = #{model.indexes.first.name}_delta&quot;
+        sources &lt;&lt; &quot;local = #{ThinkingSphinx::Index.name(model)}_delta&quot;
       end
       
       &lt;&lt;-INDEX
-index #{model.indexes.first.name}
+index #{ThinkingSphinx::Index.name(model)}
 {
   type = distributed
   #{ sources.join(&quot;\n  &quot;) }</diff>
      <filename>lib/thinking_sphinx/configuration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -178,7 +178,9 @@ module ThinkingSphinx
     # figure out how to correctly reference a column in SQL.
     #
     def column_with_prefix(column)
-      if associations[column].empty?
+      if column.is_string?
+        column.__name
+      elsif associations[column].empty?
         &quot;#{@model.quoted_table_name}.#{quote_column(column.__name)}&quot;
       else
         associations[column].collect { |assoc|
@@ -196,5 +198,9 @@ module ThinkingSphinx
     def is_many?
       associations.values.flatten.any? { |assoc| assoc.is_many? }
     end
+    
+    def is_string?
+      columns.all? { |col| col.is_string? }
+    end
   end
 end</diff>
      <filename>lib/thinking_sphinx/field.rb</filename>
    </modified>
    <modified>
      <diff>@@ -38,6 +38,10 @@ module ThinkingSphinx
     end
     
     def name
+      self.class.name(@model)
+    end
+    
+    def self.name(model)
       model.name.underscore.tr(':/\\', '_')
     end
     
@@ -46,8 +50,9 @@ module ThinkingSphinx
       File.size?(&quot;#{config.searchd_file_path}/#{self.name}_#{part}.spa&quot;).nil?
     end
     
-    def to_config(index, database_conf, charset_type)
+    def to_config(model, index, database_conf, charset_type, offset)
       # Set up associations and joins
+      add_internal_attributes
       link!
       
       attr_sources = attributes.collect { |attrib|
@@ -65,20 +70,21 @@ module ThinkingSphinx
       
       config = &lt;&lt;-SOURCE
 
-source #{model.indexes.first.name}_#{index}_core
+source #{self.class.name(model)}_#{index}_core
 {
 type     = #{db_adapter}
 sql_host = #{database_conf[:host] || &quot;localhost&quot;}
-sql_user = #{database_conf[:username]}
-sql_pass = #{database_conf[:password]}
+sql_user = #{database_conf[:username] || database_conf[:user]}
+sql_pass = #{(database_conf[:password] || &quot;&quot;).gsub('#', '\#')}
 sql_db   = #{database_conf[:database]}
+#{&quot;sql_sock = #{database_conf[:socket]}&quot; unless database_conf[:socket].blank? }
 
 sql_query_pre    = #{charset_type == &quot;utf-8&quot; &amp;&amp; adapter == :mysql ? &quot;SET NAMES utf8&quot; : &quot;&quot;}
 #{&quot;sql_query_pre    = SET SESSION group_concat_max_len = #{@options[:group_concat_max_len]}&quot; if @options[:group_concat_max_len]}
 sql_query_pre    = #{to_sql_query_pre}
-sql_query        = #{to_sql.gsub(/\n/, ' ')}
+sql_query        = #{to_sql(:offset =&gt; offset).gsub(/\n/, ' ')}
 sql_query_range  = #{to_sql_query_range}
-sql_query_info   = #{to_sql_query_info}
+sql_query_info   = #{to_sql_query_info(offset)}
 #{attr_sources}
 }
       SOURCE
@@ -86,12 +92,12 @@ sql_query_info   = #{to_sql_query_info}
       if delta?
         config += &lt;&lt;-SOURCE
 
-source #{model.indexes.first.name}_#{index}_delta : #{model.indexes.first.name}_#{index}_core
+source #{self.class.name(model)}_#{index}_delta : #{self.class.name(model)}_#{index}_core
 {
 sql_query_pre    = 
 sql_query_pre    = #{charset_type == &quot;utf-8&quot; &amp;&amp; adapter == :mysql ? &quot;SET NAMES utf8&quot; : &quot;&quot;}
 #{&quot;sql_query_pre    = SET SESSION group_concat_max_len = #{@options[:group_concat_max_len]}&quot; if @options[:group_concat_max_len]}
-sql_query        = #{to_sql(:delta =&gt; true).gsub(/\n/, ' ')}
+sql_query        = #{to_sql(:delta =&gt; true, :offset =&gt; offset).gsub(/\n/, ' ')}
 sql_query_range  = #{to_sql_query_range :delta =&gt; true}
 }
         SOURCE
@@ -149,9 +155,11 @@ sql_query_range  = #{to_sql_query_range :delta =&gt; true}
         where_clause &lt;&lt; &quot; AND &quot; &lt;&lt; @conditions.join(&quot; AND &quot;)
       end
       
+      unique_id_expr = &quot;* #{ThinkingSphinx.indexed_models.size} + #{options[:offset] || 0}&quot;
+      
       sql = &lt;&lt;-SQL
 SELECT #{ (
-  [&quot;#{@model.quoted_table_name}.#{quote_column(@model.primary_key)}&quot;] + 
+  [&quot;#{@model.quoted_table_name}.#{quote_column(@model.primary_key)} #{unique_id_expr} AS #{quote_column(@model.primary_key)} &quot;] + 
   @fields.collect { |field| field.to_select_sql } +
   @attributes.collect { |attribute| attribute.to_select_sql }
 ).join(&quot;, &quot;) }
@@ -177,9 +185,9 @@ GROUP BY #{ (
     # 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
+    def to_sql_query_info(offset)
       &quot;SELECT * FROM #{@model.quoted_table_name} WHERE &quot; +
-      &quot; #{quote_column(@model.primary_key)} = $id&quot;
+      &quot; #{quote_column(@model.primary_key)} = (($id - #{offset}) / #{ThinkingSphinx.indexed_models.size})&quot;
     end
     
     # Simple helper method for the query range SQL - which is a statement that
@@ -265,17 +273,6 @@ GROUP BY #{ (
       @conditions = builder.conditions
       @delta      = builder.properties[:delta]
       @options    = builder.properties.except(:delta)
-      
-      @attributes &lt;&lt; Attribute.new(
-        FauxColumn.new(@model.to_crc32.to_s),
-        :type =&gt; :integer,
-        :as   =&gt; :class_crc
-      )
-      @attributes &lt;&lt; Attribute.new(
-        FauxColumn.new(&quot;0&quot;),
-        :type =&gt; :integer,
-        :as   =&gt; :sphinx_deleted
-      )
     end
     
     # Returns all associations used amongst all the fields and attributes.
@@ -335,5 +332,43 @@ GROUP BY #{ (
         val ? '1' : '0'
       end
     end
+    
+    def crc_column
+      if adapter == :postgres
+        @model.to_crc32.to_s
+      elsif @model.column_names.include?(@model.inheritance_column)
+        &quot;IFNULL(CRC32(#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)}), #{@model.to_crc32.to_s})&quot;
+      else
+        @model.to_crc32.to_s
+      end
+    end
+    
+    def add_internal_attributes
+      @attributes &lt;&lt; Attribute.new(
+        FauxColumn.new(:id),
+        :type =&gt; :integer,
+        :as   =&gt; :sphinx_internal_id
+      ) unless @attributes.detect { |attr| attr.alias == :sphinx_internal_id }
+      
+      @attributes &lt;&lt; Attribute.new(
+        FauxColumn.new(crc_column),
+        :type =&gt; :integer,
+        :as   =&gt; :class_crc
+      ) unless @attributes.detect { |attr| attr.alias == :class_crc }
+      
+      @attributes &lt;&lt; Attribute.new(
+        FauxColumn.new(&quot;'&quot; + (@model.send(:subclasses).collect { |klass|
+          klass.to_crc32.to_s
+        } &lt;&lt; @model.to_crc32.to_s).join(&quot;,&quot;) + &quot;'&quot;),
+        :type =&gt; :multi,
+        :as   =&gt; :subclass_crcs
+      ) unless @attributes.detect { |attr| attr.alias == :subclass_crcs }
+      
+      @attributes &lt;&lt; Attribute.new(
+        FauxColumn.new(&quot;0&quot;),
+        :type =&gt; :integer,
+        :as   =&gt; :sphinx_deleted
+      ) unless @attributes.detect { |attr| attr.alias == :sphinx_deleted }
+    end
   end
 end</diff>
      <filename>lib/thinking_sphinx/index.rb</filename>
    </modified>
    <modified>
      <diff>@@ -81,8 +81,7 @@ module ThinkingSphinx
         def indexes(*args)
           options = args.extract_options!
           args.each do |columns|
-            columns = FauxColumn.new(columns) if columns.is_a?(Symbol)
-            fields &lt;&lt; Field.new(columns, options)
+            fields &lt;&lt; Field.new(FauxColumn.coerce(columns), options)
             
             if fields.last.sortable
               attributes &lt;&lt; Attribute.new(
@@ -137,23 +136,7 @@ module ThinkingSphinx
         def has(*args)
           options = args.extract_options!
           args.each do |columns|
-            columns = case columns
-            when Symbol, String
-              FauxColumn.new(columns)
-            when Array
-              columns.collect { |col|
-                case col
-                when Symbol, String
-                  FauxColumn.new(col)
-                else
-                  col
-                end
-              }
-            else
-              columns
-            end
-            
-            attributes &lt;&lt; Attribute.new(columns, options)
+            attributes &lt;&lt; Attribute.new(FauxColumn.coerce(columns), options)
           end
         end
         alias_method :attribute, :has</diff>
      <filename>lib/thinking_sphinx/index/builder.rb</filename>
    </modified>
    <modified>
      <diff>@@ -15,6 +15,19 @@ module ThinkingSphinx
         @stack = stack
       end
       
+      def self.coerce(columns)
+        case columns
+        when Symbol, String
+          FauxColumn.new(columns)
+        when Array
+          columns.collect { |col| FauxColumn.coerce(col) }
+        when FauxColumn
+          columns
+        else
+          nil
+        end
+      end
+      
       # Can't use normal method name, as that could be an association or
       # column name.
       # </diff>
      <filename>lib/thinking_sphinx/index/faux_column.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,7 @@ module ThinkingSphinx
   # Most times, you will just want a specific model's results - to search and
   # search_for_ids methods will do the job in exactly the same manner when
   # called from a model.
-  # 
+  #
   class Search
     class &lt;&lt; self
       # Searches for results that match the parameters provided. Will only
@@ -14,18 +14,25 @@ module ThinkingSphinx
       #
       def search_for_ids(*args)
         results, client = search_results(*args.clone)
-        
+
         options = args.extract_options!
         page    = options[:page] ? options[:page].to_i : 1
-        
+
         begin
           pager = WillPaginate::Collection.create(page,
             client.limit, results[:total_found] || 0) do |collection|
-            collection.replace results[:matches].collect { |match| match[:doc] }
+            collection.replace results[:matches].collect { |match|
+              match[:attributes][&quot;sphinx_internal_id&quot;]
+            }
             collection.instance_variable_set :@total_entries, results[:total_found]
           end
+          return (options[:include_raw] ? [pager, results] : pager)
         rescue
-          results[:matches].collect { |match| match[:doc] }
+          if options[:include_raw]
+            return results[:matches].collect{ |match| match[:attributes][&quot;sphinx_internal_id&quot;] }, results
+          else
+            return results[:matches].collect { |match| match[:attributes][&quot;sphinx_internal_id&quot;] }
+          end
         end
       end
 
@@ -37,11 +44,11 @@ module ThinkingSphinx
       # just like paginate. The same parameters - :page and :per_page - work as
       # expected, and the returned result set can be used by the will_paginate
       # helper.
-      # 
+      #
       # == Basic Searching
       #
       # The simplest way of searching is straight text.
-      # 
+      #
       #   ThinkingSphinx::Search.search &quot;pat&quot;
       #   ThinkingSphinx::Search.search &quot;google&quot;
       #   User.search &quot;pat&quot;, :page =&gt; (params[:page] || 1)
@@ -49,7 +56,7 @@ module ThinkingSphinx
       #
       # If you specify :include, like in an #find call, this will be respected
       # when loading the relevant models from the search results.
-      # 
+      #
       #   User.search &quot;pat&quot;, :include =&gt; :posts
       #
       # == Advanced Searching
@@ -71,10 +78,10 @@ module ThinkingSphinx
       # details.
       #
       # == Searching by Fields
-      # 
+      #
       # If you want to step it up a level, you can limit your search terms to
       # specific fields:
-      # 
+      #
       #   User.search :conditions =&gt; {:name =&gt; &quot;pat&quot;}
       #
       # This uses Sphinx's extended match mode, unless you specify a different
@@ -94,11 +101,11 @@ module ThinkingSphinx
       # (not multi-model searching). With a single model, Thinking Sphinx
       # can figure out what attributes and fields are available, so you can
       # put it all in the :conditions hash, and it will sort it out.
-      # 
+      #
       #   Node.search :conditions =&gt; {:parent_id =&gt; 10}
-      # 
+      #
       # Filters can be single values, arrays of values, or ranges.
-      # 
+      #
       #   Article.search &quot;East Timor&quot;, :conditions =&gt; {:rating =&gt; 3..5}
       #
       # == Excluding by Attributes
@@ -107,7 +114,7 @@ module ThinkingSphinx
       # attribute values to exclude. This is done with the :without option:
       #
       #   User.search :without =&gt; {:role_id =&gt; 1}
-      # 
+      #
       # == Sorting
       #
       # Sphinx can only sort by attributes, so generally you will need to avoid
@@ -132,13 +139,13 @@ module ThinkingSphinx
       # detail though.
       #
       # == Grouping
-      # 
+      #
       # For this you can use the group_by, group_clause and group_function
       # options - which are all directly linked to Sphinx's expectations. No
       # magic from Thinking Sphinx. It can get a little tricky, so make sure
       # you read all the relevant
       # documentation[http://sphinxsearch.com/doc.html#clustering] first.
-      # 
+      #
       # Yes this section will be expanded, but this is a start.
       #
       # == Geo/Location Searching
@@ -148,11 +155,11 @@ module ThinkingSphinx
       # take advantage of this, you will need to have both of those values in
       # attributes. To search with that point, you can then use one of the
       # following syntax examples:
-      # 
+      #
       #   Address.search &quot;Melbourne&quot;, :geo =&gt; [1.4, -2.217]
       #   Address.search &quot;Australia&quot;, :geo =&gt; [-0.55, 3.108],
       #     :latitude_attr =&gt; &quot;latit&quot;, :longitude_attr =&gt; &quot;longit&quot;
-      # 
+      #
       # The first example applies when your latitude and longitude attributes
       # are named any of lat, latitude, lon, long or longitude. If that's not
       # the case, you will need to explicitly state them in your search, _or_
@@ -161,17 +168,17 @@ module ThinkingSphinx
       #   define_index do
       #     has :latit  # Float column, stored in radians
       #     has :longit # Float column, stored in radians
-      #     
+      #
       #     set_property :latitude_attr   =&gt; &quot;latit&quot;
       #     set_property :longitude_attr  =&gt; &quot;longit&quot;
       #   end
-      # 
+      #
       # Now, geo-location searching really only has an affect if you have a
       # filter, sort or grouping clause related to it - otherwise it's just a
       # normal search. To make use of the positioning difference, use the
       # special attribute &quot;@geodist&quot; in any of your filters or sorting or grouping
       # clauses.
-      # 
+      #
       # And don't forget - both the latitude and longitude you use in your
       # search, and the values in your indexes, need to be stored as a float in radians,
       # _not_ degrees. Keep in mind that if you do this conversion in SQL
@@ -181,77 +188,90 @@ module ThinkingSphinx
       #     has 'RADIANS(lat)', :as =&gt; :lat,  :type =&gt; :float
       #     # ...
       #   end
-      # 
+      #
       def search(*args)
         results, client = search_results(*args.clone)
-        
+
         ::ActiveRecord::Base.logger.error(
           &quot;Sphinx Error: #{results[:error]}&quot;
         ) if results[:error]
-        
+
         options = args.extract_options!
         klass   = options[:class]
         page    = options[:page] ? options[:page].to_i : 1
-        
-        begin
-          pager = WillPaginate::Collection.create(page,
-            client.limit, results[:total] || 0) do |collection|
-            collection.replace instances_from_results(results[:matches], options, klass)
-            collection.instance_variable_set :@total_entries, results[:total_found]
-          end
-        rescue StandardError =&gt; err
-          instances_from_results(results[:matches], options, klass)
-        end
+
+        # begin
+          pager = ThinkingSphinx::Collection.new(page, client.limit,
+            results[:total] || 0, results[:total_found] || 0)
+          pager.replace instances_from_results(results[:matches], options, klass)
+          # pager = WillPaginate::Collection.create(page,
+          #   client.limit, results[:total] || 0) do |collection|
+          #   collection.replace instances_from_results(results[:matches], options, klass)
+          #   collection.instance_variable_set :@total_entries, results[:total_found]
+          # end
+          return (options[:include_raw] ? [pager, results] : pager)
+        # rescue StandardError =&gt; err
+        #   if options[:include_raw]
+        #     return instances_from_results(results[:matches], options, klass), results
+        #   else
+        #     return instances_from_results(results[:matches], options, klass)
+        #   end
+        # end
       end
-      
+
+      def count(*args)
+        results, client = search_results(*args.clone)
+        results[:total] || 0
+      end
+
       # Checks if a document with the given id exists within a specific index.
       # Expected parameters:
       #
       # - ID of the document
       # - Index to check within
       # - Options hash (defaults to {})
-      # 
+      #
       # Example:
-      # 
+      #
       #   ThinkingSphinx::Search.search_for_id(10, &quot;user_core&quot;, :class =&gt; User)
-      # 
+      #
       def search_for_id(*args)
         options = args.extract_options!
         client  = client_from_options options
-        
+
         query, filters    = search_conditions(
           options[:class], options[:conditions] || {}
         )
         client.filters   += filters
         client.match_mode = :extended unless query.empty?
         client.id_range   = args.first..args.first
-        
+
         begin
           return client.query(query, args[1])[:matches].length &gt; 0
         rescue Errno::ECONNREFUSED =&gt; err
           raise ThinkingSphinx::ConnectionError, &quot;Connection to Sphinx Daemon (searchd) failed.&quot;
         end
       end
-      
+
       private
-      
+
       # This method handles the common search functionality, and returns both
       # the result hash and the client. Not super elegant, but it'll do for
       # the moment.
-      # 
+      #
       def search_results(*args)
         options = args.extract_options!
         client  = client_from_options options
-        
+
         query, filters    = search_conditions(
           options[:class], options[:conditions] || {}
         )
         client.filters   += filters
         client.match_mode = :extended unless query.empty?
         query             = args.join(&quot; &quot;) + query
-        
+
         set_sort_options! client, options
-        
+
         client.limit  = options[:per_page].to_i if options[:per_page]
         page          = options[:page] ? options[:page].to_i : 1
         client.offset = (page - 1) * client.limit
@@ -259,53 +279,69 @@ module ThinkingSphinx
         begin
           ::ActiveRecord::Base.logger.debug &quot;Sphinx: #{query}&quot;
           results = client.query query
-          ::ActiveRecord::Base.logger.debug &quot;Sphinx Result: #{results[:matches].collect{|m| m[:doc]}.inspect}&quot;
+          ::ActiveRecord::Base.logger.debug &quot;Sphinx Result: #{results[:matches].collect{|m| m[:attributes][&quot;sphinx_internal_id&quot;]}.inspect}&quot;
         rescue Errno::ECONNREFUSED =&gt; err
           raise ThinkingSphinx::ConnectionError, &quot;Connection to Sphinx Daemon (searchd) failed.&quot;
         end
-        
+
         return results, client
       end
-      
+
+      # This function loops over the records and appends a 'distance' variable to each one with
+      # the value from Sphinx
+      def append_distances(instances, results, distance_name)
+        instances.each_with_index do |record, index|
+          if record
+            distance = (results[index][:attributes]['@geodist'] or nil)
+            record.instance_variable_get('@attributes')[&quot;#{distance_name}&quot;] = distance
+          end
+        end
+      end
+
       def instances_from_results(results, options = {}, klass = nil)
         if klass.nil?
           results.collect { |result| instance_from_result result, options }
         else
-          ids = results.collect { |result| result[:doc] }
-          instances = klass.find(
+          ids = results.collect { |result| result[:attributes][&quot;sphinx_internal_id&quot;] }
+          instances = ids.length &gt; 0 ? klass.find(
             :all,
             :conditions =&gt; {klass.primary_key.to_sym =&gt; ids},
             :include    =&gt; options[:include],
             :select     =&gt; options[:select]
-          )
-          ids.collect { |obj_id| instances.detect { |obj| obj.id == obj_id } }
+          ) : []
+          final_instances = ids.collect { |obj_id| instances.detect { |obj| obj.id == obj_id } }
+
+          final_instances = append_distances(final_instances, results, options[:distance_name]) if options[:distance_name] &amp;&amp; (results.collect { |result| result[:attributes]['@geodist'] }.length &gt; 0)
+
+          return final_instances
         end
       end
-      
+
       # Either use the provided class to instantiate a result from a model, or
       # get the result's CRC value and determine the class from that.
-      # 
+      #
       def instance_from_result(result, options)
         class_from_crc(result[:attributes][&quot;class_crc&quot;]).find(
-          result[:doc], :include =&gt; options[:include], :select =&gt; options[:select]
+          result[:attributes][&quot;sphinx_internal_id&quot;],
+          :include =&gt; options[:include], :select =&gt; options[:select]
         )
       end
-      
+
       # Convert a CRC value to the corresponding class.
-      # 
+      #
       def class_from_crc(crc)
         unless @models_by_crc
           Configuration.new.load_models
-          
+
           @models_by_crc = ThinkingSphinx.indexed_models.inject({}) do |hash, model|
             hash[model.constantize.to_crc32] = model
             hash
           end
         end
-        
+
         @models_by_crc[crc].constantize
       end
-      
+
       # Set all the appropriate settings for the client, using the provided
       # options hash.
       # 
@@ -314,7 +350,7 @@ module ThinkingSphinx
         client = Riddle::Client.new config.address, config.port
         klass  = options[:class]
         index_options = klass ? klass.indexes.last.options : {}
-        
+
         [
           :max_matches, :match_mode, :sort_mode, :sort_by, :id_range,
           :group_by, :group_function, :group_clause, :group_distinct, :cut_off,
@@ -327,29 +363,32 @@ module ThinkingSphinx
           )
         end
         
-        client.anchor = anchor_conditions(klass, options) || {} if client.anchor.empty?
+        options[:classes] = [klass] if klass
         
+        client.anchor = anchor_conditions(klass, options) || {} if client.anchor.empty?
+
         client.filters &lt;&lt; Riddle::Client::Filter.new(
           &quot;sphinx_deleted&quot;, [0]
         )
+        
         # class filters
         client.filters &lt;&lt; Riddle::Client::Filter.new(
-          &quot;class_crc&quot;, options[:classes].collect { |klass| klass.to_crc32 }
+          &quot;class_crc&quot;, options[:classes].collect { |k| k.to_crc32s }.flatten
         ) if options[:classes]
-        
+
         # normal attribute filters
         client.filters += options[:with].collect { |attr,val|
           Riddle::Client::Filter.new attr.to_s, filter_value(val)
         } if options[:with]
-        
+
         # exclusive attribute filters
         client.filters += options[:without].collect { |attr,val|
           Riddle::Client::Filter.new attr.to_s, filter_value(val), true
         } if options[:without]
-        
+
         client
       end
-      
+
       def filter_value(value)
         case value
         when Range
@@ -360,70 +399,65 @@ module ThinkingSphinx
           Array(value)
         end
       end
-      
+
       # Translate field and attribute conditions to the relevant search string
       # and filters.
-      # 
+      #
       def search_conditions(klass, conditions={})
         attributes = klass ? klass.indexes.collect { |index|
           index.attributes.collect { |attrib| attrib.unique_name }
         }.flatten : []
-        
+
         search_string = &quot;&quot;
         filters       = []
-        
+
         conditions.each do |key,val|
           if attributes.include?(key.to_sym)
             filters &lt;&lt; Riddle::Client::Filter.new(
-              key.to_s,
-              val.is_a?(Range) ? val : Array(val)
+              key.to_s, filter_value(val)
             )
           else
             search_string &lt;&lt; &quot;@#{key} #{val} &quot;
           end
         end
         
-        filters &lt;&lt; Riddle::Client::Filter.new(
-          &quot;class_crc&quot;, [klass.to_crc32]
-        ) if klass
-        
         return search_string, filters
       end
-      
+
       # Return the appropriate latitude and longitude values, depending on
       # whether the relevant attributes have been defined, and also whether
       # there's actually any values.
-      # 
+      #
       def anchor_conditions(klass, options)
         attributes = klass ? klass.indexes.collect { |index|
           index.attributes.collect { |attrib| attrib.unique_name }
         }.flatten : []
-        
+
         lat_attr = klass ? klass.indexes.collect { |index|
           index.options[:latitude_attr]
         }.compact.first : nil
-        
+
         lon_attr = klass ? klass.indexes.collect { |index|
           index.options[:longitude_attr]
         }.compact.first : nil
-        
+
         lat_attr = options[:latitude_attr] if options[:latitude_attr]
         lat_attr ||= :lat       if attributes.include?(:lat)
         lat_attr ||= :latitude  if attributes.include?(:latitude)
-        
+
         lon_attr = options[:longitude_attr] if options[:longitude_attr]
         lon_attr ||= :lon       if attributes.include?(:lon)
         lon_attr ||= :long      if attributes.include?(:long)
         lon_attr ||= :longitude if attributes.include?(:longitude)
-        
+
         lat = options[:lat]
         lon = options[:lon]
-        
+
         if options[:geo]
           lat = options[:geo].first
           lon = options[:geo].last
         end
-        
+
         lat &amp;&amp; lon ? {
           :latitude_attribute   =&gt; lat_attr,
           :latitude             =&gt; lat,
@@ -431,16 +465,16 @@ module ThinkingSphinx
           :longitude            =&gt; lon
         } : nil
       end
-      
+
       # Set the sort options using the :order key as well as the appropriate
       # Riddle settings.
-      # 
+      #
       def set_sort_options!(client, options)
         klass = options[:class]
         fields = klass ? klass.indexes.collect { |index|
           index.fields.collect { |field| field.unique_name }
         }.flatten : []
-        
+
         case order = options[:order]
         when Symbol
           client.sort_mode = :attr_asc if client.sort_mode == :relevance || client.sort_mode.nil?
@@ -455,23 +489,23 @@ module ThinkingSphinx
         else
           # do nothing
         end
-        
+
         client.sort_mode = :attr_asc  if client.sort_mode == :asc
         client.sort_mode = :attr_desc if client.sort_mode == :desc
       end
-      
+
       # Search through a collection of fields and translate any appearances
       # of them in a string to their attribute equivalent for sorting.
-      # 
+      #
       def sorted_fields_to_attributes(string, fields)
         fields.each { |field|
           string.gsub!(/(^|\s)#{field}(,?\s|$)/) { |match|
             match.gsub field.to_s, field.to_s.concat(&quot;_sort&quot;)
           }
         }
-        
+
         string
       end
     end
   end
-end
+end
\ No newline at end of file</diff>
      <filename>lib/thinking_sphinx/search.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,15 +3,23 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
 require 'rubygems'
 require 'fileutils'
 require 'not_a_mock'
+require 'will_paginate'
 
 require 'lib/thinking_sphinx'
 require 'spec/sphinx_helper'
 
+ActiveRecord::Base.logger = Logger.new(StringIO.new)
+
 Spec::Runner.configure do |config|
-  # config.mock_with NotAMock::RspecMockFrameworkAdapter
+  %w( tmp tmp/config tmp/log tmp/db ).each do |path|
+    FileUtils.mkdir_p &quot;#{Dir.pwd}/#{path}&quot;
+  end
+  
+  Kernel.const_set :RAILS_ROOT, &quot;#{Dir.pwd}/tmp&quot; unless defined?(RAILS_ROOT)
   
   sphinx = SphinxHelper.new
   sphinx.setup_mysql
+  
   require 'spec/fixtures/models'
   
   config.before :all do
@@ -19,19 +27,18 @@ Spec::Runner.configure do |config|
       FileUtils.mkdir_p &quot;#{Dir.pwd}/#{path}&quot;
     end
     
-    Kernel.const_set :RAILS_ROOT, &quot;#{Dir.pwd}/tmp&quot; unless defined?(RAILS_ROOT)
-    
-    # sphinx.start
+    sphinx.setup_sphinx
+    sphinx.start
   end
   
-  config.before :each do
+  config.after :each do
     NotAMock::CallRecorder.instance.reset
     NotAMock::Stubber.instance.reset
   end
   
   config.after :all do
-    # sphinx.stop
+    sphinx.stop
     
-    FileUtils.rm_r &quot;#{Dir.pwd}/tmp&quot;
+    FileUtils.rm_r &quot;#{Dir.pwd}/tmp&quot; rescue nil
   end
 end</diff>
      <filename>spec/spec_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,10 @@
 require 'active_record'
 require 'active_record/connection_adapters/mysql_adapter'
-require 'active_record/connection_adapters/postgresql_adapter'
+begin
+  require 'active_record/connection_adapters/postgresql_adapter'
+rescue LoadError
+  # No postgres?  no prob...
+end
 require 'yaml'
 
 class SphinxHelper
@@ -30,7 +34,7 @@ class SphinxHelper
       :password =&gt; @password,
       :host     =&gt; @host
     )
-    # ActiveRecord::Base.logger = nil
+    ActiveRecord::Base.logger = Logger.new(File.open(&quot;tmp/activerecord.log&quot;, &quot;a&quot;))
     
     structure = File.open(&quot;spec/fixtures/structure.sql&quot;) { |f| f.read.chomp }
     structure.split(';').each { |table|
@@ -44,7 +48,62 @@ class SphinxHelper
     }
   end
   
+  def setup_sphinx
+    @configuration = ThinkingSphinx::Configuration.new
+    File.open(&quot;spec/fixtures/sphinx/database.yml&quot;, &quot;w&quot;) do |file|
+      YAML.dump({@configuration.environment =&gt; {
+        :adapter  =&gt; 'mysql',
+        :host     =&gt; @host,
+        :database =&gt; &quot;thinking_sphinx&quot;,
+        :username =&gt; @username,
+        :password =&gt; @password
+      }}, file)
+    end
+    FileUtils.mkdir_p(@configuration.searchd_file_path)
+    
+    @configuration.database_yml_file = &quot;spec/fixtures/sphinx/database.yml&quot;
+    @configuration.build
+    
+    index
+  end
+  
   def reset
     setup_mysql
   end
+    
+  def index
+    cmd = &quot;indexer --config #{@configuration.config_file} --all&quot;
+    cmd &lt;&lt; &quot; --rotate&quot; if running?
+    `#{cmd}`
+  end
+  
+  def start
+    return if running?
+    
+    cmd = &quot;searchd --config #{@configuration.config_file}&quot;
+    `#{cmd}`    
+
+    sleep(1)
+
+    unless running?
+      puts &quot;Failed to start searchd daemon. Check #{@configuration.searchd_log_file}.&quot;
+    end
+  end
+  
+  def stop
+    return unless running?
+    `kill #{pid}`
+  end
+  
+  def pid
+    if File.exists?(&quot;#{@configuration.pid_file}&quot;)
+      `cat #{@configuration.pid_file}`[/\d+/]
+    else
+      nil
+    end
+  end
+
+  def running?
+    pid &amp;&amp; `ps #{pid} | wc -l`.to_i &gt; 1
+  end
 end</diff>
      <filename>spec/sphinx_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,6 +9,10 @@ describe &quot;ThinkingSphinx::ActiveRecord::Search&quot; do
     ActiveRecord::Base.methods.should include(&quot;search&quot;)
   end
   
+  it &quot;should add search_count to ActiveRecord::Base&quot; do
+    ActiveRecord::Base.methods.should include(&quot;search_count&quot;)
+  end
+
   it &quot;should add search_for_id to ActiveRecord::Base&quot; do
     ActiveRecord::Base.methods.should include(&quot;search_for_id&quot;)
   end
@@ -78,4 +82,26 @@ describe &quot;ThinkingSphinx::ActiveRecord::Search&quot; do
       )
     end
   end
+
+  describe &quot;search_count method&quot; do
+    before :each do
+      ThinkingSphinx::Search.stub_method(:count =&gt; true)
+    end
+
+    it &quot;should call ThinkingSphinx::Search#search with the class option set&quot; do
+      Person.search_count(&quot;search&quot;)
+
+      ThinkingSphinx::Search.should have_received(:count).with(
+        &quot;search&quot;, :class =&gt; Person
+      )
+    end
+
+    it &quot;should override the class option&quot; do
+      Person.search_count(&quot;search&quot;, :class =&gt; Friendship)
+
+      ThinkingSphinx::Search.should have_received(:count).with(
+        &quot;search&quot;, :class =&gt; Person
+      )
+    end
+  end
 end</diff>
      <filename>spec/unit/thinking_sphinx/active_record/search_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,7 +21,7 @@ describe &quot;ThinkingSphinx::ActiveRecord&quot; do
       # Remove the class so we can redefine it
       TestModule.send(:remove_const, :TestModel)
       
-      ThinkingSphinx::Index.unstub_method(:new)
+      ThinkingSphinx.indexed_models.delete &quot;TestModule::TestModel&quot;
     end
     
     it &quot;should return nil and do nothing if indexes are disabled&quot; do</diff>
      <filename>spec/unit/thinking_sphinx/active_record_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -36,7 +36,7 @@ describe ThinkingSphinx::Configuration do
       ThinkingSphinx::Configuration.stub_method(:environment =&gt; &quot;spec&quot;)
       ThinkingSphinx::Configuration.new.environment.should == &quot;spec&quot;
       ThinkingSphinx::Configuration.should have_received(:environment)
-    end
+    end    
   end
   
   describe &quot;build method&quot; do
@@ -59,13 +59,16 @@ describe ThinkingSphinx::Configuration do
       })
       
       @person_index_a = ThinkingSphinx::Index.stub_instance(
-        :to_config =&gt; &quot;&quot;, :adapter =&gt; :mysql, :delta? =&gt; false, :name =&gt; &quot;person&quot;
+        :to_config =&gt; &quot;&quot;,   :adapter =&gt; :mysql, :delta? =&gt; false,
+        :name =&gt; &quot;person&quot;,  :model =&gt; Person
       )
       @person_index_b = ThinkingSphinx::Index.stub_instance(
-        :to_config =&gt; &quot;&quot;, :adapter =&gt; :mysql, :delta? =&gt; false, :name =&gt; &quot;person&quot;
+        :to_config =&gt; &quot;&quot;,   :adapter =&gt; :mysql, :delta? =&gt; false,
+        :name =&gt; &quot;person&quot;,  :model =&gt; Person
       )
       @friendship_index_a = ThinkingSphinx::Index.stub_instance(
-        :to_config =&gt; &quot;&quot;, :adapter =&gt; :mysql, :delta? =&gt; false, :name =&gt; &quot;friendship&quot;
+        :to_config =&gt; &quot;&quot;,       :adapter =&gt; :mysql, :delta? =&gt; false,
+        :name =&gt; &quot;friendship&quot;,  :model =&gt; Friendship
       )
       
       Person.stub_method(:indexes =&gt; [@person_index_a, @person_index_b])
@@ -81,15 +84,15 @@ describe ThinkingSphinx::Configuration do
       
       Person.unstub_method      :indexes
       Friendship.unstub_method  :indexes
-      
-      FileUtils.rm_rf &quot;#{@config.app_root}/config&quot;
+      # 
+      # FileUtils.rm_rf &quot;#{@config.app_root}/config&quot;
     end
     
-    it &quot;should load the models&quot; do
-      @config.build
-      
-      @config.should have_received(:load_models)
-    end
+    # it &quot;should load the models&quot; do
+    #   @config.build
+    #   
+    #   @config.should have_received(:load_models)
+    # end
     
     it &quot;should load in the database YAML configuration&quot; do
       @config.build
@@ -137,13 +140,13 @@ describe ThinkingSphinx::Configuration do
       @config.build
       
       @person_index_a.should have_received(:to_config).with(
-        0, {:option =&gt; &quot;value&quot;}, @config.charset_type
+        Person, 0, {:option =&gt; &quot;value&quot;}, @config.charset_type, 0
       )
       @person_index_b.should have_received(:to_config).with(
-        1, {:option =&gt; &quot;value&quot;}, @config.charset_type
+        Person, 1, {:option =&gt; &quot;value&quot;}, @config.charset_type, 0
       )
       @friendship_index_a.should have_received(:to_config).with(
-        0, {:option =&gt; &quot;value&quot;}, @config.charset_type
+        Friendship, 0, {:option =&gt; &quot;value&quot;}, @config.charset_type, 1
       )
     end
     
@@ -204,7 +207,7 @@ describe ThinkingSphinx::Configuration do
     before :each do
       @settings = {
         &quot;development&quot; =&gt; {
-          &quot;config_file&quot;       =&gt; &quot;my_conf_file.conf&quot;,
+          &quot;config_file&quot;       =&gt; &quot;tmp/config/development.sphinx.conf&quot;,
           &quot;searchd_log_file&quot;  =&gt; &quot;searchd_log_file.log&quot;,
           &quot;query_log_file&quot;    =&gt; &quot;query_log_file.log&quot;,
           &quot;pid_file&quot;          =&gt; &quot;pid_file.pid&quot;,
@@ -222,7 +225,7 @@ describe ThinkingSphinx::Configuration do
           &quot;ignore_chars&quot;      =&gt; &quot;e&quot;
         }
       }
-      # puts YAML.dump(settings)
+      
       open(&quot;#{RAILS_ROOT}/config/sphinx.yml&quot;, &quot;w&quot;) do |f|
         f.write  YAML.dump(@settings)
       end
@@ -234,14 +237,16 @@ describe ThinkingSphinx::Configuration do
         config.send(key).should == value
       end
     end
+    
+    after :each do
+      FileUtils.rm &quot;#{RAILS_ROOT}/config/sphinx.yml&quot;
+    end
   end
   
   describe &quot;core_index_for_model method&quot; do
     before :each do
       @config = ThinkingSphinx::Configuration.new
-      @model  = Class.stub_instance(
-        :indexes  =&gt; [ThinkingSphinx::Index.new(Person)]
-      )
+      @model  = Person
     end
     
     it &quot;should take its name from the model, with _core appended&quot; do
@@ -312,12 +317,13 @@ describe ThinkingSphinx::Configuration do
     end
     
     it &quot;should include the star-related settings when allow_star is true&quot; do
-      @config.allow_star = true
+      @config.allow_star      = true
+      @config.min_prefix_len  = 1
       text =  @config.send(:core_index_for_model, @model, &quot;my sources&quot;)
       
       text.should match(/enable_star\s+= 1/)
       text.should match(/min_prefix_len\s+= 1/)
-      text.should match(/min_infix_len\s+= 1/)
+      # text.should match(/min_infix_len\s+= 1/)
     end
     
     it &quot;should use the configuration's infix and prefix length values if set&quot; do
@@ -327,7 +333,7 @@ describe ThinkingSphinx::Configuration do
       text =  @config.send(:core_index_for_model, @model, &quot;my sources&quot;)
       
       text.should match(/min_prefix_len\s+= 3/)
-      text.should match(/min_infix_len\s+= 2/)
+      # text.should match(/min_infix_len\s+= 2/)
     end
     
     it &quot;should not include the star-related settings when allow_star is false&quot; do
@@ -341,8 +347,16 @@ describe ThinkingSphinx::Configuration do
     
     it &quot;should set prefix_fields if any fields are flagged explicitly&quot; do
       @model.indexes.first.stub_methods(
-        :prefix_fields =&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;],
-        :infix_fields  =&gt; [&quot;d&quot;, &quot;e&quot;, &quot;f&quot;]
+        :prefix_fields =&gt; [
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;a&quot;),
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;b&quot;),
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;c&quot;)
+        ],
+        :infix_fields  =&gt; [
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;d&quot;),
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;e&quot;),
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;f&quot;)
+        ]
       )
       
       @config.send(:core_index_for_model, @model, &quot;my sources&quot;).should match(
@@ -358,8 +372,16 @@ describe ThinkingSphinx::Configuration do
     
     it &quot;should set infix_fields if any fields are flagged explicitly&quot; do
       @model.indexes.first.stub_methods(
-        :prefix_fields =&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;],
-        :infix_fields  =&gt; [&quot;d&quot;, &quot;e&quot;, &quot;f&quot;]
+        :prefix_fields =&gt; [
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;a&quot;),
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;b&quot;),
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;c&quot;)
+        ],
+        :infix_fields  =&gt; [
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;d&quot;),
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;e&quot;),
+          ThinkingSphinx::Field.stub_instance(:unique_name =&gt; &quot;f&quot;)
+        ]
       )
       
       @config.send(:core_index_for_model, @model, &quot;my sources&quot;).should match(
@@ -399,9 +421,7 @@ describe ThinkingSphinx::Configuration do
   describe &quot;delta_index_for_model method&quot; do
     before :each do
       @config = ThinkingSphinx::Configuration.new
-      @model  = Class.stub_instance(
-        :indexes =&gt; [ThinkingSphinx::Index.new(Person)]
-      )
+      @model  = Person
     end
     
     it &quot;should take its name from the model, with _delta appended&quot; do
@@ -427,9 +447,7 @@ describe ThinkingSphinx::Configuration do
   describe &quot;distributed_index_for_model method&quot; do
     before :each do
       @config = ThinkingSphinx::Configuration.new
-      @model  = Class.stub_instance(
-        :indexes  =&gt; [ThinkingSphinx::Index.new(Person)]
-      )
+      @model  = Person
     end
     
     it &quot;should take its name from the model&quot; do</diff>
      <filename>spec/unit/thinking_sphinx/configuration_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -166,6 +166,11 @@ describe ThinkingSphinx::Field do
       )
     end
     
+    it &quot;should return the column name if the column is a string&quot; do
+      @field.columns = [ThinkingSphinx::Index::FauxColumn.new(&quot;string&quot;)]
+      @field.send(:column_with_prefix, @field.columns.first).should == &quot;string&quot;
+    end
+    
     it &quot;should return the column with model's table prefix if there's no associations for the column&quot; do
       @field.send(:column_with_prefix, @field.columns.first).should == &quot;`people`.`col_name`&quot;
     end</diff>
      <filename>spec/unit/thinking_sphinx/field_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,33 @@ describe ThinkingSphinx::Index::FauxColumn do
     #
   end
   
+  describe &quot;coerce class method&quot; do
+    before :each do
+      @column = ThinkingSphinx::Index::FauxColumn.stub_instance
+      ThinkingSphinx::Index::FauxColumn.stub_method(:new =&gt; @column)
+    end
+    
+    it &quot;should return a single faux column if passed a string&quot; do
+      ThinkingSphinx::Index::FauxColumn.coerce(&quot;string&quot;).should == @column
+    end
+    
+    it &quot;should return a single faux column if passed a symbol&quot; do
+      ThinkingSphinx::Index::FauxColumn.coerce(:string).should == @column
+    end
+    
+    it &quot;should return an array of faux columns if passed an array of strings&quot; do
+      ThinkingSphinx::Index::FauxColumn.coerce([&quot;one&quot;, &quot;two&quot;]).should == [
+        @column, @column
+      ]
+    end
+    
+    it &quot;should return an array of faux columns if passed an array of symbols&quot; do
+      ThinkingSphinx::Index::FauxColumn.coerce([:one, :two]).should == [
+        @column, @column
+      ]
+    end
+  end
+  
   describe &quot;method_missing calls with no arguments&quot; do
     it &quot;should push any further method calls into name, and the old name goes into the stack&quot; do
       #</diff>
      <filename>spec/unit/thinking_sphinx/index/faux_column_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -28,7 +28,7 @@ describe ThinkingSphinx::Index do
     end
     
     it &quot;should call link!&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;)
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0)
       
       @index.should have_received(:link!)
     end
@@ -36,17 +36,17 @@ describe ThinkingSphinx::Index do
     it &quot;should raise an exception if the adapter isn't mysql or postgres&quot; do
       @index.stub_method(:adapter =&gt; :sqlite)
       
-      lambda { @index.to_config(0, @database, &quot;utf-8&quot;) }.should raise_error
+      lambda { @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0) }.should raise_error
     end
     
     it &quot;should set the core source name to {model}_{index}_core&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /source person_0_core/
       )
     end
     
     it &quot;should include the database config supplied&quot; do
-      conf = @index.to_config(0, @database, &quot;utf-8&quot;)
+      conf = @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0)
       conf.should match(/type\s+= mysql/)
       conf.should match(/sql_host\s+= localhost/)
       conf.should match(/sql_user\s+= username/)
@@ -54,71 +54,89 @@ describe ThinkingSphinx::Index do
       conf.should match(/sql_db\s+= db/)
     end
     
+    it &quot;should use 'user' if 'username' doesn't exist in database configuration&quot; do
+      conf = @index.to_config(Person, 0,
+        @database.except(:username).merge(:user =&gt; &quot;username&quot;),
+        &quot;utf-8&quot;, 0
+      )
+      conf.should match(/sql_user\s+= username/)
+    end
+    
+    it &quot;should include the database socket if set&quot; do
+      conf = @index.to_config(Person, 0, @database.merge(:socket =&gt; &quot;dbsocket&quot;), &quot;utf-8&quot;, 0)
+      conf.should match(/sql_sock\s+= dbsocket/)
+    end
+    
+    it &quot;should not include the database socket if not set&quot; do
+      conf = @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0)
+      conf.should_not match(/sql_sock/)
+    end
+    
     it &quot;should have a pre query 'SET NAMES utf8' if using mysql and utf8 charset&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /sql_query_pre\s+= SET NAMES utf8/
       )
       
       @index.stub_method(:delta? =&gt; true)
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /source person_0_delta.+sql_query_pre\s+= SET NAMES utf8/m
       )
       
       @index.stub_method(:delta? =&gt; false)
-      @index.to_config(0, @database, &quot;non-utf-8&quot;).should_not match(
+      @index.to_config(Person, 0, @database, &quot;non-utf-8&quot;, 0).should_not match(
         /SET NAMES utf8/
       )
       
       @index.stub_method(:adapter =&gt; :postgres)
-      @index.to_config(0, @database, &quot;utf-8&quot;).should_not match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should_not match(
         /SET NAMES utf8/
       )
     end
     
     it &quot;should use the pre query from the index&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /sql_query_pre\s+= sql_query_pre/
       )
     end
     
     it &quot;should not set group_concat_max_len if not specified&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should_not match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should_not match(
         /group_concat_max_len/
       )
     end
 
     it &quot;should set group_concat_max_len if specified&quot; do
       @index.options.merge! :group_concat_max_len =&gt; 2056
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /sql_query_pre\s+= SET SESSION group_concat_max_len = 2056/
       )
       
       @index.stub_method(:delta? =&gt; true)
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /source person_0_delta.+sql_query_pre\s+= SET SESSION group_concat_max_len = 2056/m
       )
     end
     
     it &quot;should use the main query from the index&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /sql_query\s+= SQL/
       )
     end
     
     it &quot;should use the range query from the index&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /sql_query_range\s+= sql_query_range/
       )
     end
-    
+
     it &quot;should use the info query from the index&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /sql_query_info\s+= sql_query_info/
       )
     end
     
     it &quot;should include the attribute sources&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /attr a\n\s+attr b/
       )
     end
@@ -126,13 +144,13 @@ describe ThinkingSphinx::Index do
     it &quot;should add a delta index with name {model}_{index}_delta if requested&quot; do
       @index.stub_method(:delta? =&gt; true)
       
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /source person_0_delta/
       )
     end
     
     it &quot;should not add a delta index unless requested&quot; do
-      @index.to_config(0, @database, &quot;utf-8&quot;).should_not match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should_not match(
         /source person_0_delta/
       )
     end
@@ -140,7 +158,7 @@ describe ThinkingSphinx::Index do
     it &quot;should have the delta index inherit from the core index&quot; do
       @index.stub_method(:delta? =&gt; true)
       
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /source person_0_delta : person_0_core/
       )
     end
@@ -148,7 +166,7 @@ describe ThinkingSphinx::Index do
     it &quot;should redefine the main query for the delta index&quot; do
       @index.stub_method(:delta? =&gt; true)
       
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /source person_0_delta.+sql_query\s+= SQL/m
       )
     end
@@ -156,7 +174,7 @@ describe ThinkingSphinx::Index do
     it &quot;should redefine the range query for the delta index&quot; do
       @index.stub_method(:delta? =&gt; true)
       
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /source person_0_delta.+sql_query_range\s+= sql_query_range/m
       )
     end
@@ -164,7 +182,7 @@ describe ThinkingSphinx::Index do
     it &quot;should redefine the pre query for the delta index&quot; do
       @index.stub_method(:delta? =&gt; true)
       
-      @index.to_config(0, @database, &quot;utf-8&quot;).should match(
+      @index.to_config(Person, 0, @database, &quot;utf-8&quot;, 0).should match(
         /source person_0_delta.+sql_query_pre\s+=\s*\n/m
       )
     end
@@ -238,7 +256,7 @@ describe ThinkingSphinx::Index do
     end
     
     after :each do
-      `rm #{@file_path}` if File.exists?(@file_path)
+      FileUtils.rm(@file_path, :force =&gt; true)
     end
     
     it &quot;should return true if the core index files are empty&quot; do</diff>
      <filename>spec/unit/thinking_sphinx/index_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,11 @@
 require 'spec/spec_helper'
+require 'will_paginate/collection'
 
 describe ThinkingSphinx::Search do
+  describe &quot;search method&quot; do
+    it &quot;should actually have some tests&quot;
+  end
+  
   describe &quot;search_for_id method&quot; do
     before :each do
       @client = Riddle::Client.stub_instance(
@@ -57,21 +62,29 @@ describe ThinkingSphinx::Search do
     it &quot;should honour the :include option&quot; do
       ThinkingSphinx::Search.send(
         :instance_from_result,
-        {:doc =&gt; 1, :attributes =&gt; {&quot;class_crc&quot; =&gt; 123}},
+        {
+          :doc =&gt; 1, :attributes =&gt; {
+            &quot;sphinx_internal_id&quot; =&gt; 2, &quot;class_crc&quot; =&gt; 123
+          }
+        },
         {:include =&gt; :assoc}
       )
 
-      Person.should have_received(:find).with(1, :include =&gt; :assoc, :select =&gt; nil)
+      Person.should have_received(:find).with(2, :include =&gt; :assoc, :select =&gt; nil)
     end
 
     it &quot;should honour the :select option&quot; do
       ThinkingSphinx::Search.send(
         :instance_from_result,
-        {:doc =&gt; 1, :attributes =&gt; {&quot;class_crc&quot; =&gt; 123}},
+        {
+          :doc =&gt; 1, :attributes =&gt; {
+            &quot;sphinx_internal_id&quot; =&gt; 2, &quot;class_crc&quot; =&gt; 123
+          }
+        },
         {:select =&gt; :columns}
       )
 
-      Person.should have_received(:find).with(1, :include =&gt; nil, :select =&gt; :columns)
+      Person.should have_received(:find).with(2, :include =&gt; nil, :select =&gt; :columns)
     end
 
   end
@@ -82,10 +95,14 @@ describe ThinkingSphinx::Search do
       @person_b = Person.stub_instance
       @person_c = Person.stub_instance
 
+      @person_a.stub_method(:attributes =&gt; [])
+      @person_b.stub_method(:attributes =&gt; [])
+      @person_c.stub_method(:attributes =&gt; [])
+      
       @results = [
-        {:doc =&gt; @person_a.id},
-        {:doc =&gt; @person_b.id},
-        {:doc =&gt; @person_c.id}
+        {:attributes =&gt; {&quot;sphinx_internal_id&quot; =&gt; @person_a.id}},
+        {:attributes =&gt; {&quot;sphinx_internal_id&quot; =&gt; @person_b.id}},
+        {:attributes =&gt; {&quot;sphinx_internal_id&quot; =&gt; @person_c.id}}
       ]
       
       Person.stub_method(
@@ -105,13 +122,13 @@ describe ThinkingSphinx::Search do
       )
 
       ThinkingSphinx::Search.should have_received(:instance_from_result).with(
-        {:doc =&gt; @person_a.id}, {}
+        {:attributes =&gt; {&quot;sphinx_internal_id&quot; =&gt; @person_a.id}}, {}
       )
       ThinkingSphinx::Search.should have_received(:instance_from_result).with(
-        {:doc =&gt; @person_b.id}, {}
+        {:attributes =&gt; {&quot;sphinx_internal_id&quot; =&gt; @person_b.id}}, {}
       )
       ThinkingSphinx::Search.should have_received(:instance_from_result).with(
-        {:doc =&gt; @person_c.id}, {}
+        {:attributes =&gt; {&quot;sphinx_internal_id&quot; =&gt; @person_c.id}}, {}
       )
     end
 
@@ -159,5 +176,83 @@ describe ThinkingSphinx::Search do
         :instances_from_results, @results, {:select =&gt; :fields}, Person
       ).should == [@person_a, @person_b, @person_c]
     end
+    
+    it &quot;should run the append distances function when distance_name is passed&quot; do
+      ThinkingSphinx::Search.stub_method(:append_distances =&gt; @results)
+      
+      ThinkingSphinx::Search.send(
+        :instances_from_results, @results, {:distance_name =&gt; 'distance'}, Person
+      )
+      
+      Person.should have_received(:find).with(
+        :all,
+        :conditions =&gt; {:id =&gt; [@person_a.id, @person_b.id, @person_c.id]},
+        :include    =&gt; nil,
+        :select     =&gt; nil
+      )
+    end
+    
+    it &quot;should have a test for the append_distances function&quot;
+  end
+  
+  describe &quot;count method&quot; do
+    before :each do
+      @client = Riddle::Client.stub_instance(
+        :filters    =&gt; [],
+        :filters=   =&gt; true,
+        :id_range=  =&gt; true,
+        :sort_mode  =&gt; :asc,
+        :limit      =&gt; 5,
+        :offset=    =&gt; 0,
+        :sort_mode= =&gt; true,
+        :query      =&gt; {
+          :matches  =&gt; [],
+          :total    =&gt; 50
+        }
+      )
+
+      ThinkingSphinx::Search.stub_methods(
+        :client_from_options =&gt; @client,
+        :search_conditions   =&gt; [&quot;&quot;, []]
+      )
+    end
+
+    it &quot;should return query total&quot; do
+      ThinkingSphinx::Search.count(42, &quot;an_index&quot;).should == 50
+    end
+  end
+  
+  describe &quot;search result&quot; do
+    before :each do
+      @results = ThinkingSphinx::Search.search &quot;nothing will match this&quot;
+    end
+    
+    it &quot;should respond to previous_page&quot; do
+      @results.should respond_to(:previous_page)
+    end
+    
+    it &quot;should respond to next_page&quot; do
+      @results.should respond_to(:next_page)
+    end
+    
+    it &quot;should respond to current_page&quot; do
+      @results.should respond_to(:current_page)
+    end
+    
+    it &quot;should respond to total_pages&quot; do
+      @results.should respond_to(:total_pages)
+    end
+    
+    it &quot;should respond to total_entries&quot; do
+      @results.should respond_to(:total_entries)
+    end
+    
+    it &quot;should respond to offset&quot; do
+      @results.should respond_to(:offset)
+    end
+        
+    it &quot;should be a subclass of Array&quot; do
+      @results.should be_kind_of(Array)
+    end
   end
 end</diff>
      <filename>spec/unit/thinking_sphinx/search_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -99,6 +99,10 @@ describe ThinkingSphinx do
     
     describe &quot;if not using MySQL&quot; do
       before :each do
+        unless ::ActiveRecord::ConnectionAdapters.const_defined?(:PostgreSQLAdapter)
+          pending &quot;No PostgreSQL&quot;
+          return
+        end
         @connection = ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.stub_instance(
           :select_all =&gt; true
         )</diff>
      <filename>spec/unit/thinking_sphinx_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,7 @@ require 'fileutils'
 namespace :thinking_sphinx do
   task :app_env do
     Rake::Task[:environment].invoke if defined?(RAILS_ROOT)
-    Rake::Task[:merb_env].invoke    if defined?(Merb)
+    Rake::Task[:merb_init].invoke    if defined?(Merb)
   end
   
   desc &quot;Start a Sphinx searchd daemon using Thinking Sphinx's settings&quot;</diff>
      <filename>tasks/thinking_sphinx_tasks.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,15 +1,21 @@
 Gem::Specification.new do |s|
-  s.name              = &quot;thinking-sphinx&quot;
-  s.version           = &quot;0.9.8&quot;
-  s.summary           = &quot;A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.&quot;
-  s.description       = &quot;A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.&quot;
-  s.author            = &quot;Pat Allan&quot;
-  s.email             = &quot;pat@freelancing-gods.com&quot;
-  s.homepage          = &quot;http://ts.freelancing-gods.com&quot;
-  s.has_rdoc          = true
-  s.rdoc_options     &lt;&lt; &quot;--title&quot; &lt;&lt; &quot;Thinking Sphinx -- Rails/Merb Sphinx Plugin&quot; &lt;&lt;
-                        &quot;--line-numbers&quot;
-  s.rubyforge_project = &quot;thinking-sphinx&quot;
-  s.test_files        = [&quot;spec/unit/thinking_sphinx/active_record/delta_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record/search_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/association_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/attribute_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/configuration_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/field_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index/builder_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index/faux_column_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/search_spec.rb&quot;, &quot;spec/unit/thinking_sphinx_spec.rb&quot;]
-  s.files             = [&quot;lib/riddle/client/filter.rb&quot;, &quot;lib/riddle/client/message.rb&quot;, &quot;lib/riddle/client/response.rb&quot;, &quot;lib/riddle/client.rb&quot;, &quot;lib/riddle.rb&quot;, &quot;lib/test.rb&quot;, &quot;lib/thinking_sphinx/active_record/delta.rb&quot;, &quot;lib/thinking_sphinx/active_record/has_many_association.rb&quot;, &quot;lib/thinking_sphinx/active_record/search.rb&quot;, &quot;lib/thinking_sphinx/active_record.rb&quot;, &quot;lib/thinking_sphinx/association.rb&quot;, &quot;lib/thinking_sphinx/attribute.rb&quot;, &quot;lib/thinking_sphinx/configuration.rb&quot;, &quot;lib/thinking_sphinx/field.rb&quot;, &quot;lib/thinking_sphinx/index/builder.rb&quot;, &quot;lib/thinking_sphinx/index/faux_column.rb&quot;, &quot;lib/thinking_sphinx/index.rb&quot;, &quot;lib/thinking_sphinx/rails_additions.rb&quot;, &quot;lib/thinking_sphinx/search.rb&quot;, &quot;lib/thinking_sphinx.rb&quot;, &quot;LICENCE&quot;, &quot;README&quot;, &quot;tasks/thinking_sphinx_tasks.rb&quot;, &quot;tasks/thinking_sphinx_tasks.rake&quot;]
-end
\ No newline at end of file
+  s.name = %q{thinking-sphinx}
+  s.version = &quot;0.9.9&quot;
+
+  s.specification_version = 2 if s.respond_to? :specification_version=
+
+  s.required_rubygems_version = Gem::Requirement.new(&quot;&gt;= 0&quot;) if s.respond_to? :required_rubygems_version=
+  s.authors = [&quot;Pat Allan&quot;]
+  s.date = %q{2008-08-22}
+  s.description = %q{A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.}
+  s.email = %q{pat@freelancing-gods.com}
+  s.files = [&quot;lib/riddle/client/filter.rb&quot;, &quot;lib/riddle/client/message.rb&quot;, &quot;lib/riddle/client/response.rb&quot;, &quot;lib/riddle/client.rb&quot;, &quot;lib/riddle.rb&quot;, &quot;lib/test.rb&quot;, &quot;lib/thinking_sphinx/active_record/delta.rb&quot;, &quot;lib/thinking_sphinx/active_record/has_many_association.rb&quot;, &quot;lib/thinking_sphinx/active_record/search.rb&quot;, &quot;lib/thinking_sphinx/active_record.rb&quot;, &quot;lib/thinking_sphinx/association.rb&quot;, &quot;lib/thinking_sphinx/attribute.rb&quot;, &quot;lib/thinking_sphinx/collection.rb&quot;, &quot;lib/thinking_sphinx/configuration.rb&quot;, &quot;lib/thinking_sphinx/field.rb&quot;, &quot;lib/thinking_sphinx/index/builder.rb&quot;, &quot;lib/thinking_sphinx/index/faux_column.rb&quot;, &quot;lib/thinking_sphinx/index.rb&quot;, &quot;lib/thinking_sphinx/rails_additions.rb&quot;, &quot;lib/thinking_sphinx/search.rb&quot;, &quot;lib/thinking_sphinx.rb&quot;, &quot;LICENCE&quot;, &quot;README&quot;, &quot;tasks/thinking_sphinx_tasks.rb&quot;, &quot;tasks/thinking_sphinx_tasks.rake&quot;, &quot;spec/unit/thinking_sphinx/active_record/delta_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record/search_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/association_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/attribute_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/configuration_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/field_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index/builder_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index/faux_column_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/search_spec.rb&quot;, &quot;spec/unit/thinking_sphinx_spec.rb&quot;]
+  s.has_rdoc = true
+  s.homepage = %q{http://ts.freelancing-gods.com}
+  s.rdoc_options = [&quot;--title&quot;, &quot;Thinking Sphinx -- Rails/Merb Sphinx Plugin&quot;, &quot;--line-numbers&quot;]
+  s.require_paths = [&quot;lib&quot;]
+  s.rubyforge_project = %q{thinking-sphinx}
+  s.rubygems_version = %q{1.1.1}
+  s.summary = %q{A concise and easy-to-use Ruby library that connects ActiveRecord to the Sphinx search daemon, managing configuration, indexing and searching.}
+  s.test_files = [&quot;spec/unit/thinking_sphinx/active_record/delta_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record/search_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/active_record_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/association_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/attribute_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/configuration_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/field_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index/builder_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index/faux_column_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/index_spec.rb&quot;, &quot;spec/unit/thinking_sphinx/search_spec.rb&quot;, &quot;spec/unit/thinking_sphinx_spec.rb&quot;]
+end</diff>
      <filename>thinking-sphinx.gemspec</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>4287a978cecace1ceb10e4bb1b2a9e4270a512aa</id>
    </parent>
  </parents>
  <author>
    <name>Ed Hickey</name>
    <email>ed@ed-new-laptop.local</email>
  </author>
  <url>http://github.com/bassnode/thinking-sphinx/commit/ce42541709dd65b0c031802091d950a776cc3084</url>
  <id>ce42541709dd65b0c031802091d950a776cc3084</id>
  <committed-date>2008-08-28T13:42:24-07:00</committed-date>
  <authored-date>2008-08-28T13:42:24-07:00</authored-date>
  <message>merged in DrMark's branch</message>
  <tree>1ec795ef79e088d7ed1bfaaea4b6e82b3edd24b2</tree>
  <committer>
    <name>Ed Hickey</name>
    <email>ed@ed-new-laptop.local</email>
  </committer>
</commit>
