pacecar 1.4.3 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/pacecar.rb +34 -0
- data/lib/pacecar/associations.rb +39 -0
- data/lib/pacecar/boolean.rb +34 -0
- data/lib/pacecar/datetime.rb +91 -0
- data/lib/pacecar/duration.rb +51 -0
- data/lib/pacecar/helpers.rb +79 -0
- data/lib/pacecar/limit.rb +22 -0
- data/lib/pacecar/numeric.rb +29 -0
- data/lib/pacecar/order.rb +24 -0
- data/lib/pacecar/polymorph.rb +18 -0
- data/lib/pacecar/presence.rb +23 -0
- data/lib/pacecar/ranking.rb +26 -0
- data/lib/pacecar/search.rb +47 -0
- data/lib/pacecar/state.rb +36 -0
- metadata +18 -4
    
        data/lib/pacecar.rb
    ADDED
    
    | @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            require 'pacecar/associations'
         | 
| 2 | 
            +
            require 'pacecar/boolean'
         | 
| 3 | 
            +
            require 'pacecar/datetime'
         | 
| 4 | 
            +
            require 'pacecar/duration'
         | 
| 5 | 
            +
            require 'pacecar/helpers'
         | 
| 6 | 
            +
            require 'pacecar/limit'
         | 
| 7 | 
            +
            require 'pacecar/order'
         | 
| 8 | 
            +
            require 'pacecar/polymorph'
         | 
| 9 | 
            +
            require 'pacecar/presence'
         | 
| 10 | 
            +
            require 'pacecar/ranking'
         | 
| 11 | 
            +
            require 'pacecar/search'
         | 
| 12 | 
            +
            require 'pacecar/state'
         | 
| 13 | 
            +
            require 'pacecar/numeric'
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            module Pacecar
         | 
| 16 | 
            +
              def self.included(base)
         | 
| 17 | 
            +
                base.class_eval do
         | 
| 18 | 
            +
                  include Pacecar::Associations
         | 
| 19 | 
            +
                  include Pacecar::Boolean
         | 
| 20 | 
            +
                  include Pacecar::Datetime
         | 
| 21 | 
            +
                  include Pacecar::Duration
         | 
| 22 | 
            +
                  include Pacecar::Limit
         | 
| 23 | 
            +
                  include Pacecar::Order
         | 
| 24 | 
            +
                  include Pacecar::Polymorph
         | 
| 25 | 
            +
                  include Pacecar::Presence
         | 
| 26 | 
            +
                  include Pacecar::Ranking
         | 
| 27 | 
            +
                  include Pacecar::Search
         | 
| 28 | 
            +
                  include Pacecar::State
         | 
| 29 | 
            +
                  include Pacecar::Numeric
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            ActiveRecord::Base.send :include, Pacecar::Helpers
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Associations
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def has_recent_records(*names)
         | 
| 10 | 
            +
                    names.each do |name|
         | 
| 11 | 
            +
                      scope "recent_#{name}_since".to_sym, lambda { |since|
         | 
| 12 | 
            +
                        {
         | 
| 13 | 
            +
                          :conditions => [conditions_for_name(name), { :since_time => since }]
         | 
| 14 | 
            +
                        }
         | 
| 15 | 
            +
                      }
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                    unless names.first == names.last
         | 
| 18 | 
            +
                      scope "recent_#{names.join('_or_')}_since".to_sym, lambda { |since|
         | 
| 19 | 
            +
                        {
         | 
| 20 | 
            +
                          :conditions => [names.collect { |name| conditions_for_name(name) }.join(' or '), { :since_time => since }]
         | 
| 21 | 
            +
                        }
         | 
| 22 | 
            +
                      }
         | 
| 23 | 
            +
                      scope "recent_#{names.join('_and_')}_since".to_sym, lambda { |since|
         | 
| 24 | 
            +
                        {
         | 
| 25 | 
            +
                          :conditions => [names.collect { |name| conditions_for_name(name) }.join(' and '), { :since_time => since }]
         | 
| 26 | 
            +
                        }
         | 
| 27 | 
            +
                      }
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  protected
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def conditions_for_name(name)
         | 
