Sha256: e9ca045ce0f30d07b3c89a24f00fa888c46b51410c8f45333359cd51f11d2d4c

Contents?: true

Size: 1.56 KB

Versions: 1

Compression:

Stored size: 1.56 KB

Contents

module ROM

  class Transformer
    attr_reader :operations

    class Operation
      attr_reader :attribute, :key, :names

      def initialize(attribute)
        @attribute = attribute
        @key = attribute.key
        @names = attribute.header.map(&:key)
      end
    end

    class Wrap < Operation
      def call(tuples)
        keys = nil

        tuples.map { |tuple|
          keys ||= tuple.keys - names

          root = Hash[keys.zip(tuple.values_at(*keys))]
          child = Hash[names.zip(tuple.values_at(*names))]

          root.merge(key => child)
        }
      end
    end

    class Group < Operation
      def call(tuples)
        keys = nil

        tuples.
          group_by { |tuple|
            keys ||= tuple.keys - names
            Hash[keys.zip(tuple.values_at(*keys))]
          }.map { |root, children|
            root.merge(
             key => children.map { |child| Hash[names.zip(child.values_at(*names))] }
            )
          }
      end
    end

    def self.build(header)
      operations = header.map do |attribute|
        type = attribute.type

        if type == Hash
          Wrap.new(attribute)
        elsif type == Array
          Group.new(attribute)
        end
      end.compact

      sorted_ops =
        operations.select { |op| Group === op } +
        operations.select { |op| Wrap === op }

      new(sorted_ops.flatten)
    end

    def initialize(operations)
      @operations = operations
    end

    def call(input)
      output = input
      operations.each { |op| output = op.call(output) }
      output
    end

  end

end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rom-0.4.2 lib/rom/transformer.rb