spatial_adapter 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'db/mysql_raw'
3
+ require 'models/common'
4
+
5
+ describe "Modified MysqlAdapter" do
6
+ before :each do
7
+ mysql_connection
8
+ @connection = ActiveRecord::Base.connection
9
+ end
10
+
11
+ describe '#supports_geography?' do
12
+ it "should be false" do
13
+ @connection.supports_geography?.should == false
14
+ end
15
+ end
16
+
17
+ describe "#columns" do
18
+ describe "type" do
19
+ it "should be SpatialMysqlColumn if column is a spatial data type" do
20
+ PointModel.columns.select{|c| c.name == 'geom'}.first.should be_a(ActiveRecord::ConnectionAdapters::SpatialMysqlColumn)
21
+ end
22
+
23
+ it "should be SpatialMysqlColumn if column is not a spatial data type" do
24
+ PointModel.columns.select{|c| c.name == 'extra'}.first.should be_a(ActiveRecord::ConnectionAdapters::MysqlColumn)
25
+ end
26
+ end
27
+
28
+ describe "@geometry_type" do
29
+ it "should be :point for columns restricted to POINT types" do
30
+ PointModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :point
31
+ end
32
+
33
+ it "should be :line_string for columns restricted to LINESTRING types" do
34
+ LineStringModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :line_string
35
+ end
36
+
37
+ it "should be :polygon for columns restricted to POLYGON types" do
38
+ PolygonModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :polygon
39
+ end
40
+
41
+ it "should be :multi_point for columns restricted to MULTIPOINT types" do
42
+ MultiPointModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_point
43
+ end
44
+
45
+ it "should be :multi_line_string for columns restricted to MULTILINESTRING types" do
46
+ MultiLineStringModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_line_string
47
+ end
48
+
49
+ it "should be :multi_polygon for columns restricted to MULTIPOLYGON types" do
50
+ MultiPolygonModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_polygon
51
+ end
52
+
53
+ it "should be :geometry_collection for columns restricted to GEOMETRYCOLLECTION types" do
54
+ GeometryCollectionModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :geometry_collection
55
+ end
56
+
57
+ it "should be :geometry for columns not restricted to a type" do
58
+ GeometryModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :geometry
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "#indexes" do
64
+ before :each do
65
+ @indexes = @connection.indexes('point_models')
66
+ end
67
+
68
+ it "should be marked as spatial if a spatial index" do
69
+ @indexes.select{|i| i.columns.include?('geom')}.first.spatial.should == true
70
+ end
71
+
72
+ it "should not be marked as spatial if not a spatial index" do
73
+ @indexes.select{|i| i.columns.include?('extra')}.first.spatial.should == false
74
+ end
75
+ end
76
+
77
+ describe "#add_index" do
78
+ after :each do
79
+ @connection.should_receive(:execute).with(any_args())
80
+ @connection.remove_index('geometry_models', 'geom')
81
+ end
82
+
83
+ it "should create a spatial index given :spatial => true" do
84
+ @connection.should_receive(:execute).with(/create spatial index/i)
85
+ @connection.add_index('geometry_models', 'geom', :spatial => true)
86
+ end
87
+
88
+ it "should not create a spatial index unless specified" do
89
+ @connection.should_not_receive(:execute).with(/create spatial index/i)
90
+ @connection.add_index('geometry_models', 'extra')
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,63 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class MigratedGeometryModel < ActiveRecord::Base
4
+ end
5
+
6
+ describe "Spatially-enabled Migrations" do
7
+ before :each do
8
+ mysql_connection
9
+ @connection = ActiveRecord::Base.connection
10
+ end
11
+
12
+ describe "creating tables" do
13
+ after :each do
14
+ @connection.drop_table "migrated_geometry_models"
15
+ end
16
+
17
+ SpatialAdapter.geometry_data_types.keys.each do |type|
18
+ it "should create #{type.to_s} columns" do
19
+ ActiveRecord::Schema.define do
20
+ create_table :migrated_geometry_models, :force => true do |t|
21
+ t.integer :extra
22
+ t.send(type, :geom)
23
+ end
24
+ end
25
+
26
+ geom_column = @connection.columns(:migrated_geometry_models).select{|c| c.name == 'geom'}.first
27
+ geom_column.should be_a(SpatialAdapter::SpatialColumn)
28
+ geom_column.geometry_type.should == type
29
+ geom_column.type.should == :geometry
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "adding columns" do
35
+ before :each do
36
+ ActiveRecord::Schema.define do
37
+ create_table :migrated_geometry_models, :force => true do |t|
38
+ t.integer :extra
39
+ end
40
+ end
41
+ end
42
+
43
+ after :each do
44
+ @connection.drop_table "migrated_geometry_models"
45
+ end
46
+
47
+ SpatialAdapter.geometry_data_types.keys.each do |type|
48
+ it "should add #{type.to_s} columns" do
49
+ ActiveRecord::Schema.define do
50
+ add_column :migrated_geometry_models, :geom, type
51
+ end
52
+
53
+ geom_column = @connection.columns(:migrated_geometry_models).select{|c| c.name == 'geom'}.first
54
+ geom_column.should be_a(SpatialAdapter::SpatialColumn)
55
+ geom_column.geometry_type.should == type
56
+ geom_column.type.should == :geometry
57
+ geom_column.with_z.should == false
58
+ geom_column.with_m.should == false
59
+ geom_column.srid.should == -1
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,103 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'db/mysql_raw'
3
+ require 'models/common'
4
+
5
+ describe "Spatially-enabled Models" do
6
+ before :each do
7
+ mysql_connection
8
+ @connection = ActiveRecord::Base.connection
9
+ end
10
+
11
+ describe "inserting records" do
12
+ it 'should save Point objects' do
13
+ model = PointModel.new(:extra => 'test', :geom => GeometryFactory.point)
14
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.point.as_hex_wkb), anything(), anything(), anything(), anything())
15
+ model.save.should == true
16
+ end
17
+
18
+ it 'should save LineString objects' do
19
+ model = LineStringModel.new(:extra => 'test', :geom => GeometryFactory.line_string)
20
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.line_string.as_hex_wkb), anything(), anything(), anything(), anything())
21
+ model.save.should == true
22
+ end
23
+
24
+ it 'should save Polygon objects' do
25
+ model = PolygonModel.new(:extra => 'test', :geom => GeometryFactory.polygon)
26
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.polygon.as_hex_wkb), anything(), anything(), anything(), anything())
27
+ model.save.should == true
28
+ end
29
+
30
+ it 'should save MultiPoint objects' do
31
+ model = MultiPointModel.new(:extra => 'test', :geom => GeometryFactory.multi_point)
32
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_point.as_hex_wkb), anything(), anything(), anything(), anything())
33
+ model.save.should == true
34
+ end
35
+
36
+ it 'should save MultiLineString objects' do
37
+ model = MultiLineStringModel.new(:extra => 'test', :geom => GeometryFactory.multi_line_string)
38
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_line_string.as_hex_wkb), anything(), anything(), anything(), anything())
39
+ model.save.should == true
40
+ end
41
+
42
+ it 'should save MultiPolygon objects' do
43
+ model = MultiPolygonModel.new(:extra => 'test', :geom => GeometryFactory.multi_polygon)
44
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_polygon.as_hex_wkb), anything(), anything(), anything(), anything())
45
+ model.save.should == true
46
+ end
47
+
48
+ it 'should save GeometryCollection objects' do
49
+ model = GeometryCollectionModel.new(:extra => 'test', :geom => GeometryFactory.geometry_collection)
50
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.geometry_collection.as_hex_wkb), anything(), anything(), anything(), anything())
51
+ model.save.should == true
52
+ end
53
+
54
+ it 'should save Geometry objects' do
55
+ model = GeometryModel.new(:extra => 'test', :geom => GeometryFactory.point)
56
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.point.as_hex_wkb), anything(), anything(), anything(), anything())
57
+ model.save.should == true
58
+ end
59
+ end
60
+
61
+ describe "finding records" do
62
+ it 'should retrieve Point objects' do
63
+ model = PointModel.create(:extra => 'test', :geom => GeometryFactory.point)
64
+ PointModel.find(model.id).geom.should == GeometryFactory.point
65
+ end
66
+
67
+ it 'should retrieve LineString objects' do
68
+ model = LineStringModel.create(:extra => 'test', :geom => GeometryFactory.line_string)
69
+ LineStringModel.find(model.id).geom.should == GeometryFactory.line_string
70
+ end
71
+
72
+ it 'should retrieve Polygon objects' do
73
+ model = PolygonModel.create(:extra => 'test', :geom => GeometryFactory.polygon)
74
+ PolygonModel.find(model.id).geom.should == GeometryFactory.polygon
75
+ end
76
+
77
+ it 'should retrieve MultiPoint objects' do
78
+ model = MultiPointModel.create(:extra => 'test', :geom => GeometryFactory.multi_point)
79
+ MultiPointModel.find(model.id).geom.should == GeometryFactory.multi_point
80
+ end
81
+
82
+ it 'should retrieve MultiLineString objects' do
83
+ model = MultiLineStringModel.create(:extra => 'test', :geom => GeometryFactory.multi_line_string)
84
+ MultiLineStringModel.find(model.id).geom.should == GeometryFactory.multi_line_string
85
+ end
86
+
87
+ it 'should retrieve MultiPolygon objects' do
88
+ model = MultiPolygonModel.create(:extra => 'test', :geom => GeometryFactory.multi_polygon)
89
+ MultiPolygonModel.find(model.id).geom.should == GeometryFactory.multi_polygon
90
+ end
91
+
92
+ it 'should retrieve GeometryCollection objects' do
93
+ model = GeometryCollectionModel.create(:extra => 'test', :geom => GeometryFactory.geometry_collection)
94
+ GeometryCollectionModel.find(model.id).geom.should == GeometryFactory.geometry_collection
95
+ end
96
+
97
+ it 'should retrieve Geometry objects' do
98
+ model = GeometryModel.create(:extra => 'test', :geom => GeometryFactory.point)
99
+ GeometryModel.find(model.id).geom.should == GeometryFactory.point
100
+ end
101
+ end
102
+ end
103
+
@@ -0,0 +1,55 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Spatially-enabled Schema Dumps" do
4
+ before :all do
5
+ mysql_connection
6
+ @connection = ActiveRecord::Base.connection
7
+
8
+ # Create a new table
9
+ ActiveRecord::Schema.define do
10
+ create_table :migrated_geometry_models, :options=> "ENGINE=MyISAM", :force => true do |t|
11
+ t.integer :extra
12
+ t.point :geom, :null => false
13
+ end
14
+ add_index :migrated_geometry_models, :geom, :spatial => true, :name => 'test_spatial_index'
15
+ end
16
+
17
+ File.open('schema.rb', "w") do |file|
18
+ ActiveRecord::SchemaDumper.dump(@connection, file)
19
+ end
20
+
21
+ # Drop the original table
22
+ @connection.drop_table "migrated_geometry_models"
23
+
24
+ # Load the dumped schema
25
+ load('schema.rb')
26
+ end
27
+
28
+ after :all do
29
+ # delete the schema file
30
+ File.delete('schema.rb')
31
+
32
+ # Drop the new table
33
+ @connection.drop_table "migrated_geometry_models"
34
+ end
35
+
36
+ it "should preserve spatial attributes of tables" do
37
+ columns = @connection.columns("migrated_geometry_models")
38
+
39
+ columns.should have(3).items
40
+ geom_column = columns.select{|c| c.name == 'geom'}.first
41
+ geom_column.should be_a(SpatialAdapter::SpatialColumn)
42
+ geom_column.geometry_type.should == :point
43
+ geom_column.type.should == :geometry
44
+ end
45
+
46
+ it "should preserve spatial indexes" do
47
+ indexes = @connection.indexes("migrated_geometry_models")
48
+
49
+ indexes.should have(1).item
50
+
51
+ indexes.first.name.should == 'test_spatial_index'
52
+ indexes.first.columns.should == ["geom"]
53
+ indexes.first.spatial.should == true
54
+ end
55
+ end
@@ -0,0 +1,152 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'db/postgis_raw'
3
+ require 'models/common'
4
+
5
+ describe "Modified PostgreSQLAdapter" do
6
+ before :each do
7
+ postgis_connection
8
+ @connection = ActiveRecord::Base.connection
9
+ end
10
+
11
+ describe '#postgis_version' do
12
+ it 'should report a version number if PostGIS is installed' do
13
+ @connection.should_receive(:select_value).with('SELECT postgis_full_version()').and_return('POSTGIS="1.5.0" GEOS="3.2.0-CAPI-1.6.0" PROJ="Rel. 4.7.1, 23 September 2009" LIBXML="2.7.6" USE_STATS')
14
+ @connection.postgis_version.should_not be_nil
15
+ end
16
+
17
+ it 'should report nil if PostGIS is not installed' do
18
+ @connection.should_receive(:select_value).with('SELECT postgis_full_version()').and_raise(ActiveRecord::StatementInvalid)
19
+ @connection.postgis_version.should be_nil
20
+ end
21
+ end
22
+
23
+ describe '#postgis_major_version' do
24
+ it 'should be the first component of the version number' do
25
+ @connection.stub!(:postgis_version).and_return('1.5.0')
26
+ @connection.postgis_major_version.should == 1
27
+ end
28
+
29
+ it 'should be nil if PostGIS is not installed' do
30
+ @connection.stub!(:postgis_version).and_return(nil)
31
+ @connection.postgis_major_version.should be_nil
32
+ end
33
+ end
34
+
35
+ describe '#postgis_minor_version' do
36
+ it 'should be the second component of the version number' do
37
+ @connection.stub!(:postgis_version).and_return('1.5.0')
38
+ @connection.postgis_minor_version.should == 5
39
+ end
40
+
41
+ it 'should be nil if PostGIS is not installed' do
42
+ @connection.stub!(:postgis_version).and_return(nil)
43
+ @connection.postgis_minor_version.should be_nil
44
+ end
45
+ end
46
+
47
+ describe '#spatial?' do
48
+ it 'should be true if PostGIS is installed' do
49
+ @connection.should_receive(:select_value).with('SELECT postgis_full_version()').and_return('POSTGIS="1.5.0" GEOS="3.2.0-CAPI-1.6.0" PROJ="Rel. 4.7.1, 23 September 2009" LIBXML="2.7.6" USE_STATS')
50
+ @connection.should be_spatial
51
+ end
52
+
53
+ it 'should be false if PostGIS is not installed' do
54
+ @connection.should_receive(:select_value).with('SELECT postgis_full_version()').and_raise(ActiveRecord::StatementInvalid)
55
+ @connection.should_not be_spatial
56
+ end
57
+ end
58
+
59
+ describe '#supports_geography?' do
60
+ it "should be true for PostGIS version 1.5.0" do
61
+ @connection.stub!(:postgis_version).and_return('1.5.0')
62
+ @connection.supports_geography?.should == true
63
+ end
64
+
65
+ it "should be true for PostGIS newer than 1.5.0" do
66
+ @connection.stub!(:postgis_version).and_return('1.5.1')
67
+ @connection.supports_geography?.should == true
68
+ end
69
+
70
+ it "should be true for PostGIS older than 1.5.0" do
71
+ @connection.stub!(:postgis_version).and_return('1.4.0')
72
+ @connection.supports_geography?.should == false
73
+ end
74
+ end
75
+
76
+ describe "#columns" do
77
+ describe "type" do
78
+ it "should be SpatialPostgreSQLColumn if column is a spatial data type" do
79
+ PointModel.columns.select{|c| c.name == 'geom'}.first.should be_a(ActiveRecord::ConnectionAdapters::SpatialPostgreSQLColumn)
80
+ end
81
+
82
+ it "should be PostgreSQLColumn if column is not a spatial data type" do
83
+ PointModel.columns.select{|c| c.name == 'extra'}.first.should be_a(ActiveRecord::ConnectionAdapters::PostgreSQLColumn)
84
+ end
85
+ end
86
+
87
+ describe "@geometry_type" do
88
+ it "should be :point for columns restricted to POINT types" do
89
+ PointModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :point
90
+ end
91
+
92
+ it "should be :line_string for columns restricted to LINESTRING types" do
93
+ LineStringModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :line_string
94
+ end
95
+
96
+ it "should be :polygon for columns restricted to POLYGON types" do
97
+ PolygonModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :polygon
98
+ end
99
+
100
+ it "should be :multi_point for columns restricted to MULTIPOINT types" do
101
+ MultiPointModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_point
102
+ end
103
+
104
+ it "should be :multi_line_string for columns restricted to MULTILINESTRING types" do
105
+ MultiLineStringModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_line_string
106
+ end
107
+
108
+ it "should be :multi_polygon for columns restricted to MULTIPOLYGON types" do
109
+ MultiPolygonModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_polygon
110
+ end
111
+
112
+ it "should be :geometry_collection for columns restricted to GEOMETRYCOLLECTION types" do
113
+ GeometryCollectionModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :geometry_collection
114
+ end
115
+
116
+ it "should be :geometry for columns not restricted to a type" do
117
+ GeometryModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :geometry
118
+ end
119
+ end
120
+ end
121
+
122
+ describe "#indexes" do
123
+ before :each do
124
+ @indexes = @connection.indexes('point_models', 'index_point_models_on_geom')
125
+ end
126
+
127
+ it "should be marked as spatial if a GIST index" do
128
+ @indexes.select{|i| i.columns.include?('geom')}.first.spatial.should == true
129
+ end
130
+
131
+ it "should not be marked as spatial if not a GIST index" do
132
+ @indexes.select{|i| i.columns.include?('extra')}.first.spatial.should == false
133
+ end
134
+ end
135
+
136
+ describe "#add_index" do
137
+ after :each do
138
+ @connection.should_receive(:execute).with(any_args())
139
+ @connection.remove_index('geometry_models', 'geom')
140
+ end
141
+
142
+ it "should create a spatial index given :spatial => true" do
143
+ @connection.should_receive(:execute).with(/using gist/i)
144
+ @connection.add_index('geometry_models', 'geom', :spatial => true)
145
+ end
146
+
147
+ it "should not create a spatial index unless specified" do
148
+ @connection.should_not_receive(:execute).with(/using gist/i)
149
+ @connection.add_index('geometry_models', 'extra')
150
+ end
151
+ end
152
+ end