| 34 | 
            +
                    "((select count(*) from #{connection.quote_table_name(name)} where #{connection.quote_table_name(name)}.#{connection.quote_column_name reflections[name].primary_key_name} = #{quoted_table_name}.#{connection.quote_column_name primary_key} and #{connection.quote_table_name(name)}.#{connection.quote_column_name("created_at")} > :since_time) > 0)"
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Boolean
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
                  def self.extended(base)
         | 
| 9 | 
            +
                    base.send :define_boolean_scopes
         | 
| 10 | 
            +
                    base.send :define_balance_count
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  protected
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  def define_boolean_scopes
         | 
| 16 | 
            +
                    boolean_column_names.each do |name|
         | 
| 17 | 
            +
                      scope name.to_sym, :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} = ?", true]
         | 
| 18 | 
            +
                      scope "not_#{name}".to_sym, :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} = ?", false]
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def define_balance_count
         | 
| 23 | 
            +
                    boolean_column_names.each do |name|
         | 
| 24 | 
            +
                      self.class_eval %Q{
         | 
| 25 | 
            +
                        def self.#{name}_balance
         | 
| 26 | 
            +
                          #{name}.count - not_#{name}.count
         | 
| 27 | 
            +
                        end
         | 
| 28 | 
            +
                      }
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,91 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Datetime
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
                  def self.extended(base)
         | 
| 9 | 
            +
                    base.send :define_datetime_scopes
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  protected
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def define_datetime_scopes
         | 
| 15 | 
            +
                    datetime_column_names.each do |name|
         | 
| 16 | 
            +
                      define_before_after_scopes(name)
         | 
| 17 | 
            +
                      define_past_future_scopes(name)
         | 
| 18 | 
            +
                      define_inside_outside_scopes(name)
         | 
| 19 | 
            +
                      define_in_date_scopes(name)
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  def define_before_after_scopes(name)
         | 
| 24 | 
            +
                    scope "#{name}_before".to_sym, lambda { |time|
         | 
| 25 | 
            +
                      { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} <= ?", time] }
         | 
| 26 | 
            +
                    }
         | 
| 27 | 
            +
                    scope "#{name}_after".to_sym, lambda { |time|
         | 
| 28 | 
            +
                      { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} >= ?", time] }
         | 
| 29 | 
            +
                    }
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def define_past_future_scopes(name)
         | 
| 33 | 
            +
                    scope "#{name}_in_past", lambda {
         | 
| 34 | 
            +
                      { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} <= ?", now] }
         | 
| 35 | 
            +
                    }
         | 
| 36 | 
            +
                    scope "#{name}_in_future", lambda {
         | 
| 37 | 
            +
                      { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} >= ?", now] }
         | 
| 38 | 
            +
                    }
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  def define_inside_outside_scopes(name)
         | 
| 42 | 
            +
                    scope "#{name}_inside".to_sym, lambda { |start, stop|
         | 
| 43 | 
            +
                      { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} >= ? and #{quoted_table_name}.#{connection.quote_column_name name} <= ?", start, stop] }
         | 
| 44 | 
            +
                    }
         | 
| 45 | 
            +
                    scope "#{name}_outside".to_sym, lambda { |start, stop|
         | 
| 46 | 
            +
                      { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} <= ? or #{quoted_table_name}.#{connection.quote_column_name name} >= ?", start, stop] }
         | 
| 47 | 
            +
                    }
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def define_in_date_scopes(name)
         | 
| 51 | 
            +
                    case connection.adapter_name
         | 
| 52 | 
            +
                    when 'MySQL', 'Mysql2'
         | 
| 53 | 
            +
                      scope "#{name}_in_year".to_sym, lambda { |year|
         | 
| 54 | 
            +
                        { :conditions => ["year(#{quoted_table_name}.#{connection.quote_column_name name}) = ?", year.to_i] }
         | 
| 55 | 
            +
                      }
         | 
