achirkunov-spatial_adapter 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'spatial_adapter/mysql'
3
+
4
+ class MigratedGeometryModel < ActiveRecord::Base
5
+ end
6
+
7
+ describe "Spatially-enabled Migrations" do
8
+ before :each do
9
+ mysql_connection
10
+ @connection = ActiveRecord::Base.connection
11
+ end
12
+
13
+ describe "creating tables" do
14
+ after :each do
15
+ @connection.drop_table "migrated_geometry_models"
16
+ end
17
+
18
+ SpatialAdapter.geometry_data_types.keys.each do |type|
19
+ it "should create #{type.to_s} columns" do
20
+ ActiveRecord::Schema.define do
21
+ create_table :migrated_geometry_models, :force => true do |t|
22
+ t.integer :extra
23
+ t.send(type, :geom)
24
+ end
25
+ end
26
+
27
+ geom_column = @connection.columns(:migrated_geometry_models).select{|c| c.name == 'geom'}.first
28
+ geom_column.should be_a(SpatialAdapter::SpatialColumn)
29
+ geom_column.geometry_type.should == type
30
+ geom_column.type.should == :geometry
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "adding columns" do
36
+ before :each do
37
+ ActiveRecord::Schema.define do
38
+ create_table :migrated_geometry_models, :force => true do |t|
39
+ t.integer :extra
40
+ end
41
+ end
42
+ end
43
+
44
+ after :each do
45
+ @connection.drop_table "migrated_geometry_models"
46
+ end
47
+
48
+ SpatialAdapter.geometry_data_types.keys.each do |type|
49
+ it "should add #{type.to_s} columns" do
50
+ ActiveRecord::Schema.define do
51
+ add_column :migrated_geometry_models, :geom, type
52
+ end
53
+
54
+ geom_column = @connection.columns(:migrated_geometry_models).select{|c| c.name == 'geom'}.first
55
+ geom_column.should be_a(SpatialAdapter::SpatialColumn)
56
+ geom_column.geometry_type.should == type
57
+ geom_column.type.should == :geometry
58
+ geom_column.with_z.should == false
59
+ geom_column.with_m.should == false
60
+ geom_column.srid.should == -1
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,104 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'spatial_adapter/mysql'
3
+ require 'db/mysql_raw'
4
+ require 'models/common'
5
+
6
+ describe "Spatially-enabled Models" do
7
+ before :each do
8
+ mysql_connection
9
+ @connection = ActiveRecord::Base.connection
10
+ end
11
+
12
+ describe "inserting records" do
13
+ it 'should save Point objects' do
14
+ model = PointModel.new(:extra => 'test', :geom => GeometryFactory.point)
15
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.point.as_hex_wkb), anything(), anything(), anything(), anything())
16
+ model.save.should == true
17
+ end
18
+
19
+ it 'should save LineString objects' do
20
+ model = LineStringModel.new(:extra => 'test', :geom => GeometryFactory.line_string)
21
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.line_string.as_hex_wkb), anything(), anything(), anything(), anything())
22
+ model.save.should == true
23
+ end
24
+
25
+ it 'should save Polygon objects' do
26
+ model = PolygonModel.new(:extra => 'test', :geom => GeometryFactory.polygon)
27
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.polygon.as_hex_wkb), anything(), anything(), anything(), anything())
28
+ model.save.should == true
29
+ end
30
+
31
+ it 'should save MultiPoint objects' do
32
+ model = MultiPointModel.new(:extra => 'test', :geom => GeometryFactory.multi_point)
33
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_point.as_hex_wkb), anything(), anything(), anything(), anything())
34
+ model.save.should == true
35
+ end
36
+
37
+ it 'should save MultiLineString objects' do
38
+ model = MultiLineStringModel.new(:extra => 'test', :geom => GeometryFactory.multi_line_string)
39
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_line_string.as_hex_wkb), anything(), anything(), anything(), anything())
40
+ model.save.should == true
41
+ end
42
+
43
+ it 'should save MultiPolygon objects' do
44
+ model = MultiPolygonModel.new(:extra => 'test', :geom => GeometryFactory.multi_polygon)
45
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.multi_polygon.as_hex_wkb), anything(), anything(), anything(), anything())
46
+ model.save.should == true
47
+ end
48
+
49
+ it 'should save GeometryCollection objects' do
50
+ model = GeometryCollectionModel.new(:extra => 'test', :geom => GeometryFactory.geometry_collection)
51
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.geometry_collection.as_hex_wkb), anything(), anything(), anything(), anything())
52
+ model.save.should == true
53
+ end
54
+
55
+ it 'should save Geometry objects' do
56
+ model = GeometryModel.new(:extra => 'test', :geom => GeometryFactory.point)
57
+ @connection.should_receive(:insert_sql).with(Regexp.new(GeometryFactory.point.as_hex_wkb), anything(), anything(), anything(), anything())
58
+ model.save.should == true
59
+ end
60
+ end
61
+
62
+ describe "finding records" do
63
+ it 'should retrieve Point objects' do
64
+ model = PointModel.create(:extra => 'test', :geom => GeometryFactory.point)
65
+ PointModel.find(model.id).geom.should == GeometryFactory.point
66
+ end
67
+
68
+ it 'should retrieve LineString objects' do
69
+ model = LineStringModel.create(:extra => 'test', :geom => GeometryFactory.line_string)
70
+ LineStringModel.find(model.id).geom.should == GeometryFactory.line_string
71
+ end
72
+
73
+ it 'should retrieve Polygon objects' do
74
+ model = PolygonModel.create(:extra => 'test', :geom => GeometryFactory.polygon)
75
+ PolygonModel.find(model.id).geom.should == GeometryFactory.polygon
76
+ end
77
+
78
+ it 'should retrieve MultiPoint objects' do
79
+ model = MultiPointModel.create(:extra => 'test', :geom => GeometryFactory.multi_point)
80
+ MultiPointModel.find(model.id).geom.should == GeometryFactory.multi_point
81
+ end
82
+
83
+ it 'should retrieve MultiLineString objects' do
84
+ model = MultiLineStringModel.create(:extra => 'test', :geom => GeometryFactory.multi_line_string)
85
+ MultiLineStringModel.find(model.id).geom.should == GeometryFactory.multi_line_string
86
+ end
87
+
88
+ it 'should retrieve MultiPolygon objects' do
89
+ model = MultiPolygonModel.create(:extra => 'test', :geom => GeometryFactory.multi_polygon)
90
+ MultiPolygonModel.find(model.id).geom.should == GeometryFactory.multi_polygon
91
+ end
92
+
93
+ it 'should retrieve GeometryCollection objects' do
94
+ model = GeometryCollectionModel.create(:extra => 'test', :geom => GeometryFactory.geometry_collection)
95
+ GeometryCollectionModel.find(model.id).geom.should == GeometryFactory.geometry_collection
96
+ end
97
+
98
+ it 'should retrieve Geometry objects' do
99
+ model = GeometryModel.create(:extra => 'test', :geom => GeometryFactory.point)
100
+ GeometryModel.find(model.id).geom.should == GeometryFactory.point
101
+ end
102
+ end
103
+ end
104
+
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'spatial_adapter/mysql'
3
+
4
+ describe "Spatially-enabled Schema Dumps" do
5
+ before :all do
6
+ mysql_connection
7
+ @connection = ActiveRecord::Base.connection
8
+
9
+ # Create a new table
10
+ ActiveRecord::Schema.define do
11
+ create_table :migrated_geometry_models, :options=> "ENGINE=MyISAM", :force => true do |t|
12
+ t.integer :extra
13
+ t.point :geom, :null => false
14
+ end
15
+ add_index :migrated_geometry_models, :geom, :spatial => true, :name => 'test_spatial_index'
16
+ end
17
+
18
+ File.open('schema.rb', "w") do |file|
19
+ ActiveRecord::SchemaDumper.dump(@connection, file)
20
+ end
21
+
22
+ # Drop the original table
23
+ @connection.drop_table "migrated_geometry_models"
24
+
25
+ # Load the dumped schema
26
+ load('schema.rb')
27
+ end
28
+
29
+ after :all do
30
+ # delete the schema file
31
+ File.delete('schema.rb')
32
+
33
+ # Drop the new table
34
+ @connection.drop_table "migrated_geometry_models"
35
+ end
36
+
37
+ it "should preserve spatial attributes of tables" do
38
+ columns = @connection.columns("migrated_geometry_models")
39
+
40
+ columns.should have(3).items
41
+ geom_column = columns.select{|c| c.name == 'geom'}.first
42
+ geom_column.should be_a(SpatialAdapter::SpatialColumn)
43
+ geom_column.geometry_type.should == :point
44
+ geom_column.type.should == :geometry
45
+ end
46
+
47
+ it "should preserve spatial indexes" do
48
+ indexes = @connection.indexes("migrated_geometry_models")
49
+
50
+ indexes.should have(1).item
51
+
52
+ indexes.first.name.should == 'test_spatial_index'
53
+ indexes.first.columns.should == ["geom"]
54
+ indexes.first.spatial.should == true
55
+ end
56
+ end
@@ -0,0 +1,230 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ require 'spatial_adapter/postgresql'
4
+ require 'db/postgis_raw'
5
+ require 'models/common'
6
+
7
+ describe "Modified PostgreSQLAdapter" do
8
+ before :each do
9
+ postgis_connection
10
+ @connection = ActiveRecord::Base.connection
11
+ end
12
+
13
+ describe '#postgis_version' do
14
+ it 'should report a version number if PostGIS is installed' do
15
+ @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')
16
+ @connection.postgis_version.should_not be_nil
17
+ end
18
+
19
+ it 'should report nil if PostGIS is not installed' do
20
+ @connection.should_receive(:select_value).with('SELECT postgis_full_version()').and_raise(ActiveRecord::StatementInvalid)
21
+ @connection.postgis_version.should be_nil
22
+ end
23
+ end
24
+
25
+ describe '#postgis_major_version' do
26
+ it 'should be the first component of the version number' do
27
+ @connection.stub!(:postgis_version).and_return('1.5.0')
28
+ @connection.postgis_major_version.should == 1
29
+ end
30
+
31
+ it 'should be nil if PostGIS is not installed' do
32
+ @connection.stub!(:postgis_version).and_return(nil)
33
+ @connection.postgis_major_version.should be_nil
34
+ end
35
+ end
36
+
37
+ describe '#postgis_minor_version' do
38
+ it 'should be the second component of the version number' do
39
+ @connection.stub!(:postgis_version).and_return('1.5.0')
40
+ @connection.postgis_minor_version.should == 5
41
+ end
42
+
43
+ it 'should be nil if PostGIS is not installed' do
44
+ @connection.stub!(:postgis_version).and_return(nil)
45
+ @connection.postgis_minor_version.should be_nil
46
+ end
47
+ end
48
+
49
+ describe '#spatial?' do
50
+ it 'should be true if PostGIS is installed' do
51
+ @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')
52
+ @connection.should be_spatial
53
+ end
54
+
55
+ it 'should be false if PostGIS is not installed' do
56
+ @connection.should_receive(:select_value).with('SELECT postgis_full_version()').and_raise(ActiveRecord::StatementInvalid)
57
+ @connection.should_not be_spatial
58
+ end
59
+ end
60
+
61
+ describe '#supports_geographic?' do
62
+ it "should be true for PostGIS version 1.5.0" do
63
+ @connection.stub!(:postgis_version).and_return('1.5.0')
64
+ @connection.supports_geographic?.should == true
65
+ end
66
+
67
+ it "should be true for PostGIS newer than 1.5.0" do
68
+ @connection.stub!(:postgis_version).and_return('1.5.1')
69
+ @connection.supports_geographic?.should == true
70
+ end
71
+
72
+ it "should be true for PostGIS older than 1.5.0" do
73
+ @connection.stub!(:postgis_version).and_return('1.4.0')
74
+ @connection.supports_geographic?.should == false
75
+ end
76
+ end
77
+
78
+ describe "#columns" do
79
+ describe "type" do
80
+ it "should be a regular SpatialPostgreSQLColumn if column is a geometry data type" do
81
+ column = PointModel.columns.select{|c| c.name == 'geom'}.first
82
+ column.should be_a(ActiveRecord::ConnectionAdapters::SpatialPostgreSQLColumn)
83
+ #column.type.should == :geometry
84
+ column.geometry_type.should == :point
85
+ column.should_not be_geographic
86
+ end
87
+
88
+ it "should be a geographic SpatialPostgreSQLColumn if column is a geography data type" do
89
+ column = GeographyPointModel.columns.select{|c| c.name == 'geom'}.first
90
+ column.should be_a(ActiveRecord::ConnectionAdapters::SpatialPostgreSQLColumn)
91
+ #column.type.should == :geometry
92
+ column.geometry_type.should == :point
93
+ column.should be_geographic
94
+ end
95
+
96
+ it "should be PostgreSQLColumn if column is not a spatial data type" do
97
+ PointModel.columns.select{|c| c.name == 'extra'}.first.should be_a(ActiveRecord::ConnectionAdapters::PostgreSQLColumn)
98
+ end
99
+ end
100
+
101
+ describe "@geometry_type" do
102
+ it "should be :point for geometry columns restricted to POINT types" do
103
+ PointModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :point
104
+ end
105
+
106
+ it "should be :line_string for geometry columns restricted to LINESTRING types" do
107
+ LineStringModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :line_string
108
+ end
109
+
110
+ it "should be :polygon for geometry columns restricted to POLYGON types" do
111
+ PolygonModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :polygon
112
+ end
113
+
114
+ it "should be :multi_point for geometry columns restricted to MULTIPOINT types" do
115
+ MultiPointModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_point
116
+ end
117
+
118
+ it "should be :multi_line_string for geometry columns restricted to MULTILINESTRING types" do
119
+ MultiLineStringModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_line_string
120
+ end
121
+
122
+ it "should be :multi_polygon for geometry columns restricted to MULTIPOLYGON types" do
123
+ MultiPolygonModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_polygon
124
+ end
125
+
126
+ it "should be :geometry_collection for geometry columns restricted to GEOMETRYCOLLECTION types" do
127
+ GeometryCollectionModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :geometry_collection
128
+ end
129
+
130
+ it "should be :geometry for geometry columns not restricted to a type" do
131
+ GeometryModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :geometry
132
+ end
133
+
134
+ it "should be :point for geography columns restricted to POINT types" do
135
+ GeographyPointModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :point
136
+ end
137
+
138
+ it "should be :line_string for geography columns restricted to LINESTRING types" do
139
+ GeographyLineStringModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :line_string
140
+ end
141
+
142
+ it "should be :polygon for geography columns restricted to POLYGON types" do
143
+ GeographyPolygonModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :polygon
144
+ end
145
+
146
+ it "should be :multi_point for geography columns restricted to MULTIPOINT types" do
147
+ GeographyMultiPointModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_point
148
+ end
149
+
150
+ it "should be :multi_line_string for geography columns restricted to MULTILINESTRING types" do
151
+ GeographyMultiLineStringModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_line_string
152
+ end
153
+
154
+ it "should be :multi_polygon for geography columns restricted to MULTIPOLYGON types" do
155
+ GeographyMultiPolygonModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :multi_polygon
156
+ end
157
+
158
+ it "should be :geometry_collection for geography columns restricted to GEOMETRYCOLLECTION types" do
159
+ GeographyGeometryCollectionModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :geometry_collection
160
+ end
161
+
162
+ it "should be :geometry for geography columns not restricted to a type" do
163
+ GeographyModel.columns.select{|c| c.name == 'geom'}.first.geometry_type.should == :geometry
164
+ end
165
+ end
166
+ end
167
+
168
+ describe "#indexes" do
169
+ before :each do
170
+ @indexes = @connection.indexes('point_models')
171
+ end
172
+
173
+ it "should return an IndexDefinition for each index on the table" do
174
+ @indexes.should have(2).items
175
+ @indexes.each do |i|
176
+ i.should be_a(ActiveRecord::ConnectionAdapters::IndexDefinition)
177
+ end
178
+ end
179
+
180
+ it "should indicate the correct columns in the index" do
181
+ @indexes.select{|i| i.name == 'index_point_models_on_geom'}.first.columns.should == ['geom']
182
+ @indexes.select{|i| i.name == 'index_point_models_on_extra'}.first.columns.should == ['extra', 'more_extra']
183
+ end
184
+
185
+ it "should be marked as spatial if a GiST index on a geometry column" do
186
+ @indexes.select{|i| i.name == 'index_point_models_on_geom'}.first.spatial.should == true
187
+ end
188
+
189
+ it "should be marked as spatial if a GiST index on a geography column" do
190
+ @indexes = @connection.indexes('geography_point_models')
191
+ @indexes.select{|i| i.name == 'index_geography_point_models_on_geom'}.first.spatial.should == true
192
+ end
193
+
194
+ it "should not be marked as spatial if not a GiST index" do
195
+ @indexes.select{|i| i.name == 'index_point_models_on_extra'}.first.spatial.should == false
196
+ end
197
+
198
+ it "should not be marked as spatial if a GiST index on a non-geometry column" do
199
+ @connection.execute(<<-SQL)
200
+ create table non_spatial_models
201
+ (
202
+ id serial primary key,
203
+ location point,
204
+ extra varchar(255)
205
+ );
206
+ create index index_non_spatial_models_on_location on non_spatial_models using gist (box(location, location));
207
+ SQL
208
+ @indexes = @connection.indexes('non_spatial_models')
209
+ @indexes.select{|i| i.name == 'index_non_spatial_models_on_location'}.first.spatial.should == false
210
+ @connection.execute 'drop table non_spatial_models'
211
+ end
212
+ end
213
+
214
+ describe "#add_index" do
215
+ after :each do
216
+ @connection.should_receive(:execute).with(any_args())
217
+ @connection.remove_index('geometry_models', 'geom')
218
+ end
219
+
220
+ it "should create a spatial index given :spatial => true" do
221
+ @connection.should_receive(:execute).with(/using gist/i)
222
+ @connection.add_index('geometry_models', 'geom', :spatial => true)
223
+ end
224
+
225
+ it "should not create a spatial index unless specified" do
226
+ @connection.should_not_receive(:execute).with(/using gist/i)
227
+ @connection.add_index('geometry_models', 'extra')
228
+ end
229
+ end
230
+ end