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

Defined in:
lib/rom/sql/extensions/postgres/types/geometric.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/network.rb

Defined Under Namespace

Modules: ArrayMethods, JSONMethods

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
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 }
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

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
Line =
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
Circle =
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
Box =
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
LineSegment =
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
Polygon =
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
Path =
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

Class Method Summary collapse

Class Method Details

.Array(db_type) ⇒ Object



23
24
25
# File 'lib/rom/sql/extensions/postgres/types/array.rb', line 23

def self.Array(db_type)
  @array_types[db_type]
end

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



11
12
13
# File 'lib/rom/sql/extensions/postgres/types.rb', line 11

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