| 56 | 
            +
                      scope "#{name}_in_month".to_sym, lambda { |month|
         | 
| 57 | 
            +
                        { :conditions => ["month(#{quoted_table_name}.#{connection.quote_column_name name}) = ?", month.to_i] }
         | 
| 58 | 
            +
                      }
         | 
| 59 | 
            +
                      scope "#{name}_in_day".to_sym, lambda { |day|
         | 
| 60 | 
            +
                        { :conditions => ["day(#{quoted_table_name}.#{connection.quote_column_name name}) = ?", day.to_i] }
         | 
| 61 | 
            +
                      }
         | 
| 62 | 
            +
                    when 'PostgreSQL'
         | 
| 63 | 
            +
                      scope "#{name}_in_year".to_sym, lambda { |year|
         | 
| 64 | 
            +
                        { :conditions => ["extract(year from #{quoted_table_name}.#{connection.quote_column_name name}) = ?", year.to_i] }
         | 
| 65 | 
            +
                      }
         | 
| 66 | 
            +
                      scope "#{name}_in_month".to_sym, lambda { |month|
         | 
| 67 | 
            +
                        { :conditions => ["extract(month from #{quoted_table_name}.#{connection.quote_column_name name}) = ?", month.to_i] }
         | 
| 68 | 
            +
                      }
         | 
| 69 | 
            +
                      scope "#{name}_in_day".to_sym, lambda { |day|
         | 
| 70 | 
            +
                        { :conditions => ["extract(day from #{quoted_table_name}.#{connection.quote_column_name name}) = ?", day.to_i] }
         | 
| 71 | 
            +
                      }
         | 
| 72 | 
            +
                    when 'SQLite'
         | 
| 73 | 
            +
                      scope "#{name}_in_year".to_sym, lambda { |year|
         | 
| 74 | 
            +
                        { :conditions => ["strftime('%Y', #{quoted_table_name}.#{connection.quote_column_name name}) = ?", sprintf('%04d', year)] }
         | 
| 75 | 
            +
                      }
         | 
| 76 | 
            +
                      scope "#{name}_in_month".to_sym, lambda { |month|
         | 
| 77 | 
            +
                        { :conditions => ["strftime('%m', #{quoted_table_name}.#{connection.quote_column_name name}) = ?", sprintf('%02d', month)] }
         | 
| 78 | 
            +
                      }
         | 
| 79 | 
            +
                      scope "#{name}_in_day".to_sym, lambda { |day|
         | 
| 80 | 
            +
                        { :conditions => ["strftime('%d', #{quoted_table_name}.#{connection.quote_column_name name}) = ?", sprintf('%02d', day)] }
         | 
| 81 | 
            +
                      }
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  def now
         | 
| 86 | 
            +
                    defined?(Time.zone_default) && Time.zone_default ? Time.zone_default.now : Time.now
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
            end
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Duration
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
                  def self.extended(base)
         | 
| 9 | 
            +
                    base.send :define_duration_scopes
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  protected
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def define_duration_scopes
         | 
| 15 | 
            +
                    case connection.adapter_name
         | 
| 16 | 
            +
                    when 'MySQL', 'Mysql2'
         | 
| 17 | 
            +
                      scope :with_duration_of, lambda { |duration, start, stop|
         | 
| 18 | 
            +
                        { :conditions => ["abs(datediff(#{quoted_table_name}.#{connection.quote_column_name start}, #{quoted_table_name}.#{connection.quote_column_name stop})) = ?", duration] }
         | 
| 19 | 
            +
                      }
         | 
| 20 | 
            +
                      scope :with_duration_over, lambda { |duration, start, stop|
         | 
| 21 | 
            +
                        { :conditions => ["abs(datediff(#{quoted_table_name}.#{connection.quote_column_name start}, #{quoted_table_name}.#{connection.quote_column_name stop})) > ?", duration] }
         | 
| 22 | 
            +
                      }
         | 
