Sha256: f248711222ff881e595a049104581751356c29da3a60822b41d27d30ebdf7183

Contents?: true

Size: 1.97 KB

Versions: 1

Compression:

Stored size: 1.97 KB

Contents

require "forwardable"
require "set"

module Terrestrial
  class Record
    extend Forwardable

    def initialize(mapping, attributes)
      @mapping = mapping
      @attributes = attributes
    end

    attr_reader :mapping, :attributes
    def_delegators :to_h, :fetch

    def namespace
      mapping.namespace
    end

    def if_upsert(&block)
      self
    end

    def if_delete(&block)
      self
    end

    def updatable?
      updatable_attributes.any?
    end

    def updatable_attributes
      attributes.reject { |k, _v| non_updatable_fields.include?(k) }
    end

    def keys
      attributes.keys
    end

    def identity_values
      identity.values
    end

    def identity
      attributes.select { |k,_v| identity_fields.include?(k) }
    end

    def identity_fields
      mapping.primary_key
    end

    def merge(more_attributes)
      new_with_attributes(attributes.merge(more_attributes))
    end

    def merge!(more_attributes)
      attributes.merge!(more_attributes)
    end

    def reject(&block)
      new_with_attributes(updatable_attributes.reject(&block).merge(identity))
    end

    def to_h
      attributes.to_h
    end

    def empty?
      updatable_attributes.empty?
    end

    def subset?(other_record)
      mapping == other_record.mapping &&
        to_set.subset?(other_record.to_set)
    end

    def deep_clone
      new_with_attributes(Marshal.load(Marshal.dump(attributes)))
    end

    def ==(other)
      other.is_a?(self.class) &&
        [other.mapping, other.attributes] == [mapping, attributes]
    end

    protected

    def to_set
      Set.new(attributes.to_a)
    end

    private

    def non_updatable_fields
      identity_fields + mapping.database_owned_fields + nil_fields_expecting_default_value
    end

    def nil_fields_expecting_default_value
      mapping.database_default_fields.select { |k| attributes[k].nil? }
    end

    def new_with_attributes(new_attributes)
      self.class.new(mapping, new_attributes)
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
terrestrial-0.5.0 lib/terrestrial/record.rb