active_any 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/.travis.yml +15 -2
- data/README.md +23 -12
- data/Rakefile +1 -1
- data/lib/active_any/adapters/abstract_adapter.rb +0 -12
- data/lib/active_any/associations/association.rb +28 -1
- data/lib/active_any/associations/has_many_association.rb +5 -0
- data/lib/active_any/associations/preloader/association.rb +130 -0
- data/lib/active_any/associations/preloader/belongs_to.rb +26 -0
- data/lib/active_any/associations/preloader/has_many.rb +25 -0
- data/lib/active_any/associations/preloader.rb +111 -0
- data/lib/active_any/associations.rb +8 -7
- data/lib/active_any/attribute.rb +71 -0
- data/lib/active_any/base.rb +48 -0
- data/lib/active_any/configuration.rb +19 -0
- data/lib/active_any/core.rb +17 -1
- data/lib/active_any/reflection/association_reflection.rb +65 -0
- data/lib/active_any/reflection.rb +6 -0
- data/lib/active_any/relation/finder_methods.rb +34 -0
- data/lib/active_any/relation/query_methods.rb +145 -0
- data/lib/active_any/relation.rb +34 -150
- data/lib/active_any/subscriber.rb +20 -0
- data/lib/active_any/version.rb +1 -1
- data/lib/active_any.rb +8 -40
- metadata +12 -2
| @@ -54,8 +54,73 @@ module ActiveAny | |
| 54 54 | 
             
                    @primary_key ||= options[:primary_key] || primary_key_for_record_class
         | 
| 55 55 | 
             
                  end
         | 
| 56 56 |  | 
| 57 | 
            +
                  def scope_for(klass)
         | 
| 58 | 
            +
                    scope ? klass.unscoped.instance_exec(nil, &scope) : klass.unscoped
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  def check_preloadable!
         | 
| 62 | 
            +
                    return unless scope
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    if scope.arity.positive?
         | 
| 65 | 
            +
                      raise ArgumentError, <<-MSG.squish
         | 
| 66 | 
            +
                        The association scope '#{name}' is instance dependent (the scope
         | 
| 67 | 
            +
                        block takes an argument). Preloading instance dependent scopes is
         | 
| 68 | 
            +
                        not supported.
         | 
| 69 | 
            +
                      MSG
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                  alias check_eager_loadable! check_preloadable!
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  def inverse_of
         | 
| 75 | 
            +
                    return unless inverse_name
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    @inverse_of ||= klass._reflect_on_association inverse_name
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
             | 
| 57 80 | 
             
                  private
         | 
| 58 81 |  | 
| 82 | 
            +
                  def inverse_name
         | 
| 83 | 
            +
                    options.fetch(:inverse_of) do
         | 
| 84 | 
            +
                      @automatic_inverse_of ||= automatic_inverse_of
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                  def automatic_inverse_of
         | 
| 89 | 
            +
                    if can_find_inverse_of_automatically?(self)
         | 
| 90 | 
            +
                      inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                      begin
         | 
| 93 | 
            +
                        reflection = klass._reflect_on_association(inverse_name)
         | 
| 94 | 
            +
                      rescue NameError
         | 
| 95 | 
            +
                        # Give up: we couldn't compute the klass type so we won't be able
         | 
| 96 | 
            +
                        # to find any associations either.
         | 
| 97 | 
            +
                        reflection = false
         | 
| 98 | 
            +
                      end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                      if valid_inverse_reflection?(reflection)
         | 
| 101 | 
            +
                        return inverse_name
         | 
| 102 | 
            +
                      end
         | 
| 103 | 
            +
                    end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                    false
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  VALID_AUTOMATIC_INVERSE_MACROS = %i[has_many has_one belongs_to].freeze
         | 
| 109 | 
            +
                  INVALID_AUTOMATIC_INVERSE_OPTIONS = %i[foreign_key].freeze
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  def can_find_inverse_of_automatically?(reflection)
         | 