| 23 | 
            +
                      scope :with_duration_under, lambda { |duration, start, stop|
         | 
| 24 | 
            +
                        { :conditions => ["abs(datediff(#{quoted_table_name}.#{connection.quote_column_name start}, #{quoted_table_name}.#{connection.quote_column_name stop})) < ?", duration] }
         | 
| 25 | 
            +
                      }
         | 
| 26 | 
            +
                    when 'PostgreSQL'
         | 
| 27 | 
            +
                      scope :with_duration_of, lambda { |duration, start, stop|
         | 
| 28 | 
            +
                        { :conditions => ["age(#{quoted_table_name}.#{connection.quote_column_name stop}, #{quoted_table_name}.#{connection.quote_column_name start}) = '? days'", duration] }
         | 
| 29 | 
            +
                      }
         | 
| 30 | 
            +
                      scope :with_duration_over, lambda { |duration, start, stop|
         | 
| 31 | 
            +
                        { :conditions => ["age(#{quoted_table_name}.#{connection.quote_column_name stop}, #{quoted_table_name}.#{connection.quote_column_name start}) > interval '? days'", duration] }
         | 
| 32 | 
            +
                      }
         | 
| 33 | 
            +
                      scope :with_duration_under, lambda { |duration, start, stop|
         | 
| 34 | 
            +
                        { :conditions => ["age(#{quoted_table_name}.#{connection.quote_column_name stop}, #{quoted_table_name}.#{connection.quote_column_name start}) < interval '? days'", duration] }
         | 
| 35 | 
            +
                      }
         | 
| 36 | 
            +
                    when 'SQLite'
         | 
| 37 | 
            +
                      scope :with_duration_of, lambda { |duration, start, stop|
         | 
| 38 | 
            +
                        { :conditions => ["abs(julianday(#{quoted_table_name}.#{connection.quote_column_name start}) - julianday(#{quoted_table_name}.#{connection.quote_column_name stop})) = ?", duration] }
         | 
| 39 | 
            +
                      }
         | 
| 40 | 
            +
                      scope :with_duration_over, lambda { |duration, start, stop|
         | 
| 41 | 
            +
                        { :conditions => ["abs(julianday(#{quoted_table_name}.#{connection.quote_column_name start}) - julianday(#{quoted_table_name}.#{connection.quote_column_name stop})) > ?", duration] }
         | 
| 42 | 
            +
                      }
         | 
| 43 | 
            +
                      scope :with_duration_under, lambda { |duration, start, stop|
         | 
| 44 | 
            +
                        { :conditions => ["abs(julianday(#{quoted_table_name}.#{connection.quote_column_name start}) - julianday(#{quoted_table_name}.#{connection.quote_column_name stop})) < ?", duration] }
         | 
| 45 | 
            +
                      }
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| @@ -0,0 +1,79 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Helpers
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                mattr_accessor :options
         | 
| 5 | 
            +
                self.options = {
         | 
| 6 | 
            +
                  :state_pattern => /_(type|state)$/i,
         | 
| 7 | 
            +
                  :default_limit => 10
         | 
| 8 | 
            +
                }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def self.included(base)
         | 
| 11 | 
            +
                  base.extend ClassMethods
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                module ClassMethods
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def safe_column_names
         | 
| 17 | 
            +
                    safe_columns.collect(&:name)
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def non_boolean_column_names
         | 
| 21 | 
            +
                    column_names_without_type :boolean
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def boolean_column_names
         | 
| 25 | 
            +
                    column_names_for_type :boolean
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def datetime_column_names
         | 
| 29 | 
            +
                    column_names_for_type :datetime, :date
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def text_and_string_column_names
         | 
| 33 | 
            +
                    column_names_for_type :text, :string
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def non_state_text_and_string_columns
         | 
| 37 | 
            +
                    text_and_string_column_names.reject { |name| name =~ Pacecar::Helpers.options[:state_pattern] }
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def numeric_column_names
         | 
| 41 | 
            +
                    column_names_for_type :integer, :float
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  protected
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def safe_columns
         | 
