Sha256: 068a3c972dd3c7304fa88a07ed919a644a830e886639f1f7bdb69ada3175c029

Contents?: true

Size: 1.78 KB

Versions: 1

Compression:

Stored size: 1.78 KB

Contents

module Fx
  class Aggregate
    include Comparable

    attr_reader :name, :arguments, :definition
    delegate :<=>, to: :name

    def initialize(aggregate_row)
      @name = aggregate_row.fetch("name")
      @arguments = aggregate_row.fetch("arguments", "")
      @definition = aggregate_row.except("name", "arguments")
    end

    def ==(other)
      other.is_a?(self.class) &&
        name == other.name &&
        arguments == other.arguments &&
        definition == other.definition
    end

    def to_schema
      <<-SCHEMA
  create_aggregate :#{name}, sql_definition: <<-\SQL
    CREATE AGGREGATE #{name}(#{arguments})(
      #{options_for_create_statement.join(",\n").indent(6).lstrip}
    );
  SQL
      SCHEMA
    end

    private

    Field = Struct.new(:option, :type)
    private_constant :Field

    # Maps pg_aggregate columns to their definition field and type.
    FIELDS = {
      "aggtransfn" => Field.new("SFUNC", "raw"),
      "aggtranstype" => Field.new("STYPE", "raw"),
      "aggtransspace" => Field.new("SSPACE", "int"),
      "aggfinalfn" => Field.new("FINALFUNC", "raw"),
      "aggfinalextra" => Field.new("FINALFUNC_EXTRA", "bool"),
      "agginitval" => Field.new("INITCOND", "string")
    }.freeze

    def options_for_create_statement
      FIELDS.map do |key, field|
        value = format_value(field.type, @definition[key])
        next if !value

        if value == true
          field.option
        else
          "#{field.option} = #{value}"
        end
      end.compact
    end

    def format_value(type, value)
      return if value.nil?
      return if value == "-"

      case type
      when "bool"
        return value == "t"
      when "int"
        return if value.to_i == 0
      when "string"
        return "'#{value}'"
      end

      value
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
fx-aggregate-0.1.0 lib/fx-aggregate/aggregate.rb