spatial_adapter 0.2.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,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