| 47 | 
            +
                    case ActiveRecord::Base.connection.adapter_name
         | 
| 48 | 
            +
                    when 'MySQL'
         | 
| 49 | 
            +
                      begin
         | 
| 50 | 
            +
                        columns
         | 
| 51 | 
            +
                      rescue Mysql::Error
         | 
| 52 | 
            +
                        Array.new
         | 
| 53 | 
            +
                      end
         | 
| 54 | 
            +
                    when 'Mysql2'
         | 
| 55 | 
            +
                      begin
         | 
| 56 | 
            +
                        columns
         | 
| 57 | 
            +
                      rescue Mysql2::Error
         | 
| 58 | 
            +
                        Array.new
         | 
| 59 | 
            +
                      end
         | 
| 60 | 
            +
                    when 'SQLite', 'PostgreSQL'
         | 
| 61 | 
            +
                      begin
         | 
| 62 | 
            +
                        columns
         | 
| 63 | 
            +
                      rescue ActiveRecord::StatementInvalid # If the table does not exist
         | 
| 64 | 
            +
                        Array.new
         | 
| 65 | 
            +
                      end
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  def column_names_for_type(*types)
         | 
| 70 | 
            +
                    safe_columns.select { |column| types.include? column.type }.collect(&:name)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  def column_names_without_type(*types)
         | 
| 74 | 
            +
                    safe_columns.select { |column| ! types.include? column.type }.collect(&:name)
         | 
| 75 | 
            +
                  end      
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Limit
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
                  def self.extended(base)
         | 
| 9 | 
            +
                    base.send :define_limit_scopes
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  protected
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def define_limit_scopes
         | 
| 15 | 
            +
                    scope :limited, lambda { |*args|
         | 
| 16 | 
            +
                      { :limit => args.flatten.first || (defined?(per_page) ? per_page : Pacecar::Helpers.options[:default_limit]) }
         | 
| 17 | 
            +
                    }
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Numeric
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
                  def self.extended(base)
         | 
| 9 | 
            +
                    base.send :define_numeric_scopes
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  protected
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def define_numeric_scopes
         | 
| 15 | 
            +
                    numeric_column_names.each do |name|
         | 
| 16 | 
            +
                      { :greater_than => '>', :less_than => '<' }.each do |method_name, symbol|
         | 
| 17 | 
            +
                        scope "#{name}_#{method_name}".to_sym, lambda { |value|
         | 
| 18 | 
            +
                          { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} #{symbol} ?", value] }
         | 
| 19 | 
            +
                        }
         | 
| 20 | 
            +
                        scope "#{name}_#{method_name}_or_equal_to".to_sym, lambda { |value|
         | 
| 21 | 
            +
                          { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} #{symbol}= ?", value] }
         | 
| 22 | 
            +
                        }
         | 
| 23 | 
            +
                      end
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Order
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
                  def self.extended(base)
         | 
| 9 | 
            +
                    base.send :define_order_scopes
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  protected
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def define_order_scopes
         | 
| 15 | 
            +
                    safe_column_names.each do |name|
         | 
| 16 | 
            +
                      scope "by_#{name}".to_sym, lambda { |*args|
         | 
| 17 | 
            +
                        { :order => "#{quoted_table_name}.#{connection.quote_column_name name} #{args.flatten.first || 'asc'}" }
         | 
| 18 | 
            +
                      }
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Polymorph
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def has_polymorph(name)
         | 
| 10 | 
            +
                    scope "for_#{name}_type".to_sym, lambda { |type|
         | 
| 11 | 
            +
                      polymorph_type = "#{name}_type"
         | 
| 12 | 
            +
                      { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name polymorph_type} = ?", type.to_s] }
         | 
| 13 | 
            +
                    }
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Presence
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
                  def self.extended(base)
         | 
| 9 | 
            +
                    base.send :define_presence_scopes
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  protected
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def define_presence_scopes
         | 
| 15 | 
            +
                    non_boolean_column_names.each do |name|
         | 
