Class: ActiveRecord::ConnectionAdapters::CockroachDB::OID::Spatial

Inherits:
Type::Value
  • Object
show all
Defined in:
lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(oid, sql_type) ⇒ Spatial

sql_type is a string that comes from the database definition examples:

"geometry(Point,4326)"
"geography(Point,4326)"
"geometry(Polygon,4326) NOT NULL"
"geometry(Geography,4326)"


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb', line 28

def initialize(oid, sql_type)
  super()
  @sql_type = sql_type.freeze
  @factory_attrs = self.class
    .parse_sql_type(sql_type)
    .then { |geo_type, srid, has_z, has_m|
      {
        geo_type: geo_type.underscore.freeze,
        srid: srid.freeze,
        has_z: has_z.freeze,
        has_m: has_m.freeze,
        sql_type: type.to_s.freeze
      }
    }
    .freeze
end

Class Method Details

.parse_sql_type(sql_type) ⇒ Object

sql_type: geometry, geometry(Point), geometry(Point,4326), …

returns [geo_type, srid, has_z, has_m]

geo_type: geography, geometry, point, line_string, polygon, ...
srid:     1234
has_z:    false
has_m:    false


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb', line 53

def self.parse_sql_type(sql_type)
  geo_type = nil
  srid = 0
  has_z = false
  has_m = false

  if sql_type =~ /(geography|geometry)\((.*)\)$/i
    # geometry(Point)
    # geometry(Point,4326)
    params = Regexp.last_match(2).split(',')
    if params.first =~ /([a-z]+[^zm])(z?)(m?)/i
      has_z = Regexp.last_match(2).length > 0
      has_m = Regexp.last_match(3).length > 0
      geo_type = Regexp.last_match(1)
    end
    srid = Regexp.last_match(1).to_i if params.last =~ /(\d+)/
  else
    geo_type = sql_type
  end
  [geo_type, srid, has_z, has_m]
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

TODO: add tests (see #390)



102
103
104
105
106
# File 'lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb', line 102

def ==(other)
  super &&
    @sql_type == other.sql_type &&
    @factory_attrs == other.factory_attrs
end

#geographic?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb', line 75

def geographic?
  @sql_type.start_with?("geography")
end

#hashObject

TODO: add tests (see #390)



110
111
112
# File 'lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb', line 110

def hash
  super ^ [@sql_type, @factory_attrs].hash
end

#serialize(value) ⇒ Object

support setting an RGeo object or a WKT string



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb', line 88

def serialize(value)
  return if value.nil?

  geo_value = cast_value(value)

  # TODO: - only valid types should be allowed
  # e.g. linestring is not valid for point column
  # raise "maybe should raise" unless RGeo::Feature::Geometry.check_type(geo_value)

  RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb, emit_ewkb_srid: true)
                           .generate(geo_value)
end

#spatial?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb', line 79

def spatial?
  true
end

#typeObject



83
84
85
# File 'lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb', line 83

def type
  geographic? ? :geography : :geometry
end