achirkunov-spatial_adapter 1.0.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.
@@ -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