Module: ActiveRecord::ConnectionAdapters::PostGIS::SchemaStatements

Included in:
ActiveRecord::ConnectionAdapters::PostGISAdapter
Defined in:
lib/active_record/connection_adapters/postgis/schema_statements.rb

Instance Method Summary collapse

Instance Method Details

#create_table_definition(*args, **kwargs) ⇒ Object

override


77
78
79
# File 'lib/active_record/connection_adapters/postgis/schema_statements.rb', line 77

def create_table_definition(*args, **kwargs)
  PostGIS::TableDefinition.new(self, *args, **kwargs)
end

#initialize_type_map(map = type_map) ⇒ Object


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/active_record/connection_adapters/postgis/schema_statements.rb', line 87

def initialize_type_map(map = type_map)
  %w(
    geography
    geometry
    geometry_collection
    line_string
    multi_line_string
    multi_point
    multi_polygon
    st_point
    st_polygon
  ).each do |geo_type|
    map.register_type(geo_type) do |_, _, sql_type|
      # 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)"
      geo_type, srid, has_z, has_m, geographic = OID::Spatial.parse_sql_type(sql_type)
      OID::Spatial.new(geo_type: geo_type, srid: srid, has_z: has_z, has_m: has_m, geographic: geographic)
    end
  end

  super
end

#native_database_typesObject

override


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/active_record/connection_adapters/postgis/schema_statements.rb', line 60

def native_database_types
  # Add spatial types
  super.merge(
    geography:           { name: "geography" },
    geometry:            { name: "geometry" },
    geometry_collection: { name: "geometry_collection" },
    line_string:         { name: "line_string" },
    multi_line_string:   { name: "multi_line_string" },
    multi_point:         { name: "multi_point" },
    multi_polygon:       { name: "multi_polygon" },
    spatial:             { name: "geometry" },
    st_point:            { name: "st_point" },
    st_polygon:          { name: "st_polygon" }
  )
end

#new_column_from_field(table_name, field) ⇒ Object


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/active_record/connection_adapters/postgis/schema_statements.rb', line 10

def new_column_from_field(table_name, field)
  column_name, type, default, notnull, oid, fmod, collation, comment = field
   = (column_name, type, oid.to_i, fmod.to_i)
  default_value = extract_value_from_default(default)
  default_function = extract_default_function(default_value, default)

  serial =
    if (match = default_function&.match(/\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z/))
      sequence_name_from_parts(table_name, column_name, match[:suffix]) == match[:sequence_name]
    end

  # {:dimension=>2, :has_m=>false, :has_z=>false, :name=>"latlon", :srid=>0, :type=>"GEOMETRY"}
  spatial = spatial_column_info(table_name).get(column_name, .sql_type)

  SpatialColumn.new(
    column_name,
    default_value,
    ,
    !notnull,
    default_function,
    collation: collation,
    comment: comment.presence,
    serial: serial,
    spatial: spatial
  )
end

#spatial_column_info(table_name) ⇒ Object

memoize hash of column infos for tables


82
83
84
85
# File 'lib/active_record/connection_adapters/postgis/schema_statements.rb', line 82

def spatial_column_info(table_name)
  @spatial_column_info ||= {}
  @spatial_column_info[table_name.to_sym] ||= SpatialColumnInfo.new(self, table_name.to_s)
end

#type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil) ⇒ Object

override github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb#L544

returns Postgresql sql type string examples:

"geometry(Point,4326)"
"geography(Point,4326)"

note: type alone is not enough to detect the sql type, so `limit` is used to pass the additional information. :(

type_to_sql(:geography, limit: “Point,4326”)

> “geography(Point,4326)”


50
51
52
53
54
55
56
57
# File 'lib/active_record/connection_adapters/postgis/schema_statements.rb', line 50

def type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil, **)
  case type.to_s
  when "geometry", "geography"
    "#{type}(#{limit})"
  else
    super
  end
end