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.
Files changed (45) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +3 -0
  3. data/README.rdoc +30 -17
  4. data/Rakefile +11 -0
  5. data/init.rb +1 -0
  6. data/lib/spatial_adapter/base/mysql/adapter.rb +54 -0
  7. data/lib/spatial_adapter/base/mysql/spatial_column.rb +12 -0
  8. data/lib/spatial_adapter/base/mysql.rb +9 -0
  9. data/lib/spatial_adapter/common/schema_dumper.rb +12 -12
  10. data/lib/spatial_adapter/common/spatial_column.rb +4 -4
  11. data/lib/spatial_adapter/common/table_definition.rb +8 -10
  12. data/lib/spatial_adapter/common.rb +10 -0
  13. data/lib/spatial_adapter/jdbcmysql.rb +50 -0
  14. data/lib/spatial_adapter/mysql.rb +43 -85
  15. data/lib/spatial_adapter/mysql2.rb +39 -86
  16. data/lib/spatial_adapter/postgresql.rb +315 -324
  17. data/lib/spatial_adapter/version.rb +3 -0
  18. data/lib/spatial_adapter.rb +3 -7
  19. data/spatial_adapter.gemspec +39 -0
  20. data/spec/db/jdbcmysql_raw.rb +70 -0
  21. data/spec/db/mysql2_raw.rb +9 -9
  22. data/spec/db/mysql_raw.rb +9 -9
  23. data/spec/jdbcmysql_spec.rb +25 -0
  24. data/spec/mysql2_spec.rb +31 -0
  25. data/spec/mysql_spec.rb +17 -0
  26. data/spec/postgresql/connection_adapter_spec.rb +34 -39
  27. data/spec/postgresql/migration_spec.rb +51 -51
  28. data/spec/postgresql/models_spec.rb +37 -37
  29. data/spec/postgresql/schema_dumper_spec.rb +12 -12
  30. data/spec/postgresql_spec.rb +5 -0
  31. data/spec/{shared_examples.rb → shared/common_model_actions_spec.rb} +2 -2
  32. data/spec/shared/mysql_connection_adapter_spec.rb +110 -0
  33. data/spec/{mysql/migration_spec.rb → shared/mysql_migration_spec.rb} +17 -17
  34. data/spec/shared/mysql_models_spec.rb +58 -0
  35. data/spec/{mysql/schema_dumper_spec.rb → shared/mysql_schema_dumper_spec.rb} +24 -27
  36. data/spec/spec_helper.rb +25 -21
  37. metadata +131 -84
  38. data/VERSION +0 -1
  39. data/spec/README.txt +0 -22
  40. data/spec/mysql/connection_adapter_spec.rb +0 -106
  41. data/spec/mysql/models_spec.rb +0 -65
  42. data/spec/mysql2/connection_adapter_spec.rb +0 -106
  43. data/spec/mysql2/migration_spec.rb +0 -64
  44. data/spec/mysql2/models_spec.rb +0 -65
  45. 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
- describe "Spatially-enabled Migrations" do
8
- before :each do
9
- mysql_connection
10
- @connection = ActiveRecord::Base.connection
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
- describe "creating tables" do
11
+
12
+ context "creating tables" do
14
13
  after :each do
15
- @connection.drop_table "migrated_geometry_models"
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 = @connection.columns(:migrated_geometry_models).select{|c| c.name == 'geom'}.first
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
- describe "adding columns" do
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
- @connection.drop_table "migrated_geometry_models"
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 = @connection.columns(:migrated_geometry_models).select{|c| c.name == 'geom'}.first
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
- require 'spec_helper'
2
- require 'spatial_adapter/mysql'
1
+ shared_examples_for 'spatially enabled schema dump' do
2
+ let(:establish){ mysql_connection }
3
3
 
4
- describe "Spatially-enabled Schema Dumps" do
5
- before :all do
6
- mysql_connection
7
- @connection = ActiveRecord::Base.connection
4
+ let(:connection) do
5
+ establish
6
+ ActiveRecord::Base.connection
7
+ end
8
8
 
9
- # Create a new table
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, :name => 'test_spatial_index'
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(@connection, file)
19
+ File.open('schema.rb', "w:UTF-8") do |file|
20
+ ActiveRecord::SchemaDumper.dump(connection, file)
20
21
  end
21
-
22
- # Drop the original table
23
- @connection.drop_table "migrated_geometry_models"
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
- # Drop the new table
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 = @connection.columns("migrated_geometry_models")
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 = @connection.indexes("migrated_geometry_models")
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 'rubygems'
2
- require 'spec'
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