| 16 | 
            +
                      scope "#{name}_present".to_sym, :conditions => "#{quoted_table_name}.#{connection.quote_column_name name} IS NOT NULL"
         | 
| 17 | 
            +
                      scope "#{name}_missing".to_sym, :conditions => "#{quoted_table_name}.#{connection.quote_column_name name} IS NULL"
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Ranking
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def has_ranking(association)
         | 
| 10 | 
            +
                    define_ranking_scope association, :maximum, :desc
         | 
| 11 | 
            +
                    define_ranking_scope association, :minimum, :asc
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  protected
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def define_ranking_scope(association, name, direction)
         | 
| 17 | 
            +
                    scope "#{name}_#{association}",
         | 
| 18 | 
            +
                    :select => "#{quoted_table_name}.*, count(#{reflections[association].quoted_table_name}.#{connection.quote_column_name reflections[association].primary_key_name}) as #{association}_count",
         | 
| 19 | 
            +
                    :joins => "inner join #{association} on #{association}.#{reflections[association].primary_key_name} = #{quoted_table_name}.#{connection.quote_column_name primary_key}",
         | 
| 20 | 
            +
                    :group => safe_column_names.collect { |name| "#{quoted_table_name}.#{connection.quote_column_name(name)}" }.join(', '),
         | 
| 21 | 
            +
                    :order => "#{association}_count #{direction}"
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module Search
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
                  def self.extended(base)
         | 
| 9 | 
            +
                    base.send :define_search_scopes
         | 
| 10 | 
            +
                    base.send :define_basic_search_scope
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  protected
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  def define_search_scopes
         | 
| 16 | 
            +
                    safe_column_names.each do |name|
         | 
| 17 | 
            +
                      scope "#{name}_equals".to_sym, lambda { |query|
         | 
| 18 | 
            +
                        { :conditions => { table_name => { name.to_sym => query} } }
         | 
| 19 | 
            +
                      }
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                    text_and_string_column_names.each do |name|
         | 
| 22 | 
            +
                      scope "#{name}_matches".to_sym, lambda { |query|
         | 
| 23 | 
            +
                        { :conditions => ["lower(#{quoted_table_name}.#{connection.quote_column_name(name)}) LIKE lower(:query)", { :query => "%#{query}%" }] }
         | 
| 24 | 
            +
                      }
         | 
| 25 | 
            +
                      scope "#{name}_starts_with".to_sym, lambda { |query|
         | 
| 26 | 
            +
                        { :conditions => ["lower(#{quoted_table_name}.#{connection.quote_column_name(name)}) LIKE lower(:query)", { :query => "#{query}%" }] }
         | 
| 27 | 
            +
                      }
         | 
| 28 | 
            +
                      scope "#{name}_ends_with".to_sym, lambda { |query|
         | 
| 29 | 
            +
                        { :conditions => ["lower(#{quoted_table_name}.#{connection.quote_column_name(name)}) LIKE lower(:query)", { :query => "%#{query}" }] }
         | 
| 30 | 
            +
                      }
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def define_basic_search_scope
         | 
| 35 | 
            +
                    scope :search_for, lambda { |*args|
         | 
| 36 | 
            +
                      opts = args.extract_options!
         | 
| 37 | 
            +
                      query = args.flatten.first
         | 
| 38 | 
            +
                      columns = opts[:on] || non_state_text_and_string_columns
         | 
| 39 | 
            +
                      joiner = opts[:require].eql?(:all) ? 'AND' : 'OR'
         | 
| 40 | 
            +
                      match = columns.collect { |name| "lower(#{quoted_table_name}.#{connection.quote_column_name(name)}) LIKE lower(:query)" }.join(" #{joiner} ")
         | 
| 41 | 
            +
                      { :conditions => [match, { :query => "%#{query}%" } ] }
         | 
| 42 | 
            +
                    }
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            module Pacecar
         | 
| 2 | 
            +
              module State
         | 
| 3 | 
            +
                def self.included(base)
         | 
| 4 | 
            +
                  base.extend ClassMethods
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                module ClassMethods
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def has_state(*names)
         | 