| 112 | 
            +
                    reflection.options[:inverse_of] != false &&
         | 
| 113 | 
            +
                      VALID_AUTOMATIC_INVERSE_MACROS.include?(reflection.macro) &&
         | 
| 114 | 
            +
                      INVALID_AUTOMATIC_INVERSE_OPTIONS.none? { |opt| reflection.options[opt] } &&
         | 
| 115 | 
            +
                      !reflection.scope
         | 
| 116 | 
            +
                  end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  def valid_inverse_reflection?(reflection)
         | 
| 119 | 
            +
                    reflection &&
         | 
| 120 | 
            +
                      klass.name == reflection.record_class.name &&
         | 
| 121 | 
            +
                      can_find_inverse_of_automatically?(reflection)
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
             | 
| 59 124 | 
             
                  def join_pk
         | 
| 60 125 | 
             
                    raise NotImplementedError
         | 
| 61 126 | 
             
                  end
         | 
| @@ -10,7 +10,9 @@ module ActiveAny | |
| 10 10 |  | 
| 11 11 | 
             
                included do
         | 
| 12 12 | 
             
                  class_attribute :reflections, instance_writer: false
         | 
| 13 | 
            +
                  class_attribute :_reflections, instance_writer: false
         | 
| 13 14 | 
             
                  self.reflections = {}
         | 
| 15 | 
            +
                  self._reflections = {}
         | 
| 14 16 | 
             
                end
         | 
| 15 17 |  | 
| 16 18 | 
             
                class UnknownPrimaryKey < StandardError
         | 
| @@ -45,5 +47,9 @@ module ActiveAny | |
| 45 47 | 
             
                def self.add_reflection(klass, name, reflection)
         | 
| 46 48 | 
             
                  klass.reflections = klass.reflections.merge(name.to_s => reflection)
         | 
| 47 49 | 
             
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def self._reflect_on_association(association)
         | 
| 52 | 
            +
                  _reflections[association.to_s]
         | 
| 53 | 
            +
                end
         | 
| 48 54 | 
             
              end
         | 
| 49 55 | 
             
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ActiveAny
         | 
| 4 | 
            +
              class Relation
         | 
| 5 | 
            +
                module FinderMethods
         | 
| 6 | 
            +
                  def find_by(condition)
         | 
| 7 | 
            +
                    where(condition).take
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def first(limit = nil)
         | 
| 11 | 
            +
                    if loaded
         | 
| 12 | 
            +
                      limit ? records.first(limit) : records.first
         | 
| 13 | 
            +
                    else
         | 
| 14 | 
            +
                      limit ? spawn.records.first(limit) : spawn.records.first
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def last(limit = nil)
         | 
| 19 | 
            +
                    return find_last(limit) if loaded? || limit_value
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    result = limit(limit)
         | 
| 22 | 
            +
                    result.order!(klass.primary_key) if order_clause.empty? && klass.primary_key
         | 
| 23 | 
            +
                    result = result.reverse_order!
         | 
| 24 | 
            +
                    limit ? result.reverse : result.first
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  private
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  def find_last(limit)
         | 
| 30 | 
            +
                    limit ? records.last(limit) : records.last
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,145 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ActiveAny
         | 
| 4 | 
            +
              class Relation
         | 
| 5 | 
            +
                MULTI_VALUE_METHODS  = %i[group includes join].freeze
         | 
| 6 | 
            +
                SINGLE_VALUE_METHODS = %i[limit].freeze
         | 
| 7 | 
            +
                CLAUSE_METHODS = %i[where order].freeze
         | 
| 8 | 
            +
                VALUE_METHODS = (MULTI_VALUE_METHODS + SINGLE_VALUE_METHODS + CLAUSE_METHODS).freeze
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                module QueryMethods # rubocop:disable Metrics/ModuleLength
         | 
| 11 | 
            +
                  extend ActiveSupport::Concern
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  Relation::VALUE_METHODS.each do |name|
         | 
| 14 | 
            +
                    method_name = \
         | 
