spatial_adapter 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +3 -0
- data/README.rdoc +30 -17
- data/Rakefile +11 -0
- data/init.rb +1 -0
- data/lib/spatial_adapter/base/mysql/adapter.rb +54 -0
- data/lib/spatial_adapter/base/mysql/spatial_column.rb +12 -0
- data/lib/spatial_adapter/base/mysql.rb +9 -0
- data/lib/spatial_adapter/common/schema_dumper.rb +12 -12
- data/lib/spatial_adapter/common/spatial_column.rb +4 -4
- data/lib/spatial_adapter/common/table_definition.rb +8 -10
- data/lib/spatial_adapter/common.rb +10 -0
- data/lib/spatial_adapter/jdbcmysql.rb +50 -0
- data/lib/spatial_adapter/mysql.rb +43 -85
- data/lib/spatial_adapter/mysql2.rb +39 -86
- data/lib/spatial_adapter/postgresql.rb +315 -324
- data/lib/spatial_adapter/version.rb +3 -0
- data/lib/spatial_adapter.rb +3 -7
- data/spatial_adapter.gemspec +39 -0
- data/spec/db/jdbcmysql_raw.rb +70 -0
- data/spec/db/mysql2_raw.rb +9 -9
- data/spec/db/mysql_raw.rb +9 -9
- data/spec/jdbcmysql_spec.rb +25 -0
- data/spec/mysql2_spec.rb +31 -0
- data/spec/mysql_spec.rb +17 -0
- data/spec/postgresql/connection_adapter_spec.rb +34 -39
- data/spec/postgresql/migration_spec.rb +51 -51
- data/spec/postgresql/models_spec.rb +37 -37
- data/spec/postgresql/schema_dumper_spec.rb +12 -12
- data/spec/postgresql_spec.rb +5 -0
- data/spec/{shared_examples.rb → shared/common_model_actions_spec.rb} +2 -2
- data/spec/shared/mysql_connection_adapter_spec.rb +110 -0
- data/spec/{mysql/migration_spec.rb → shared/mysql_migration_spec.rb} +17 -17
- data/spec/shared/mysql_models_spec.rb +58 -0
- data/spec/{mysql/schema_dumper_spec.rb → shared/mysql_schema_dumper_spec.rb} +24 -27
- data/spec/spec_helper.rb +25 -21
- metadata +131 -84
- data/VERSION +0 -1
- data/spec/README.txt +0 -22
- data/spec/mysql/connection_adapter_spec.rb +0 -106
- data/spec/mysql/models_spec.rb +0 -65
- data/spec/mysql2/connection_adapter_spec.rb +0 -106
- data/spec/mysql2/migration_spec.rb +0 -64
- data/spec/mysql2/models_spec.rb +0 -65
- data/spec/mysql2/schema_dumper_spec.rb +0 -56
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
CHANGED
@@ -16,7 +16,7 @@ The following gems are required:
|
|
16
16
|
For PostgreSQL:
|
17
17
|
|
18
18
|
- PostGIS version 1.4.0 or higher should be installed in your database
|
19
|
-
|
19
|
+
|
20
20
|
== Installation
|
21
21
|
|
22
22
|
Choose ONE of the following installation methods. You shouldn't have to do both.
|
@@ -27,15 +27,15 @@ This is the preferred method of installation, and will pull in the required
|
|
27
27
|
dependencies as well.
|
28
28
|
|
29
29
|
gem install spatial_adapter
|
30
|
-
|
30
|
+
|
31
31
|
In a Rails 2.x app, you can add a gem dependency in environment.rb:
|
32
32
|
|
33
33
|
config.gem 'spatial_adapter'
|
34
|
-
|
34
|
+
|
35
35
|
In a Rails 3 app, add a gem dependency to Gemfile:
|
36
36
|
|
37
37
|
gem 'spatial_adapter'
|
38
|
-
|
38
|
+
|
39
39
|
=== As a Rails Plugin
|
40
40
|
|
41
41
|
In your Rails project, run the following:
|
@@ -50,18 +50,20 @@ Choose the database type for which you would like to use spatial_adapter, and
|
|
50
50
|
load each with
|
51
51
|
|
52
52
|
require 'spatial_adapter/[database]'
|
53
|
-
|
53
|
+
|
54
54
|
where [database] should be replaced with one of the following:
|
55
55
|
|
56
56
|
- postgresql
|
57
57
|
- mysql
|
58
|
-
|
58
|
+
- mysql2
|
59
|
+
- jdbcmysql
|
60
|
+
|
59
61
|
For example to use the PostgreSQL spatial adapter:
|
60
62
|
|
61
63
|
require 'spatial_adapter/postgresql'
|
62
|
-
|
63
|
-
In a Rails app, spatial_adapter will automatically load the adapter for the
|
64
|
-
specified in your database.yml configuration.
|
64
|
+
|
65
|
+
In a Rails app, spatial_adapter will automatically load the adapter for the
|
66
|
+
database specified in your database.yml configuration.
|
65
67
|
|
66
68
|
== Operations
|
67
69
|
|
@@ -73,13 +75,13 @@ and loaded in migrations the same way as columns of basic types.
|
|
73
75
|
|
74
76
|
Here is an example of code for the creation of a table with a geometric column
|
75
77
|
in PostGIS, along with the addition of a spatial index on the column:
|
76
|
-
|
78
|
+
|
77
79
|
ActiveRecord::Schema.define do
|
78
80
|
create_table :table_points, :force => true do |t|
|
79
81
|
t.string :data
|
80
82
|
t.point :geom, :null => false, :srid => 123, :with_z => true
|
81
83
|
end
|
82
|
-
|
84
|
+
|
83
85
|
add_index :table_points, :geom, :spatial => true
|
84
86
|
end
|
85
87
|
|
@@ -90,15 +92,15 @@ Here is a related statement valid for MySql version <= 5.0.16:
|
|
90
92
|
t.string :data
|
91
93
|
t.point :geom, :null => false
|
92
94
|
end
|
93
|
-
|
95
|
+
|
94
96
|
add_index :table_points, :geom, :spatial => true
|
95
97
|
end
|
96
|
-
|
98
|
+
|
97
99
|
=== Differences Between Databases
|
98
100
|
|
99
|
-
- On all versions of MySQL, the :srid, :with_z, and :with_m options are ignored,
|
100
|
-
they are not supported.
|
101
|
-
|
101
|
+
- On all versions of MySQL, the :srid, :with_z, and :with_m options are ignored,
|
102
|
+
since they are not supported.
|
103
|
+
|
102
104
|
- On MySQL versions <= 5.0.16, you have to add <tt>:options =>
|
103
105
|
"ENGINE=MyISAM"</tt> to the create_table statement, since only MyISAM tables
|
104
106
|
can have spatial columns. In addition, only MyISAM tables may have spatial
|
@@ -161,7 +163,7 @@ library (http://georuby.rubyforge.org/): This is where the
|
|
161
163
|
|
162
164
|
place = Place.find_first
|
163
165
|
place.the_geom.y=123456.7 # this doesn't work
|
164
|
-
|
166
|
+
|
165
167
|
Since the translation to a geometry is performed every time the_geom is read,
|
166
168
|
the change to y will not be saved! You would have to do something like this:
|
167
169
|
|
@@ -195,3 +197,14 @@ These will hopefully be added back in the near future.
|
|
195
197
|
|
196
198
|
Any questions, enhancement proposals, bug notifications or corrections can be
|
197
199
|
made via the project page at http://github.com/fragility/spatial_adapter
|
200
|
+
|
201
|
+
== Running Tests
|
202
|
+
|
203
|
+
The gem depdencencies can be installed with `bundle install`.
|
204
|
+
|
205
|
+
You will need to set up an empty database named `spatial_adapter` for each
|
206
|
+
adapter you want to test.
|
207
|
+
|
208
|
+
Tests are partitioned by adapter and can be run using separate rake task.
|
209
|
+
|
210
|
+
bundle exec rake spec:[adapter]
|
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
[:mysql, :mysql2, :jdbcmysql, :postgresql].each do |adapter|
|
7
|
+
desc "Run specs for #{adapter} adapter"
|
8
|
+
RSpec::Core::RakeTask.new("spec:#{adapter.to_s}") do |t|
|
9
|
+
t.pattern = "spec/#{adapter}_spec.rb"
|
10
|
+
end
|
11
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/rails/init"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module SpatialAdapter::Base::Mysql
|
2
|
+
module Adapter
|
3
|
+
GEOMETRY_REGEXP = /geometry|point|linestring|polygon|multipoint|multilinestring|multipolygon|geometrycollection/i
|
4
|
+
|
5
|
+
def supports_geographic?
|
6
|
+
false
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included klass
|
10
|
+
klass.class_eval do
|
11
|
+
def native_database_types
|
12
|
+
(defined?(NATIVE_DATABASE_TYPES) ? NATIVE_DATABASE_TYPES : super()) \
|
13
|
+
.merge(SpatialAdapter.geometry_data_types)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Redefines the quote method to add behaviour for when a Geometry is
|
17
|
+
# encountered ; used when binding variables in find_by methods
|
18
|
+
def quote(value, column = nil)
|
19
|
+
if value.kind_of?(GeoRuby::SimpleFeatures::Geometry)
|
20
|
+
"GeomFromWKB(0x#{value.as_hex_wkb},#{value.srid})"
|
21
|
+
else
|
22
|
+
super(value,column)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#Redefines add_index to support the case where the index is spatial
|
27
|
+
#If the :spatial key in the options table is true, then the sql string for a spatial index is created
|
28
|
+
def add_index(table_name,column_name,options = {})
|
29
|
+
index_name = options[:name] || index_name(table_name,:column => Array(column_name))
|
30
|
+
|
31
|
+
if options[:spatial]
|
32
|
+
execute "CREATE SPATIAL INDEX #{index_name} ON #{table_name} (#{Array(column_name).join(", ")})"
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def show_table_status_like(table)
|
43
|
+
execute("SHOW TABLE STATUS LIKE '#{table}'")
|
44
|
+
end
|
45
|
+
|
46
|
+
def show_fields_from(table, name = nil)
|
47
|
+
execute("SHOW FIELDS FROM #{quote_table_name(table)}", name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def show_keys_from(table, name = nil)
|
51
|
+
execute("SHOW KEYS FROM #{quote_table_name(table)}", name) || []
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module SpatialAdapter::Base::Mysql
|
2
|
+
module SpatialColumn
|
3
|
+
def string_to_geometry(string)
|
4
|
+
return string unless string.is_a?(String)
|
5
|
+
begin
|
6
|
+
GeoRuby::SimpleFeatures::Geometry.from_ewkb(string[4..-1])
|
7
|
+
rescue Exception => exception
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -3,7 +3,7 @@ ActiveRecord::SchemaDumper.ignore_tables << "spatial_ref_sys" << "geometry_colum
|
|
3
3
|
ActiveRecord::SchemaDumper.class_eval do
|
4
4
|
# These are the valid options for a column specification (spatial options added)
|
5
5
|
VALID_COLUMN_SPEC_KEYS = [:name, :limit, :precision, :scale, :default, :null, :srid, :with_z, :with_m, :geographic]
|
6
|
-
|
6
|
+
|
7
7
|
def table(table, stream)
|
8
8
|
columns = @connection.columns(table)
|
9
9
|
begin
|
@@ -15,7 +15,7 @@ ActiveRecord::SchemaDumper.class_eval do
|
|
15
15
|
elsif @connection.respond_to?(:primary_key)
|
16
16
|
pk = @connection.primary_key(table)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
tbl.print " create_table #{table.inspect}"
|
20
20
|
if columns.detect { |c| c.name == pk }
|
21
21
|
if pk != 'id'
|
@@ -24,13 +24,13 @@ ActiveRecord::SchemaDumper.class_eval do
|
|
24
24
|
else
|
25
25
|
tbl.print ", :id => false"
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
# Added by Spatial Adapter to ensure correct MySQL table engine
|
29
29
|
if @connection.respond_to?(:options_for)
|
30
30
|
res = @connection.options_for(table)
|
31
31
|
tbl.print ", :options=>'#{res}'" if res
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
tbl.print ", :force => true"
|
35
35
|
tbl.puts " do |t|"
|
36
36
|
|
@@ -69,7 +69,7 @@ ActiveRecord::SchemaDumper.class_eval do
|
|
69
69
|
|
70
70
|
tbl.puts " end"
|
71
71
|
tbl.puts
|
72
|
-
|
72
|
+
|
73
73
|
indexes(table, tbl)
|
74
74
|
|
75
75
|
tbl.rewind
|
@@ -79,10 +79,10 @@ ActiveRecord::SchemaDumper.class_eval do
|
|
79
79
|
stream.puts "# #{e.message}"
|
80
80
|
stream.puts
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
stream
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
|
87
87
|
def indexes(table, stream)
|
88
88
|
if (indexes = @connection.indexes(table)).any?
|
@@ -101,14 +101,14 @@ ActiveRecord::SchemaDumper.class_eval do
|
|
101
101
|
stream.puts
|
102
102
|
end
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
private
|
106
|
-
|
106
|
+
|
107
107
|
# Build specification for a table column
|
108
108
|
def column_spec(column)
|
109
109
|
spec = {}
|
110
110
|
spec[:name] = column.name.inspect
|
111
|
-
|
111
|
+
|
112
112
|
# AR has an optimisation which handles zero-scale decimals as integers. This
|
113
113
|
# code ensures that the dumper still dumps the column as a decimal.
|
114
114
|
spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) }
|
@@ -121,9 +121,9 @@ ActiveRecord::SchemaDumper.class_eval do
|
|
121
121
|
spec[:scale] = column.scale.inspect if !column.scale.nil?
|
122
122
|
spec[:null] = 'false' if !column.null
|
123
123
|
spec[:default] = default_string(column.default) if column.has_default?
|
124
|
-
|
124
|
+
|
125
125
|
# Additions for spatial columns
|
126
|
-
if column.is_a?(SpatialColumn)
|
126
|
+
if column.is_a?(::SpatialAdapter::SpatialColumn)
|
127
127
|
# Override with specific geometry type
|
128
128
|
spec[:type] = column.geometry_type.to_s
|
129
129
|
spec[:srid] = column.srid.inspect if column.srid != -1
|
@@ -9,11 +9,11 @@ module SpatialAdapter
|
|
9
9
|
@with_z = with_z
|
10
10
|
@with_m = with_m
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def spatial?
|
14
14
|
!@geometry_type.nil?
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def geographic?
|
18
18
|
false
|
19
19
|
end
|
@@ -25,9 +25,9 @@ module SpatialAdapter
|
|
25
25
|
spatial? ? self.class.string_to_geometry(value) : super
|
26
26
|
end
|
27
27
|
|
28
|
-
#Redefines type_cast_code to add support for geometries.
|
28
|
+
#Redefines type_cast_code to add support for geometries.
|
29
29
|
#
|
30
|
-
#WARNING : Since ActiveRecord keeps only the string values directly returned from the database, it translates from these to the correct types everytime an attribute is read (using the code returned by this method), which is probably ok for simple types, but might be less than efficient for geometries. Also you cannot modify the geometry object returned directly or your change will not be saved.
|
30
|
+
#WARNING : Since ActiveRecord keeps only the string values directly returned from the database, it translates from these to the correct types everytime an attribute is read (using the code returned by this method), which is probably ok for simple types, but might be less than efficient for geometries. Also you cannot modify the geometry object returned directly or your change will not be saved.
|
31
31
|
# alias_method :type_cast_code_without_spatial, :type_cast_code
|
32
32
|
def type_cast_code(var_name)
|
33
33
|
spatial? ? "#{self.class.name}.string_to_geometry(#{var_name})" : super
|
@@ -1,14 +1,12 @@
|
|
1
|
-
|
1
|
+
require 'spatial_adapter'
|
2
2
|
|
3
|
-
ActiveRecord::ConnectionAdapters::TableDefinition
|
4
|
-
SpatialAdapter.geometry_data_types.keys.each do |
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
column_names.each { |name| column(name, '#{column_type}', options) }
|
3
|
+
class ActiveRecord::ConnectionAdapters::TableDefinition
|
4
|
+
SpatialAdapter.geometry_data_types.keys.each do |column_name|
|
5
|
+
define_method(column_name) do |*args|
|
6
|
+
options = args.extract_options!
|
7
|
+
args.each do |name|
|
8
|
+
column(name, column_name, options)
|
11
9
|
end
|
12
|
-
|
10
|
+
end
|
13
11
|
end
|
14
12
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module SpatialAdapter
|
2
|
+
module Common
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'spatial_adapter/common/raw_geom_info'
|
7
|
+
require 'spatial_adapter/common/spatial_column'
|
8
|
+
require 'spatial_adapter/common/schema_definitions'
|
9
|
+
require 'spatial_adapter/common/schema_dumper'
|
10
|
+
require 'spatial_adapter/common/table_definition'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spatial_adapter'
|
2
|
+
require 'spatial_adapter/base/mysql'
|
3
|
+
require 'active_record/connection_adapters/jdbcmysql_adapter'
|
4
|
+
|
5
|
+
module ActiveRecord::ConnectionAdapters
|
6
|
+
class MysqlAdapter
|
7
|
+
include SpatialAdapter::Base::Mysql::Adapter
|
8
|
+
|
9
|
+
#Redefinition of columns to add the information that a column is geometric
|
10
|
+
def columns(table_name, name = nil)#:nodoc:
|
11
|
+
show_fields_from(table_name, name).map do |field|
|
12
|
+
klass = \
|
13
|
+
if field["Type"] =~ GEOMETRY_REGEXP
|
14
|
+
ActiveRecord::ConnectionAdapters::SpatialMysqlColumn
|
15
|
+
else
|
16
|
+
ActiveRecord::ConnectionAdapters::MysqlColumn
|
17
|
+
end
|
18
|
+
klass.new(field['Field'], field['Default'], field['Type'], field['Null'] == "YES")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Check the nature of the index : If it is SPATIAL, it is indicated in the
|
23
|
+
# IndexDefinition object (redefined to add the spatial flag in
|
24
|
+
# spatial_adapter_common.rb)
|
25
|
+
def indexes(table_name, name = nil)#:nodoc:
|
26
|
+
indexes = []
|
27
|
+
current_index = nil
|
28
|
+
show_keys_from(table_name, name).each do |row|
|
29
|
+
if current_index != row['Key_name']
|
30
|
+
next if row['Key_name'] == "PRIMARY" # skip the primary key
|
31
|
+
current_index = row['Key_name']
|
32
|
+
indexes << ActiveRecord::ConnectionAdapters::IndexDefinition \
|
33
|
+
.new(row['Table'], row['Key_name'], row['Non_unique'] == "0", [], row['Index_type'] == "SPATIAL")
|
34
|
+
end
|
35
|
+
indexes.last.columns << row['Column_name']
|
36
|
+
end
|
37
|
+
indexes
|
38
|
+
end
|
39
|
+
|
40
|
+
def options_for(table)
|
41
|
+
engine = show_table_status_like(table).first['Engine']
|
42
|
+
engine !~ /inno/i ? "ENGINE=#{engine}" : nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class SpatialMysqlColumn < MysqlColumn
|
47
|
+
include SpatialAdapter::SpatialColumn
|
48
|
+
extend SpatialAdapter::Base::Mysql::SpatialColumn
|
49
|
+
end
|
50
|
+
end
|
@@ -1,98 +1,56 @@
|
|
1
1
|
require 'spatial_adapter'
|
2
|
+
require 'spatial_adapter/base/mysql'
|
2
3
|
require 'active_record/connection_adapters/mysql_adapter'
|
3
4
|
|
4
|
-
ActiveRecord::ConnectionAdapters
|
5
|
-
|
5
|
+
module ActiveRecord::ConnectionAdapters
|
6
|
+
class MysqlAdapter
|
7
|
+
include SpatialAdapter::Base::Mysql::Adapter
|
8
|
+
|
9
|
+
#Redefinition of columns to add the information that a column is geometric
|
10
|
+
def columns(table_name, name = nil)#:nodoc:
|
11
|
+
result = show_fields_from(table_name, name)
|
12
|
+
|
13
|
+
columns = []
|
14
|
+
result.each do |field|
|
15
|
+
klass = \
|
16
|
+
if field[1] =~ GEOMETRY_REGEXP
|
17
|
+
ActiveRecord::ConnectionAdapters::SpatialMysqlColumn
|
18
|
+
else
|
19
|
+
ActiveRecord::ConnectionAdapters::MysqlColumn
|
20
|
+
end
|
21
|
+
columns << klass.new(field[0], field[4], field[1], field[2] == "YES")
|
22
|
+
end
|
6
23
|
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
alias :original_native_database_types :native_database_types
|
12
|
-
def native_database_types
|
13
|
-
original_native_database_types.merge!(geometry_data_types)
|
14
|
-
end
|
15
|
-
|
16
|
-
alias :original_quote :quote
|
17
|
-
#Redefines the quote method to add behaviour for when a Geometry is encountered ; used when binding variables in find_by methods
|
18
|
-
def quote(value, column = nil)
|
19
|
-
if value.kind_of?(GeoRuby::SimpleFeatures::Geometry)
|
20
|
-
"GeomFromWKB(0x#{value.as_hex_wkb},#{value.srid})"
|
21
|
-
else
|
22
|
-
original_quote(value,column)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
#Redefinition of columns to add the information that a column is geometric
|
27
|
-
def columns(table_name, name = nil)#:nodoc:
|
28
|
-
sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
|
29
|
-
columns = []
|
30
|
-
result = execute(sql, name)
|
31
|
-
result.each do |field|
|
32
|
-
klass = field[1] =~ /geometry|point|linestring|polygon|multipoint|multilinestring|multipolygon|geometrycollection/i ? ActiveRecord::ConnectionAdapters::SpatialMysqlColumn : ActiveRecord::ConnectionAdapters::MysqlColumn
|
33
|
-
columns << klass.new(field[0], field[4], field[1], field[2] == "YES")
|
24
|
+
result.free
|
25
|
+
columns
|
34
26
|
end
|
35
|
-
result.free
|
36
|
-
columns
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
#operations relative to migrations
|
41
27
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
indexes = []
|
57
|
-
current_index = nil
|
58
|
-
execute("SHOW KEYS FROM #{table_name}", name).each do |row|
|
59
|
-
if current_index != row[2]
|
60
|
-
next if row[2] == "PRIMARY" # skip the primary key
|
61
|
-
current_index = row[2]
|
62
|
-
indexes << ActiveRecord::ConnectionAdapters::IndexDefinition.new(row[0], row[2], row[1] == "0", [], row[10] == "SPATIAL")
|
28
|
+
# Check the nature of the index : If it is SPATIAL, it is indicated in the
|
29
|
+
# IndexDefinition object (redefined to add the spatial flag in
|
30
|
+
# spatial_adapter_common.rb)
|
31
|
+
def indexes(table_name, name = nil)#:nodoc:
|
32
|
+
indexes = []
|
33
|
+
current_index = nil
|
34
|
+
show_keys_from(table_name, name).each do |row|
|
35
|
+
if current_index != row[2]
|
36
|
+
next if row[2] == "PRIMARY" # skip the primary key
|
37
|
+
current_index = row[2]
|
38
|
+
indexes << ActiveRecord::ConnectionAdapters::IndexDefinition \
|
39
|
+
.new(row[0], row[2], row[1] == "0", [], row[10] == "SPATIAL")
|
40
|
+
end
|
41
|
+
indexes.last.columns << row[4]
|
63
42
|
end
|
64
|
-
indexes
|
43
|
+
indexes
|
65
44
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
def options_for(table)
|
71
|
-
result = execute("show table status like '#{table}'")
|
72
|
-
engine = result.fetch_row[1]
|
73
|
-
if engine !~ /inno/i #inno is default so do nothing for it in order not to clutter the migration
|
74
|
-
"ENGINE=#{engine}"
|
75
|
-
else
|
76
|
-
nil
|
45
|
+
|
46
|
+
def options_for(table)
|
47
|
+
engine = show_table_status_like(table).fetch_row[1]
|
48
|
+
engine !~ /inno/i ? "ENGINE=#{engine}" : nil
|
77
49
|
end
|
78
50
|
end
|
79
|
-
end
|
80
51
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
class SpatialMysqlColumn < MysqlColumn
|
85
|
-
include SpatialAdapter::SpatialColumn
|
86
|
-
|
87
|
-
#MySql-specific geometry string parsing. By default, MySql returns geometries in strict wkb format with "0" characters in the first 4 positions.
|
88
|
-
def self.string_to_geometry(string)
|
89
|
-
return string unless string.is_a?(String)
|
90
|
-
begin
|
91
|
-
GeoRuby::SimpleFeatures::Geometry.from_ewkb(string[4..-1])
|
92
|
-
rescue Exception => exception
|
93
|
-
nil
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
52
|
+
class SpatialMysqlColumn < MysqlColumn
|
53
|
+
include SpatialAdapter::SpatialColumn
|
54
|
+
extend SpatialAdapter::Base::Mysql::SpatialColumn
|
97
55
|
end
|
98
56
|
end
|