Class: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
- Inherits:
-
Object
- Object
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
- Defined in:
- lib/spatial_adapter/postgresql.rb
Instance Method Summary collapse
- #add_column(table_name, column_name, type, options = {}) ⇒ Object
-
#add_index(table_name, column_name, options = {}) ⇒ Object
Adds an index to a column.
-
#columns(table_name, name = nil) ⇒ Object
:nodoc:.
- #create_table(table_name, options = {}) {|table_definition| ... } ⇒ Object
-
#disable_referential_integrity(&block) ⇒ Object
:nodoc:.
-
#indexes(table_name, name = nil) ⇒ Object
Returns the list of all indexes for a table.
- #native_database_types ⇒ Object
- #original_add_column ⇒ Object
- #original_native_database_types ⇒ Object
- #original_quote ⇒ Object
- #original_remove_column ⇒ Object
- #postgis_major_version ⇒ Object
- #postgis_minor_version ⇒ Object
- #postgis_version ⇒ Object
-
#quote(value, column = nil) ⇒ Object
Redefines the quote method to add behaviour for when a Geometry is encountered.
- #remove_column(table_name, *column_names) ⇒ Object
- #spatial? ⇒ Boolean
- #supports_geographic? ⇒ Boolean
Instance Method Details
#add_column(table_name, column_name, type, options = {}) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/spatial_adapter/postgresql.rb', line 111 def add_column(table_name, column_name, type, = {}) unless SpatialAdapter.geometry_data_types[type].nil? geom_column = ActiveRecord::ConnectionAdapters::PostgreSQLColumnDefinition.new(self, column_name, type, nil, nil, [:null], [:srid] || -1 , [:with_z] || false , [:with_m] || false, [:geographic] || false) if geom_column.geographic default = [:default] notnull = [:null] == false execute("ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{geom_column.to_sql}") change_column_default(table_name, column_name, default) if () change_column_null(table_name, column_name, false, default) if notnull else geom_column.table_name = table_name execute geom_column.to_sql end else original_add_column(table_name, column_name, type, ) end end |
#add_index(table_name, column_name, options = {}) ⇒ Object
Adds an index to a column.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/spatial_adapter/postgresql.rb', line 132 def add_index(table_name, column_name, = {}) column_names = Array(column_name) index_name = index_name(table_name, :column => column_names) if Hash === # legacy support, since this param was a string index_type = [:unique] ? "UNIQUE" : "" index_name = [:name] || index_name index_method = [:spatial] ? 'USING GIST' : "" else index_type = end quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ") execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} #{index_method} (#{quoted_column_names})" end |
#columns(table_name, name = nil) ⇒ Object
:nodoc:
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/spatial_adapter/postgresql.rb', line 47 def columns(table_name, name = nil) #:nodoc: raw_geom_infos = column_spatial_info(table_name) column_definitions(table_name).collect do |name, type, default, notnull| case type when /geography/i ActiveRecord::ConnectionAdapters::SpatialPostgreSQLColumn.create_from_geography(name, default, type, notnull == 'f') when /geometry/i raw_geom_info = raw_geom_infos[name] if raw_geom_info.nil? # This column isn't in the geometry_columns table, so we don't know anything else about it ActiveRecord::ConnectionAdapters::SpatialPostgreSQLColumn.create_simplified(name, default, notnull == "f") else ActiveRecord::ConnectionAdapters::SpatialPostgreSQLColumn.new(name, default, raw_geom_info.type, notnull == "f", raw_geom_info.srid, raw_geom_info.with_z, raw_geom_info.with_m) end else ActiveRecord::ConnectionAdapters::PostgreSQLColumn.new(name, default, type, notnull == "f") end end end |
#create_table(table_name, options = {}) {|table_definition| ... } ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/spatial_adapter/postgresql.rb', line 68 def create_table(table_name, = {}) # Using the subclassed table definition table_definition = ActiveRecord::ConnectionAdapters::PostgreSQLTableDefinition.new(self) table_definition.primary_key([:primary_key] || ActiveRecord::Base.get_primary_key(table_name.to_s.singularize)) unless [:id] == false yield table_definition if block_given? if [:force] && table_exists?(table_name) drop_table(table_name, ) end create_sql = "CREATE#{' TEMPORARY' if [:temporary]} TABLE " create_sql << "#{quote_table_name(table_name)} (" create_sql << table_definition.to_sql create_sql << ") #{[:options]}" # This is the additional portion for PostGIS unless table_definition.geom_columns.nil? table_definition.geom_columns.each do |geom_column| geom_column.table_name = table_name create_sql << "; " + geom_column.to_sql end end execute create_sql end |
#disable_referential_integrity(&block) ⇒ Object
:nodoc:
198 199 200 201 202 203 204 205 206 207 |
# File 'lib/spatial_adapter/postgresql.rb', line 198 def disable_referential_integrity(&block) #:nodoc: if supports_disable_referential_integrity?() then execute(tables_without_postgis.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";")) end yield ensure if supports_disable_referential_integrity?() then execute(tables_without_postgis.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";")) end end |
#indexes(table_name, name = nil) ⇒ Object
Returns the list of all indexes for a table.
This is a full replacement for the ActiveRecord method and as a result has a higher probability of breaking in future releases.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/spatial_adapter/postgresql.rb', line 151 def indexes(table_name, name = nil) schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',') # Changed from upstread: link to pg_am to grab the index type (e.g. "gist") result = query(<<-SQL, name) SELECT distinct i.relname, d.indisunique, d.indkey, t.oid, am.amname FROM pg_class t, pg_class i, pg_index d, pg_attribute a, pg_am am WHERE i.relkind = 'i' AND d.indexrelid = i.oid AND d.indisprimary = 'f' AND t.oid = d.indrelid AND t.relname = '#{table_name}' AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN (#{schemas}) ) AND i.relam = am.oid AND a.attrelid = t.oid ORDER BY i.relname SQL indexes = [] indexes = result.map do |row| index_name = row[0] unique = row[1] == 't' indkey = row[2].split(" ") oid = row[3] indtype = row[4] # Changed from upstream: need to get the column types to test for spatial indexes columns = query(<<-SQL, "Columns for index #{row[0]} on #{table_name}").inject({}) {|attlist, r| attlist[r[1]] = [r[0], r[2]]; attlist} SELECT a.attname, a.attnum, t.typname FROM pg_attribute a, pg_type t WHERE a.attrelid = #{oid} AND a.attnum IN (#{indkey.join(",")}) AND a.atttypid = t.oid SQL # Only GiST indexes on spatial columns denote a spatial index spatial = indtype == 'gist' && columns.size == 1 && (columns.values.first[1] == 'geometry' || columns.values.first[1] == 'geography') column_names = indkey.map {|attnum| columns[attnum] ? columns[attnum][0] : nil } ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, column_names, spatial) end indexes end |
#native_database_types ⇒ Object
33 34 35 |
# File 'lib/spatial_adapter/postgresql.rb', line 33 def native_database_types original_native_database_types.merge!(SpatialAdapter.geometry_data_types) end |
#original_add_column ⇒ Object
110 |
# File 'lib/spatial_adapter/postgresql.rb', line 110 alias :original_add_column :add_column |
#original_native_database_types ⇒ Object
32 |
# File 'lib/spatial_adapter/postgresql.rb', line 32 alias :original_native_database_types :native_database_types |
#original_quote ⇒ Object
37 |
# File 'lib/spatial_adapter/postgresql.rb', line 37 alias :original_quote :quote |
#original_remove_column ⇒ Object
95 |
# File 'lib/spatial_adapter/postgresql.rb', line 95 alias :original_remove_column :remove_column |
#postgis_major_version ⇒ Object
14 15 16 17 |
# File 'lib/spatial_adapter/postgresql.rb', line 14 def postgis_major_version version = postgis_version version ? version.scan(/^(\d)\.\d\.\d$/)[0][0].to_i : nil end |
#postgis_minor_version ⇒ Object
19 20 21 22 |
# File 'lib/spatial_adapter/postgresql.rb', line 19 def postgis_minor_version version = postgis_version version ? version.scan(/^\d\.(\d)\.\d$/)[0][0].to_i : nil end |
#postgis_version ⇒ Object
6 7 8 9 10 11 12 |
# File 'lib/spatial_adapter/postgresql.rb', line 6 def postgis_version begin select_value("SELECT postgis_full_version()").scan(/POSTGIS="([\d\.]*)"/)[0][0] rescue ActiveRecord::StatementInvalid nil end end |
#quote(value, column = nil) ⇒ Object
Redefines the quote method to add behaviour for when a Geometry is encountered
39 40 41 42 43 44 45 |
# File 'lib/spatial_adapter/postgresql.rb', line 39 def quote(value, column = nil) if value.kind_of?(GeoRuby::SimpleFeatures::Geometry) "'#{value.as_hex_ewkb}'" else original_quote(value,column) end end |
#remove_column(table_name, *column_names) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/spatial_adapter/postgresql.rb', line 96 def remove_column(table_name, *column_names) column_names = column_names.flatten columns(table_name).each do |col| if column_names.include?(col.name.to_sym) # Geometry columns have to be removed using DropGeometryColumn if col.is_a?(::SpatialAdapter::SpatialColumn) && col.spatial? && !col.geographic? execute "SELECT DropGeometryColumn('#{table_name}','#{col.name}')" else original_remove_column(table_name, col.name) end end end end |
#spatial? ⇒ Boolean
24 25 26 |
# File 'lib/spatial_adapter/postgresql.rb', line 24 def spatial? !postgis_version.nil? end |
#supports_geographic? ⇒ Boolean
28 29 30 |
# File 'lib/spatial_adapter/postgresql.rb', line 28 def supports_geographic? postgis_major_version > 1 || (postgis_major_version == 1 && postgis_minor_version >= 5) end |