spatial_adapter 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -0,0 +1,110 @@
|
|
1
|
+
shared_examples_for 'a modified mysql adapter' do
|
2
|
+
let(:establish){ mysql_connection }
|
3
|
+
let(:column){ ActiveRecord::ConnectionAdapters::MysqlColumn }
|
4
|
+
let(:spatial_column){ ActiveRecord::ConnectionAdapters::SpatialMysqlColumn }
|
5
|
+
|
6
|
+
let(:connection) do
|
7
|
+
establish
|
8
|
+
ActiveRecord::Base.connection
|
9
|
+
end
|
10
|
+
|
11
|
+
context '#supports_geographic?' do
|
12
|
+
it "should be false" do
|
13
|
+
connection.supports_geographic?.should == false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "#columns" do
|
18
|
+
context "type" do
|
19
|
+
it "should be SpatialMysqlColumn if column is a spatial data type" do
|
20
|
+
PointModel.columns.select{|c| c.name == 'geom'} \
|
21
|
+
.first.should be_a(spatial_column)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be SpatialMysqlColumn if column is not a spatial data type" do
|
25
|
+
PointModel.columns.select{|c| c.name == 'extra'} \
|
26
|
+
.first.should be_a(column)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "@geometry_type" do
|
31
|
+
it "should be :point for columns restricted to POINT types" do
|
32
|
+
PointModel.columns.select{|c| c.name == 'geom'} \
|
33
|
+
.first.geometry_type.should == :point
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be :line_string for columns restricted to LINESTRING types" do
|
37
|
+
LineStringModel.columns.select{|c| c.name == 'geom'} \
|
38
|
+
.first.geometry_type.should == :line_string
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should be :polygon for columns restricted to POLYGON types" do
|
42
|
+
PolygonModel.columns.select{|c| c.name == 'geom'} \
|
43
|
+
.first.geometry_type.should == :polygon
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should be :multi_point for columns restricted to MULTIPOINT types" do
|
47
|
+
MultiPointModel.columns.select{|c| c.name == 'geom'} \
|
48
|
+
.first.geometry_type.should == :multi_point
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should be :multi_line_string for columns restricted to MULTILINESTRING types" do
|
52
|
+
MultiLineStringModel.columns.select{|c| c.name == 'geom'} \
|
53
|
+
.first.geometry_type.should == :multi_line_string
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be :multi_polygon for columns restricted to MULTIPOLYGON types" do
|
57
|
+
MultiPolygonModel.columns.select{|c| c.name == 'geom'} \
|
58
|
+
.first.geometry_type.should == :multi_polygon
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should be :geometry_collection for columns restricted to GEOMETRYCOLLECTION types" do
|
62
|
+
GeometryCollectionModel.columns.select{|c| c.name == 'geom'} \
|
63
|
+
.first.geometry_type.should == :geometry_collection
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should be :geometry for columns not restricted to a type" do
|
67
|
+
GeometryModel.columns.select{|c| c.name == 'geom'} \
|
68
|
+
.first.geometry_type.should == :geometry
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "#indexes" do
|
74
|
+
let(:indexes){ connection.indexes('point_models') }
|
75
|
+
|
76
|
+
it "should return an IndexDefinition for each index on the table" do
|
77
|
+
indexes.should have(2).items
|
78
|
+
indexes.each do |i|
|
79
|
+
i.should be_a(ActiveRecord::ConnectionAdapters::IndexDefinition)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should indicate the correct columns in the index" do
|
84
|
+
indexes.select{|i| i.name == 'index_point_models_on_geom'} \
|
85
|
+
.first.columns.should == ['geom']
|
86
|
+
indexes.select{|i| i.name == 'index_point_models_on_extra'} \
|
87
|
+
.first.columns.should == ['extra', 'more_extra']
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be marked as spatial if a spatial index" do
|
91
|
+
indexes.select{|i| i.columns.include?('geom')}.first.spatial.should == true
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should not be marked as spatial if not a spatial index" do
|
95
|
+
indexes.select{|i| i.columns.include?('extra')}.first.spatial.should == false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "#add_index" do
|
100
|
+
it "should create a spatial index given :spatial => true" do
|
101
|
+
connection.should_receive(:execute).with(/create spatial index/i)
|
102
|
+
connection.add_index('geometry_models', 'geom', :spatial => true)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should not create a spatial index unless specified" do
|
106
|
+
connection.should_not_receive(:execute).with(/create spatial index/i)
|
107
|
+
connection.add_index('geometry_models', 'extra')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -1,20 +1,19 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'spatial_adapter/mysql'
|
3
|
-
|
4
1
|
class MigratedGeometryModel < ActiveRecord::Base
|
5
2
|
end
|
6
3
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
shared_examples_for 'spatially enabled migrations' do
|
5
|
+
let(:establish){ mysql_connection }
|
6
|
+
|
7
|
+
let(:connection) do
|
8
|
+
establish
|
9
|
+
ActiveRecord::Base.connection
|
11
10
|
end
|
12
|
-
|
13
|
-
|
11
|
+
|
12
|
+
context "creating tables" do
|
14
13
|
after :each do
|
15
|
-
|
14
|
+
connection.drop_table "migrated_geometry_models"
|
16
15
|
end
|
17
|
-
|
16
|
+
|
18
17
|
SpatialAdapter.geometry_data_types.keys.each do |type|
|
19
18
|
it "should create #{type.to_s} columns" do
|
20
19
|
ActiveRecord::Schema.define do
|
@@ -24,7 +23,8 @@ describe "Spatially-enabled Migrations" do
|
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
27
|
-
geom_column =
|
26
|
+
geom_column = connection \
|
27
|
+
.columns(:migrated_geometry_models).select{|c| c.name == 'geom'}.first
|
28
28
|
geom_column.should be_a(SpatialAdapter::SpatialColumn)
|
29
29
|
geom_column.geometry_type.should == type
|
30
30
|
geom_column.type.should == :string
|
@@ -32,7 +32,7 @@ describe "Spatially-enabled Migrations" do
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
context "adding columns" do
|
36
36
|
before :each do
|
37
37
|
ActiveRecord::Schema.define do
|
38
38
|
create_table :migrated_geometry_models, :force => true do |t|
|
@@ -40,9 +40,9 @@ describe "Spatially-enabled Migrations" do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
after :each do
|
45
|
-
|
45
|
+
connection.drop_table "migrated_geometry_models"
|
46
46
|
end
|
47
47
|
|
48
48
|
SpatialAdapter.geometry_data_types.keys.each do |type|
|
@@ -51,7 +51,7 @@ describe "Spatially-enabled Migrations" do
|
|
51
51
|
add_column :migrated_geometry_models, :geom, type
|
52
52
|
end
|
53
53
|
|
54
|
-
geom_column =
|
54
|
+
geom_column = connection.columns(:migrated_geometry_models).select{|c| c.name == 'geom'}.first
|
55
55
|
geom_column.should be_a(SpatialAdapter::SpatialColumn)
|
56
56
|
geom_column.geometry_type.should == type
|
57
57
|
geom_column.type.should == :string
|
@@ -61,4 +61,4 @@ describe "Spatially-enabled Migrations" do
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
shared_examples_for 'spatially enabled models' do
|
2
|
+
let(:establish){ mysql_connection }
|
3
|
+
|
4
|
+
let(:connection) do
|
5
|
+
establish
|
6
|
+
ActiveRecord::Base.connection
|
7
|
+
end
|
8
|
+
|
9
|
+
context "inserting records" do
|
10
|
+
it 'should save Point objects' do
|
11
|
+
model = PointModel.new(:extra => 'test', :geom => GeometryFactory.point)
|
12
|
+
connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.point.as_hex_wkb), anything(), anything(), anything(), anything())
|
13
|
+
model.save.should == true
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should save LineString objects' do
|
17
|
+
model = LineStringModel.new(:extra => 'test', :geom => GeometryFactory.line_string)
|
18
|
+
connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.line_string.as_hex_wkb), anything(), anything(), anything(), anything())
|
19
|
+
model.save.should == true
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should save Polygon objects' do
|
23
|
+
model = PolygonModel.new(:extra => 'test', :geom => GeometryFactory.polygon)
|
24
|
+
connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.polygon.as_hex_wkb), anything(), anything(), anything(), anything())
|
25
|
+
model.save.should == true
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should save MultiPoint objects' do
|
29
|
+
model = MultiPointModel.new(:extra => 'test', :geom => GeometryFactory.multi_point)
|
30
|
+
connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_point.as_hex_wkb), anything(), anything(), anything(), anything())
|
31
|
+
model.save.should == true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should save MultiLineString objects' do
|
35
|
+
model = MultiLineStringModel.new(:extra => 'test', :geom => GeometryFactory.multi_line_string)
|
36
|
+
connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_line_string.as_hex_wkb), anything(), anything(), anything(), anything())
|
37
|
+
model.save.should == true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should save MultiPolygon objects' do
|
41
|
+
model = MultiPolygonModel.new(:extra => 'test', :geom => GeometryFactory.multi_polygon)
|
42
|
+
connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_polygon.as_hex_wkb), anything(), anything(), anything(), anything())
|
43
|
+
model.save.should == true
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should save GeometryCollection objects' do
|
47
|
+
model = GeometryCollectionModel.new(:extra => 'test', :geom => GeometryFactory.geometry_collection)
|
48
|
+
connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.geometry_collection.as_hex_wkb), anything(), anything(), anything(), anything())
|
49
|
+
model.save.should == true
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should save Geometry objects' do
|
53
|
+
model = GeometryModel.new(:extra => 'test', :geom => GeometryFactory.point)
|
54
|
+
connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.point.as_hex_wkb), anything(), anything(), anything(), anything())
|
55
|
+
model.save.should == true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,56 +1,53 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
shared_examples_for 'spatially enabled schema dump' do
|
2
|
+
let(:establish){ mysql_connection }
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
let(:connection) do
|
5
|
+
establish
|
6
|
+
ActiveRecord::Base.connection
|
7
|
+
end
|
8
8
|
|
9
|
-
|
9
|
+
before :all do
|
10
10
|
ActiveRecord::Schema.define do
|
11
11
|
create_table :migrated_geometry_models, :options=> "ENGINE=MyISAM", :force => true do |t|
|
12
12
|
t.integer :extra
|
13
13
|
t.point :geom, :null => false
|
14
14
|
end
|
15
|
-
add_index :migrated_geometry_models, :geom, :spatial => true,
|
15
|
+
add_index :migrated_geometry_models, :geom, :spatial => true,
|
16
|
+
:name => 'test_spatial_index'
|
16
17
|
end
|
17
18
|
|
18
|
-
File.open('schema.rb', "w") do |file|
|
19
|
-
ActiveRecord::SchemaDumper.dump(
|
19
|
+
File.open('schema.rb', "w:UTF-8") do |file|
|
20
|
+
ActiveRecord::SchemaDumper.dump(connection, file)
|
20
21
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# Load the dumped schema
|
22
|
+
|
23
|
+
connection.drop_table "migrated_geometry_models"
|
24
|
+
|
26
25
|
load('schema.rb')
|
27
26
|
end
|
28
|
-
|
27
|
+
|
29
28
|
after :all do
|
30
|
-
# delete the schema file
|
31
29
|
File.delete('schema.rb')
|
32
30
|
|
33
|
-
|
34
|
-
@connection.drop_table "migrated_geometry_models"
|
31
|
+
connection.drop_table "migrated_geometry_models"
|
35
32
|
end
|
36
|
-
|
33
|
+
|
37
34
|
it "should preserve spatial attributes of tables" do
|
38
|
-
columns =
|
39
|
-
|
35
|
+
columns = connection.columns("migrated_geometry_models")
|
36
|
+
|
40
37
|
columns.should have(3).items
|
41
38
|
geom_column = columns.select{|c| c.name == 'geom'}.first
|
42
39
|
geom_column.should be_a(SpatialAdapter::SpatialColumn)
|
43
40
|
geom_column.geometry_type.should == :point
|
44
41
|
geom_column.type.should == :string
|
45
42
|
end
|
46
|
-
|
43
|
+
|
47
44
|
it "should preserve spatial indexes" do
|
48
|
-
indexes =
|
49
|
-
|
45
|
+
indexes = connection.indexes("migrated_geometry_models")
|
46
|
+
|
50
47
|
indexes.should have(1).item
|
51
|
-
|
48
|
+
|
52
49
|
indexes.first.name.should == 'test_spatial_index'
|
53
50
|
indexes.first.columns.should == ["geom"]
|
54
51
|
indexes.first.spatial.should == true
|
55
52
|
end
|
56
|
-
end
|
53
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
require
|
3
|
-
require 'geo_ruby'
|
4
|
-
gem 'activerecord', '=3.0.3'
|
5
|
-
require 'active_record'
|
6
|
-
|
7
|
-
$:.unshift((File.join(File.dirname(__FILE__), '..', 'lib')))
|
8
|
-
|
9
|
-
include GeoRuby::SimpleFeatures
|
10
|
-
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.require(:default)
|
11
3
|
|
12
4
|
def postgis_connection
|
13
5
|
ActiveRecord::Base.establish_connection(
|
@@ -28,7 +20,7 @@ def mysql_connection
|
|
28
20
|
:username => 'root',
|
29
21
|
:host => 'localhost'
|
30
22
|
)
|
31
|
-
|
23
|
+
|
32
24
|
# Don't output migration logging
|
33
25
|
ActiveRecord::Migration.verbose = false
|
34
26
|
end
|
@@ -40,7 +32,19 @@ def mysql2_connection
|
|
40
32
|
:username => 'root',
|
41
33
|
:host => 'localhost'
|
42
34
|
)
|
43
|
-
|
35
|
+
|
36
|
+
# Don't output migration logging
|
37
|
+
ActiveRecord::Migration.verbose = false
|
38
|
+
end
|
39
|
+
|
40
|
+
def jdbcmysql_connection
|
41
|
+
ActiveRecord::Base.establish_connection(
|
42
|
+
:adapter => 'jdbcmysql',
|
43
|
+
:database => 'spatial_adapter',
|
44
|
+
:username => 'root',
|
45
|
+
:host => 'localhost'
|
46
|
+
)
|
47
|
+
|
44
48
|
# Don't output migration logging
|
45
49
|
ActiveRecord::Migration.verbose = false
|
46
50
|
end
|
@@ -50,39 +54,39 @@ class GeometryFactory
|
|
50
54
|
def point
|
51
55
|
Point.from_x_y(1, 2, 4326)
|
52
56
|
end
|
53
|
-
|
57
|
+
|
54
58
|
def line_string
|
55
59
|
LineString.from_coordinates([[1.4,2.5],[1.5,6.7]], 4326)
|
56
60
|
end
|
57
|
-
|
61
|
+
|
58
62
|
def polygon
|
59
63
|
Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]], 4326)
|
60
64
|
end
|
61
|
-
|
65
|
+
|
62
66
|
def multi_point
|
63
67
|
MultiPoint.from_coordinates([[12.4,-23.3],[-65.1,23.4],[23.55555555,23]], 4326)
|
64
68
|
end
|
65
|
-
|
69
|
+
|
66
70
|
def multi_line_string
|
67
71
|
MultiLineString.from_line_strings([LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012]]),LineString.from_coordinates([[1.5,45.2],[-54.12312,-0.012],[45.123,23.3]])], 4326)
|
68
72
|
end
|
69
|
-
|
73
|
+
|
70
74
|
def multi_polygon
|
71
75
|
MultiPolygon.from_polygons([Polygon.from_coordinates([[[12.4,-45.3],[45.4,41.6],[4.456,1.0698],[12.4,-45.3]],[[2.4,5.3],[5.4,1.4263],[14.46,1.06],[2.4,5.3]]]),Polygon.from_coordinates([[[0,0],[4,0],[4,4],[0,4],[0,0]],[[1,1],[3,1],[3,3],[1,3],[1,1]]])], 4326)
|
72
76
|
end
|
73
|
-
|
77
|
+
|
74
78
|
def geometry_collection
|
75
79
|
GeometryCollection.from_geometries([Point.from_x_y(4.67,45.4),LineString.from_coordinates([[5.7,12.45],[67.55,54]])], 4326)
|
76
80
|
end
|
77
|
-
|
81
|
+
|
78
82
|
def pointz
|
79
83
|
Point.from_x_y_z(1, 2, 3, 4326)
|
80
84
|
end
|
81
|
-
|
85
|
+
|
82
86
|
def pointm
|
83
87
|
Point.from_x_y_m(1, 2, 3, 4326)
|
84
88
|
end
|
85
|
-
|
89
|
+
|
86
90
|
def point4
|
87
91
|
Point.from_x_y_z_m(1, 2, 3, 4, 4326)
|
88
92
|
end
|