| 10 | 
            +
                    opts = names.extract_options!
         | 
| 11 | 
            +
                    names.each do |name|
         | 
| 12 | 
            +
                      constant = opts[:with] || const_get(name.to_s.pluralize.upcase)
         | 
| 13 | 
            +
                      constant.each do |state|
         | 
| 14 | 
            +
                        scope "#{name}_#{state.downcase}".to_sym, :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} = ?", state]
         | 
| 15 | 
            +
                        scope "#{name}_not_#{state.downcase}".to_sym, :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} <> ?", state]
         | 
| 16 | 
            +
                        self.class_eval %Q{
         | 
| 17 | 
            +
                          def #{name}_#{state.downcase}?
         | 
| 18 | 
            +
                            #{name} == '#{state}'
         | 
| 19 | 
            +
                          end
         | 
| 20 | 
            +
                          def #{name}_not_#{state.downcase}?
         | 
| 21 | 
            +
                            #{name} != '#{state}'
         | 
| 22 | 
            +
                          end
         | 
| 23 | 
            +
                        }
         | 
| 24 | 
            +
                      end
         | 
| 25 | 
            +
                      scope "#{name}".to_sym, lambda { |state|
         | 
| 26 | 
            +
                        { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} = ?", state] }
         | 
| 27 | 
            +
                      }
         | 
| 28 | 
            +
                      scope "#{name}_not".to_sym, lambda { |state|
         | 
| 29 | 
            +
                        { :conditions => ["#{quoted_table_name}.#{connection.quote_column_name name} <> ?", state] }
         | 
| 30 | 
            +
                      }
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: pacecar
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 4 | 
            +
              hash: 15
         | 
| 5 5 | 
             
              prerelease: false
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 1
         | 
| 8 8 | 
             
              - 4
         | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 1.4. | 
| 9 | 
            +
              - 4
         | 
| 10 | 
            +
              version: 1.4.4
         | 
| 11 11 | 
             
            platform: ruby
         | 
| 12 12 | 
             
            authors: 
         | 
| 13 13 | 
             
            - Matt Jankowski
         | 
| @@ -15,7 +15,7 @@ autorequire: | |
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 17 |  | 
| 18 | 
            -
            date: 2010-12- | 
| 18 | 
            +
            date: 2010-12-11 00:00:00 -05:00
         | 
| 19 19 | 
             
            default_executable: 
         | 
| 20 20 | 
             
            dependencies: []
         | 
| 21 21 |  | 
| @@ -31,6 +31,20 @@ files: | |
| 31 31 | 
             
            - init.rb
         | 
| 32 32 | 
             
            - README.rdoc
         | 
| 33 33 | 
             
            - MIT-LICENSE
         | 
| 34 | 
            +
            - lib/pacecar/associations.rb
         | 
| 35 | 
            +
            - lib/pacecar/boolean.rb
         | 
| 36 | 
            +
            - lib/pacecar/datetime.rb
         | 
| 37 | 
            +
            - lib/pacecar/duration.rb
         | 
| 38 | 
            +
            - lib/pacecar/helpers.rb
         | 
| 39 | 
            +
            - lib/pacecar/limit.rb
         | 
| 40 | 
            +
            - lib/pacecar/numeric.rb
         | 
| 41 | 
            +
            - lib/pacecar/order.rb
         | 
| 42 | 
            +
            - lib/pacecar/polymorph.rb
         | 
| 43 | 
            +
            - lib/pacecar/presence.rb
         | 
| 44 | 
            +
            - lib/pacecar/ranking.rb
         | 
| 45 | 
            +
            - lib/pacecar/search.rb
         | 
| 46 | 
            +
            - lib/pacecar/state.rb
         | 
| 47 | 
            +
            - lib/pacecar.rb
         | 
| 34 48 | 
             
            has_rdoc: true
         | 
| 35 49 | 
             
            homepage: http://github.com/thoughtbot/pacecar
         | 
| 36 50 | 
             
            licenses: []
         |