Module: ROM::SQL::Postgres::Types

Defined in:
lib/rom/sql/extensions/postgres/types/ltree.rb,
lib/rom/sql/extensions/postgres/types.rb,
lib/rom/sql/extensions/postgres/types/json.rb,
lib/rom/sql/extensions/postgres/types/array.rb,
lib/rom/sql/extensions/postgres/types/range.rb,
lib/rom/sql/extensions/postgres/types/network.rb,
lib/rom/sql/extensions/postgres/types/geometric.rb,
lib/rom/sql/extensions/postgres/types/array_types.rb

Defined Under Namespace

Modules: ArrayMethods, JSONMethods, LTreeMethods, RangeFunctions, RangeOperators Classes: JSONNullType

Constant Summary collapse

UUID =
Type('uuid', SQL::Types::String)
HStore =
Type('hstore') do
  read = SQL::Types.Constructor(Hash, &:to_hash)

  SQL::Types.Constructor(Hash, &Sequel.method(:hstore))
    .meta(read: read)
end
Bytea =
Type('bytea') do
  SQL::Types.Constructor(Sequel::SQL::Blob, &Sequel::SQL::Blob.method(:new))
end
Money =
Type('money', SQL::Types::Decimal)
XML =
Type('xml', SQL::Types::String)
JSONRead =
(SQL::Types::Array | SQL::Types::Hash).constructor do |value|
  if value.respond_to?(:to_hash)
    value.to_hash
  elsif value.respond_to?(:to_ary)
    value.to_ary
  else
    value
  end
end
JSONNull =
JSONNullType.instance.freeze
JSON =
Type('json') do
  (SQL::Types::Array | SQL::Types::Hash).constructor(Sequel.method(:pg_json)).meta(read: JSONRead)
end
JSONB =
Type('jsonb') do
  (SQL::Types::Array | SQL::Types::Hash).constructor(Sequel.method(:pg_jsonb)).meta(read: JSONRead)
end
Array =
SQL::Types::Array
ArrayRead =
Array.constructor { |v| v.respond_to?(:to_ary) ? v.to_ary : v }
LTree =
Type('ltree') do
  SQL::Types.define(ROM::Types::Values::TreePath) do
    input do |label_path|
      label_path.to_s
    end

    output do |label_path|
      ROM::Types::Values::TreePath.new(label_path.to_s) if label_path
    end
  end
end
Int4Range =
range('int4range', range_read_type(:int4range))
Int8Range =
range('int8range', range_read_type(:int8range))
NumRange =
range('numrange',  range_read_type(:numrange))
TsRange =
range('tsrange',   range_read_type(:tsrange))
TsTzRange =
range('tstzrange', range_read_type(:tstzrange))
DateRange =
range('daterange', range_read_type(:daterange))
IPAddress =
Type('inet') do
  read = SQL::Types.Constructor(IPAddr) { |ip| IPAddr.new(ip.to_s) }

  SQL::Types.Constructor(IPAddr, &:to_s).meta(read: read)
end
Point =

The list of geometric data types supported by PostgreSQL

Type('point') do
  SQL::Types.define(Values::Point) do
    input do |point|
      "(#{ point.x },#{ point.y })"
    end

    output do |point|
      x, y = point.to_s[1...-1].split(',', 2)
      Values::Point.new(Float(x), Float(y))
    end
  end
end
Line =
Type('line') do
  SQL::Types.define(Values::Line) do
    input do |line|
      "{#{ line.a },#{ line.b },#{line.c}}"
    end

    output do |line|
      a, b, c = line.to_s[1..-2].split(',', 3)
      Values::Line.new(Float(a), Float(b), Float(c))
    end
  end
end
Circle =
Type('circle') do
  SQL::Types.define(Values::Circle) do
    input do |circle|
      "<(#{ circle.center.x },#{ circle.center.y }),#{ circle.radius }>"
    end

    output do |circle|
      x, y, r = circle.to_s.tr('()<>', '').split(',', 3)
      center = Values::Point.new(Float(x), Float(y))
      Values::Circle.new(center, Float(r))
    end
  end
end
Box =
Type('box') do
  SQL::Types.define(Values::Box) do
    input do |box|
      "((#{ box.upper_right.x },#{ box.upper_right.y }),"\
      "(#{ box.lower_left.x },#{ box.lower_left.y }))"
    end

    output do |box|
      x_right, y_right, x_left, y_left = box.to_s.tr('()', '').split(',', 4)
      upper_right = Values::Point.new(Float(x_right), Float(y_right))
      lower_left = Values::Point.new(Float(x_left), Float(y_left))
      Values::Box.new(upper_right, lower_left)
    end
  end
end
LineSegment =
Type('lseg') do
  SQL::Types.define(Values::LineSegment) do
    input do |segment|
      "[(#{ segment.begin.x },#{ segment.begin.y }),"\
      "(#{ segment.end.x },#{ segment.end.y })]"
    end

    output do |segment|
      x_begin, y_begin, x_end, y_end = segment.to_s.tr('()[]', '').split(',', 4)
      point_begin = Values::Point.new(Float(x_begin), Float(y_begin))
      point_end = Values::Point.new(Float(x_end), Float(y_end))
      Values::LineSegment.new(point_begin, point_end)
    end
  end
end
Polygon =
Type('polygon') do
  SQL::Types.define(::Array) do
    input do |points|
      points_joined = points.map { |p| "(#{ p.x },#{ p.y })" }.join(',')
      "(#{ points_joined })"
    end

    output do |polygon|
      coordinates = polygon.to_s.tr('()', '').split(',').each_slice(2)
      coordinates.map { |x, y| Values::Point.new(Float(x), Float(y)) }
    end
  end
end
Path =
Type('path') do
  SQL::Types.define(Values::Path) do
    input do |path|
      points_joined = path.to_a.map { |p| "(#{ p.x },#{ p.y })" }.join(',')

      if path.open?
        "[#{ points_joined }]"
      else
        "(#{ points_joined })"
      end
    end

    output do |path|
      open = path.to_s.start_with?('[') && path.to_s.end_with?(']')
      coordinates = path.to_s.tr('()[]', '').split(',').each_slice(2)
      points = coordinates.map { |x, y| Values::Point.new(Float(x), Float(y)) }

      if open
        Values::Path.new(points, :open)
      else
        Values::Path.new(points, :closed)
      end
    end
  end
end

Class Method Summary collapse

Class Method Details

.Type(name, type = yield)) ⇒ Object



13
14
15
# File 'lib/rom/sql/extensions/postgres/types.rb', line 13

def self.Type(name, type = yield)
  type.meta(db_type: name, database: 'postgres')
end