| 15 | 
            +
                      case name
         | 
| 16 | 
            +
                      when *Relation::MULTI_VALUE_METHODS then "#{name}_values"
         | 
| 17 | 
            +
                      when *Relation::SINGLE_VALUE_METHODS then "#{name}_value"
         | 
| 18 | 
            +
                      when *Relation::CLAUSE_METHODS then "#{name}_clause"
         | 
| 19 | 
            +
                      end
         | 
| 20 | 
            +
                    class_eval <<-CODE, __FILE__, __LINE__ + 1
         | 
| 21 | 
            +
                      def #{method_name}                   # def includes_values
         | 
| 22 | 
            +
                        get_value(#{name.inspect})         #   get_value(:includes)
         | 
| 23 | 
            +
                      end                                  # end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                      def #{method_name}=(value)           # def includes_values=(value)
         | 
| 26 | 
            +
                        set_value(#{name.inspect}, value)  #   set_value(:includes, value)
         | 
| 27 | 
            +
                      end                                  # end
         | 
| 28 | 
            +
                    CODE
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def get_value(name)
         | 
| 32 | 
            +
                    @values[name] || default_value_for(name)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def set_value(name, value)
         | 
| 36 | 
            +
                    assert_mutability!
         | 
| 37 | 
            +
                    @values[name] = value
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def values
         | 
| 41 | 
            +
                    @values.dup
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  def limit(value)
         | 
| 45 | 
            +
                    spawn.limit!(value)
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def where(condition)
         | 
| 49 | 
            +
                    spawn.where!(condition)
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  def take(limit = nil)
         | 
| 53 | 
            +
                    limit ? find_take_with_limit(limit) : find_take
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def reverse_order
         | 
| 57 | 
            +
                    spawn.reverse_order!
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  def reverse_order!
         | 
| 61 | 
            +
                    self.order_clause = order_clause.reverse!
         | 
| 62 | 
            +
                    self
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  def group(*args)
         | 
| 66 | 
            +
                    spawn.group!(*args)
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  def order(*args)
         | 
| 70 | 
            +
                    spawn.order!(*args)
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  def limit!(value)
         | 
| 74 | 
            +
                    self.limit_value = value
         | 
| 75 | 
            +
                    self
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  def where!(condition)
         | 
| 79 | 
            +
                    self.where_clause += WhereClause.new(condition)
         | 
| 80 | 
            +
                    self
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  def group!(*args)
         | 
| 84 | 
            +
                    args.flatten!
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    self.group_values += args
         | 
| 87 | 
            +
                    self
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  def order!(*args)
         | 
| 91 | 
            +
                    args.flatten!
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    self.order_clause += OrderClause.new(args)
         | 
| 94 | 
            +
                    self
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  def includes(*args)
         | 
| 98 | 
            +
                    spawn.includes!(*args)
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  def includes!(*args)
         | 
| 102 | 
            +
                    args.reject!(&:blank?)
         | 
| 103 | 
            +
                    args.flatten!
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                    self.includes_values |= args
         | 
| 106 | 
            +
                    self
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  private
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  def find_take
         | 
| 112 | 
            +
                    if loaded
         | 
| 113 | 
            +
                      records.first
         | 
| 114 | 
            +
                    else
         | 
| 115 | 
            +
                      limit(1).records.first
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
                  end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                  def find_take_with_limit(limit)
         | 
| 120 | 
            +
                    if loaded
         | 
| 121 | 
            +
                      records.take(limit)
         | 
| 122 | 
            +
                    else
         | 
| 123 | 
            +
                      limit(limit).to_a
         | 
| 124 | 
            +
                    end
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                  FROZEN_EMPTY_ARRAY = [].freeze
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                  def default_value_for(name)
         | 
| 130 | 
            +
                    case name
         | 
| 131 | 
            +
                    when :where then WhereClause.empty
         | 
| 132 | 
            +
                    when :order then OrderClause.empty
         | 
| 133 | 
            +
                    when *Relation::MULTI_VALUE_METHODS then FROZEN_EMPTY_ARRAY
         | 
| 134 | 
            +
                    when *Relation::SINGLE_VALUE_METHODS then nil
         | 
| 135 | 
            +
                    else
         | 
| 136 | 
            +
                      raise ArgumentError, "unknown relation value #{name.inspect}"
         | 
| 137 | 
            +
                    end
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                  def assert_mutability!
         | 
| 141 | 
            +
                    raise ImmutableRelation if @loaded
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
              end
         | 
| 145 | 
            +
            end
         | 
    
        data/lib/active_any/relation.rb
    CHANGED
    
    | @@ -1,42 +1,23 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'active_any/relation/finder_methods'
         | 
| 4 | 
            +
            require 'active_any/relation/query_methods'
         | 
| 3 5 | 
             
            require 'active_any/relation/merger'
         | 
| 4 6 | 
             
            require 'active_any/relation/where_clause'
         | 
| 5 7 | 
             
            require 'active_any/relation/order_clause'
         | 
| 6 8 |  | 
| 7 9 | 
             
            module ActiveAny
         | 
| 8 | 
            -
              class Relation | 
| 10 | 
            +
              class Relation
         | 
| 9 11 | 
             
                attr_reader :loaded, :klass
         | 
| 10 12 |  | 
| 11 13 | 
             
                delegate :each, to: :records
         | 
| 12 14 |  | 
| 13 15 | 
             
                include Enumerable
         | 
| 16 | 
            +
                include FinderMethods
         | 
| 17 | 
            +
                include QueryMethods
         | 
| 14 18 |  | 
| 15 19 | 
             
                class ImmutableRelation < StandardError; end
         | 
| 16 20 |  | 
| 17 | 
            -
                MULTI_VALUE_METHODS  = %i[group].freeze
         | 
| 18 | 
            -
                SINGLE_VALUE_METHODS = %i[limit].freeze
         | 
| 19 | 
            -
                CLAUSE_METHODS = %i[where order].freeze
         | 
| 20 | 
            -
                VALUE_METHODS = (MULTI_VALUE_METHODS + SINGLE_VALUE_METHODS + CLAUSE_METHODS).freeze
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                Relation::VALUE_METHODS.each do |name|
         | 
| 23 | 
            -
                  method_name = \
         | 
| 24 | 
            -
                    case name
         | 
| 25 | 
            -
                    when *Relation::MULTI_VALUE_METHODS then "#{name}_values"
         | 
| 26 | 
            -
                    when *Relation::SINGLE_VALUE_METHODS then "#{name}_value"
         | 
| 27 | 
            -
                    when *Relation::CLAUSE_METHODS then "#{name}_clause"
         | 
| 28 | 
            -
                    end
         | 
| 29 | 
            -
                  class_eval <<-CODE, __FILE__, __LINE__ + 1
         | 
| 30 | 
            -
                    def #{method_name}                   # def includes_values
         | 
| 31 | 
            -
                      get_value(#{name.inspect})         #   get_value(:includes)
         | 
| 32 | 
            -
                    end                                  # end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                    def #{method_name}=(value)           # def includes_values=(value)
         | 
| 35 | 
            -
                      set_value(#{name.inspect}, value)  #   set_value(:includes, value)
         | 
| 36 | 
            -
                    end                                  # end
         | 
| 37 | 
            -
                  CODE
         | 
| 38 | 
            -
                end
         | 
| 39 | 
            -
             | 
| 40 21 | 
             
                def self.create(klass, *args)
         | 
| 41 22 | 
             
                  new(klass, *args)
         | 
| 42 23 | 
             
                end
         | 
| @@ -48,73 +29,10 @@ module ActiveAny | |
| 48 29 | 
             
                  @values = {}
         | 
| 49 30 | 
             
                end
         | 
| 50 31 |  | 
| 51 | 
            -
                def get_value(name)
         | 
| 52 | 
            -
                  @values[name] || default_value_for(name)
         | 
| 53 | 
            -
                end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                def set_value(name, value)
         | 
| 56 | 
            -
                  assert_mutability!
         | 
| 57 | 
            -
                  @values[name] = value
         | 
| 58 | 
            -
                end
         | 
| 59 | 
            -
             | 
| 60 32 | 
             
                def to_a
         | 
| 61 33 | 
             
                  records.dup
         | 
| 62 34 | 
             
                end
         | 
| 63 35 |  | 
| 64 | 
            -
                def limit(value)
         | 
| 65 | 
            -
                  spawn.limit!(value)
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                def where(condition)
         | 
| 69 | 
            -
                  spawn.where!(condition)
         | 
| 70 | 
            -
                end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                def find_by(condition)
         | 
| 73 | 
            -
                  where(condition).take
         | 
| 74 | 
            -
                end
         | 
| 75 | 
            -
             | 
| 76 | 
            -
                def take(limit = nil)
         | 
| 77 | 
            -
                  limit ? find_take_with_limit(limit) : find_take
         | 
| 78 | 
            -
                end
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                def first(limit = nil)
         | 
| 81 | 
            -
                  if loaded
         | 
| 82 | 
            -
                    limit ? records.first(limit) : records.first
         | 
| 83 | 
            -
                  else
         | 
| 84 | 
            -
                    limit ? spawn.records.first(limit) : spawn.records.first
         | 
| 85 | 
            -
                  end
         | 
| 86 | 
            -
                end
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                def last(limit = nil)
         | 
| 89 | 
            -
                  return find_last(limit) if loaded? || limit_value
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                  result = limit(limit)
         | 
| 92 | 
            -
                  result.order!(klass.primary_key) if order_clause.empty? && klass.primary_key
         | 
| 93 | 
            -
                  result = result.reverse_order!
         | 
| 94 | 
            -
                  limit ? result.reverse : result.first
         | 
| 95 | 
            -
                end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                def reverse_order
         | 
| 98 | 
            -
                  spawn.reverse_order!
         | 
| 99 | 
            -
                end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                def reverse_order!
         | 
| 102 | 
            -
                  self.order_clause = order_clause.reverse!
         | 
| 103 | 
            -
                  self
         | 
| 104 | 
            -
                end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                def find_last(limit)
         | 
| 107 | 
            -
                  limit ? records.last(limit) : records.last
         | 
| 108 | 
            -
                end
         | 
| 109 | 
            -
             | 
| 110 | 
            -
                def group(*args)
         | 
| 111 | 
            -
                  spawn.group!(*args)
         | 
| 112 | 
            -
                end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                def order(*args)
         | 
| 115 | 
            -
                  spawn.order!(*args)
         | 
| 116 | 
            -
                end
         | 
| 117 | 
            -
             | 
| 118 36 | 
             
                def merge(other)
         | 
| 119 37 | 
             
                  if other.is_a?(Array)
         | 
| 120 38 | 
             
                    records & other
         | 
| @@ -137,32 +55,8 @@ module ActiveAny | |
| 137 55 | 
             
                  end
         | 
| 138 56 | 
             
                end
         | 
| 139 57 |  | 
| 140 | 
            -
                def limit!(value)
         | 
| 141 | 
            -
                  self.limit_value = value
         | 
| 142 | 
            -
                  self
         | 
| 143 | 
            -
                end
         | 
| 144 | 
            -
             | 
| 145 | 
            -
                def where!(condition)
         | 
| 146 | 
            -
                  self.where_clause += WhereClause.new(condition)
         | 
| 147 | 
            -
                  self
         | 
| 148 | 
            -
                end
         | 
| 149 | 
            -
             | 
| 150 | 
            -
                def group!(*args)
         | 
| 151 | 
            -
                  args.flatten!
         | 
| 152 | 
            -
             | 
| 153 | 
            -
                  self.group_values += args
         | 
| 154 | 
            -
                  self
         | 
| 155 | 
            -
                end
         | 
| 156 | 
            -
             | 
| 157 | 
            -
                def order!(*args)
         | 
| 158 | 
            -
                  args.flatten!
         | 
| 159 | 
            -
             | 
| 160 | 
            -
                  self.order_clause += OrderClause.new(args)
         | 
| 161 | 
            -
                  self
         | 
| 162 | 
            -
                end
         | 
| 163 | 
            -
             | 
| 164 58 | 
             
                def records
         | 
| 165 | 
            -
                   | 
| 59 | 
            +
                  load
         | 
| 166 60 | 
             
                  @records
         | 
| 167 61 | 
             
                end
         | 
| 168 62 |  | 
| @@ -172,10 +66,6 @@ module ActiveAny | |
| 172 66 | 
             
                  super
         | 
| 173 67 | 
             
                end
         | 
| 174 68 |  | 
| 175 | 
            -
                def values
         | 
| 176 | 
            -
                  @values.dup
         | 
| 177 | 
            -
                end
         | 
| 178 | 
            -
             | 
| 179 69 | 
             
                def reset
         | 
| 180 70 | 
             
                  @loaded = nil
         | 
| 181 71 | 
             
                  @records = [].freeze
         | 
| @@ -186,58 +76,52 @@ module ActiveAny | |
| 186 76 | 
             
                  @loaded
         | 
| 187 77 | 
             
                end
         | 
| 188 78 |  | 
| 189 | 
            -
                 | 
| 190 | 
            -
             | 
| 191 | 
            -
                def load_unless_loaded
         | 
| 79 | 
            +
                def load
         | 
| 192 80 | 
             
                  exec_query unless loaded
         | 
| 193 81 | 
             
                  self
         | 
| 194 82 | 
             
                end
         | 
| 195 83 |  | 
| 196 | 
            -
                def  | 
| 197 | 
            -
                   | 
| 84 | 
            +
                def eager_loading?
         | 
| 85 | 
            +
                  false
         | 
| 198 86 | 
             
                end
         | 
| 199 87 |  | 
| 200 | 
            -
                 | 
| 201 | 
            -
                  if loaded
         | 
| 202 | 
            -
                    records.take(limit)
         | 
| 203 | 
            -
                  else
         | 
| 204 | 
            -
                    limit(limit).to_a
         | 
| 205 | 
            -
                  end
         | 
| 206 | 
            -
                end
         | 
| 88 | 
            +
                private
         | 
| 207 89 |  | 
| 208 | 
            -
                def  | 
| 209 | 
            -
                   | 
| 210 | 
            -
                    records.first
         | 
| 211 | 
            -
                  else
         | 
| 212 | 
            -
                    limit(1).records.first
         | 
| 213 | 
            -
                  end
         | 
| 90 | 
            +
                def spawn
         | 
| 91 | 
            +
                  clone
         | 
| 214 92 | 
             
                end
         | 
| 215 93 |  | 
| 216 | 
            -
                def  | 
| 217 | 
            -
                   | 
| 94 | 
            +
                def clauses
         | 
| 95 | 
            +
                  {
         | 
| 218 96 | 
             
                    where_clause: where_clause,
         | 
| 219 97 | 
             
                    limit_value: limit_value,
         | 
| 220 98 | 
             
                    group_values: group_values,
         | 
| 221 99 | 
             
                    order_clause: order_clause
         | 
| 222 | 
            -
                   | 
| 223 | 
            -
                  @loaded = true
         | 
| 100 | 
            +
                  }
         | 
| 224 101 | 
             
                end
         | 
| 225 102 |  | 
| 226 | 
            -
                def  | 
| 227 | 
            -
                   | 
| 103 | 
            +
                def exec_query
         | 
| 104 | 
            +
                  ActiveSupport::Notifications.instrument('exec_query.active_any', clauses: clauses, class_name: klass.name) do
         | 
| 105 | 
            +
                    @records = klass.find_by_query(clauses)
         | 
| 106 | 
            +
                    preload_records(@records)
         | 
| 107 | 
            +
                    @loaded = true
         | 
| 108 | 
            +
                  end
         | 
| 228 109 | 
             
                end
         | 
| 229 110 |  | 
| 230 | 
            -
                 | 
| 231 | 
            -
             | 
| 232 | 
            -
             | 
| 233 | 
            -
                   | 
| 234 | 
            -
                   | 
| 235 | 
            -
                   | 
| 236 | 
            -
                   | 
| 237 | 
            -
             | 
| 238 | 
            -
             | 
| 239 | 
            -
                    raise ArgumentError, "unknown relation value #{name.inspect}"
         | 
| 111 | 
            +
                def preload_records(records)
         | 
| 112 | 
            +
                  # TODO: implement preload
         | 
| 113 | 
            +
                  # preload = preload_values
         | 
| 114 | 
            +
                  preload = []
         | 
| 115 | 
            +
                  preload += includes_values unless eager_loading?
         | 
| 116 | 
            +
                  preloader = nil
         | 
| 117 | 
            +
                  preload.each do |associations|
         | 
| 118 | 
            +
                    preloader ||= build_preloader
         | 
| 119 | 
            +
                    preloader.preload records, associations
         | 
| 240 120 | 
             
                  end
         | 
| 241 121 | 
             
                end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                def build_preloader
         | 
| 124 | 
            +
                  ActiveAny::Associations::Preloader.new
         | 
| 125 | 
            +
                end
         | 
| 242 126 | 
             
              end
         | 
| 243 127 | 
             
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ActiveAny
         | 
| 4 | 
            +
              class Subscriber < ActiveSupport::LogSubscriber
         | 
| 5 | 
            +
                attach_to :active_any
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def exec_query(event)
         | 
| 8 | 
            +
                  class_name = event.payload[:class_name]
         | 
| 9 | 
            +
                  clauses = event.payload[:clauses]
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  debug "#{class_name} exec_query(clauses: #{clauses})"
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                private
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def logger
         | 
| 17 | 
            +
                  super || ActiveSupport::LogSubscriber.logger = ActiveAny.config.logger
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
    
        data/lib/active_any/version.rb
    CHANGED
    
    
    
        data/lib/active_any.rb
    CHANGED
    
    | @@ -4,6 +4,8 @@ require 'active_support' | |
| 4 4 | 
             
            require 'active_support/core_ext'
         | 
| 5 5 |  | 
| 6 6 | 
             
            require 'active_any/version'
         | 
| 7 | 
            +
            require 'active_any/attribute'
         | 
| 8 | 
            +
            require 'active_any/configuration'
         | 
| 7 9 | 
             
            require 'active_any/relation'
         | 
| 8 10 | 
             
            require 'active_any/reflection'
         | 
| 9 11 | 
             
            require 'active_any/associations'
         | 
| @@ -11,52 +13,18 @@ require 'active_any/association_relation' | |
| 11 13 | 
             
            require 'active_any/attribute_assignment'
         | 
| 12 14 | 
             
            require 'active_any/finders'
         | 
| 13 15 | 
             
            require 'active_any/core'
         | 
| 16 | 
            +
            require 'active_any/base'
         | 
| 17 | 
            +
            require 'active_any/subscriber'
         | 
| 14 18 | 
             
            require 'active_any/adapter'
         | 
| 15 19 | 
             
            require 'active_any/adapters/abstract_adapter'
         | 
| 16 20 | 
             
            require 'active_any/adapters/object_adapter'
         | 
| 17 21 |  | 
| 18 22 | 
             
            module ActiveAny
         | 
| 19 | 
            -
               | 
| 20 | 
            -
                 | 
| 21 | 
            -
                include Associations
         | 
| 22 | 
            -
                include AttributeAssignment
         | 
| 23 | 
            -
                include Finders
         | 
| 24 | 
            -
                include Reflection
         | 
| 23 | 
            +
              def self.configure
         | 
| 24 | 
            +
                yield config
         | 
| 25 25 | 
             
              end
         | 
| 26 26 |  | 
| 27 | 
            -
               | 
| 28 | 
            -
                 | 
| 29 | 
            -
                  child.abstract_class = false
         | 
| 30 | 
            -
                end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                class << self
         | 
| 33 | 
            -
                  attr_accessor :data
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  def adapter
         | 
| 36 | 
            -
                    @adapter ||= ObjectAdapter.new(self)
         | 
| 37 | 
            -
                  end
         | 
| 38 | 
            -
                end
         | 
| 39 | 
            -
              end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
              class Hash < Base
         | 
| 42 | 
            -
                def self.inherited(child)
         | 
| 43 | 
            -
                  child.abstract_class = false
         | 
| 44 | 
            -
                end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                class << self
         | 
| 47 | 
            -
                  attr_reader :data
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                  def data=(data)
         | 
| 50 | 
            -
                    data.map(&:keys).flatten.each do |method|
         | 
| 51 | 
            -
                      attr_accessor method
         | 
| 52 | 
            -
                    end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                    @data = data.map { |d| new(d) }
         | 
| 55 | 
            -
                  end
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                  def adapter
         | 
| 58 | 
            -
                    @adapter ||= ObjectAdapter.new(self)
         | 
| 59 | 
            -
                  end
         | 
| 60 | 
            -
                end
         | 
| 27 | 
            +
              def self.config
         | 
| 28 | 
            +
                @config ||= Configuration.new
         | 
| 61 29 | 
             
              end
         | 
| 62 30 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: active_any
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - yuemori
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2017-07- | 
| 11 | 
            +
            date: 2017-07-25 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -212,7 +212,14 @@ files: | |
| 212 212 | 
             
            - lib/active_any/associations/builder/has_many.rb
         | 
| 213 213 | 
             
            - lib/active_any/associations/collection_proxy.rb
         | 
| 214 214 | 
             
            - lib/active_any/associations/has_many_association.rb
         | 
| 215 | 
            +
            - lib/active_any/associations/preloader.rb
         | 
| 216 | 
            +
            - lib/active_any/associations/preloader/association.rb
         | 
| 217 | 
            +
            - lib/active_any/associations/preloader/belongs_to.rb
         | 
| 218 | 
            +
            - lib/active_any/associations/preloader/has_many.rb
         | 
| 219 | 
            +
            - lib/active_any/attribute.rb
         | 
| 215 220 | 
             
            - lib/active_any/attribute_assignment.rb
         | 
| 221 | 
            +
            - lib/active_any/base.rb
         | 
| 222 | 
            +
            - lib/active_any/configuration.rb
         | 
| 216 223 | 
             
            - lib/active_any/core.rb
         | 
| 217 224 | 
             
            - lib/active_any/finders.rb
         | 
| 218 225 | 
             
            - lib/active_any/reflection.rb
         | 
| @@ -220,9 +227,12 @@ files: | |
| 220 227 | 
             
            - lib/active_any/reflection/belongs_to_reflection.rb
         | 
| 221 228 | 
             
            - lib/active_any/reflection/has_many_reflection.rb
         | 
| 222 229 | 
             
            - lib/active_any/relation.rb
         | 
| 230 | 
            +
            - lib/active_any/relation/finder_methods.rb
         | 
| 223 231 | 
             
            - lib/active_any/relation/merger.rb
         | 
| 224 232 | 
             
            - lib/active_any/relation/order_clause.rb
         | 
| 233 | 
            +
            - lib/active_any/relation/query_methods.rb
         | 
| 225 234 | 
             
            - lib/active_any/relation/where_clause.rb
         | 
| 235 | 
            +
            - lib/active_any/subscriber.rb
         | 
| 226 236 | 
             
            - lib/active_any/version.rb
         | 
| 227 237 | 
             
            homepage: https://github.com/yuemori/active_any
         | 
| 228 238 | 
             
            licenses:
         |