activerecord-trilogis-adapter 8.0.0 → 8.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d6986c4a92cdff8495b93cf837edbc946a9401c1a12a2b639bc7440c974d0d6
4
- data.tar.gz: b5663960d9aa5514a8c495d6603871c20acbdfdbdd534d78da2c70eb8f4e154d
3
+ metadata.gz: 1c43e31eb6d57d6b2eaf0ed551c13c729e1a7366e71f368871e358f262c6acac
4
+ data.tar.gz: 53488d879dd78083bc5671f5067a9b357a4f453213e2df373c9cf0e321542c6e
5
5
  SHA512:
6
- metadata.gz: 784de6dc127d3c4f584ed540d37391e1bbb88496ff1e05c9e0229686356b4bd69af33635910b7c81dd12844b649f9db9808458d4251734a4531b7261c2ee99bc
7
- data.tar.gz: 3e9e4ddea564f8e6843baa1f36104b83f5679b5ecb0ed46e8e0edb5c7f97f942534640f5a35d582dbae3a5c6332c59af828eb7a14b41c21b92f6f2637ae53123
6
+ metadata.gz: 384a3d95ec59d189d0615d2571498a0d7c7feff5f65862fd166f14d468eefd73c67fbc89072574b32aafebb1c36a79570f3221a8878f9b0272016a06f784eceb
7
+ data.tar.gz: d87c990d357629fb81929572fb4feedafae6dce63e7eb78be41552bc0d1f22f41a8ccc98c21327ac96060180d49349ad8a78fdb2b52b817d1f97c9243b10076a
@@ -9,7 +9,10 @@ module ActiveRecord
9
9
  def add_column_options!(sql, options)
10
10
  # Add SRID option for spatial columns in MySQL 8.0+
11
11
  # Format: /*!80003 SRID #{srid} */
12
- sql << " /*!80003 SRID #{options[:srid]} */" if options[:srid]
12
+ if options[:srid]
13
+ sql_result = "#{sql} /*!80003 SRID #{options[:srid]} */"
14
+ sql.replace(sql_result)
15
+ end
13
16
 
14
17
  super
15
18
  end
@@ -77,18 +77,20 @@ module ActiveRecord
77
77
  if spatial_type?(type.to_s)
78
78
  # Build ALTER TABLE statement for spatial column
79
79
  sql_type = spatial_sql_type(type, options[:type])
80
- sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{sql_type}"
80
+ base_sql = "ALTER TABLE #{quote_table_name(table_name)} " \
81
+ "ADD #{quote_column_name(column_name)} #{sql_type}"
82
+ sql_parts = [base_sql]
81
83
 
82
84
  # Add SRID if specified
83
- sql << " SRID #{options[:srid]}" if options[:srid] && options[:srid] != 0
85
+ sql_parts << " SRID #{options[:srid]}" if options[:srid] && options[:srid] != 0
84
86
 
85
87
  # Add NULL constraint
86
- sql << " NOT NULL" if options[:null] == false
88
+ sql_parts << " NOT NULL" if options[:null] == false
87
89
 
88
90
  # Add DEFAULT if specified (allow falsy values like 0/false)
89
- sql << " DEFAULT #{quote_default_expression(options[:default], nil)}" if options.key?(:default)
91
+ sql_parts << " DEFAULT #{quote_default_expression(options[:default], nil)}" if options.key?(:default)
90
92
 
91
- execute sql
93
+ execute sql_parts.join
92
94
 
93
95
  # Clear memoized spatial column info for this table
94
96
  clear_spatial_cache_for(table_name)
@@ -159,10 +161,19 @@ module ActiveRecord
159
161
  # Build a spatial column from field metadata
160
162
  def build_spatial_column(table_name, field, field_name, sql_type)
161
163
  spatial_info = spatial_column_info(table_name).get(field_name, sql_type)
164
+
165
+ # Keep original sql_type in metadata (point, linestring, etc.)
166
+ # This preserves the actual geometric type for @geo_type_name
162
167
  type_metadata = fetch_type_metadata(sql_type)
163
168
 
169
+ # Lookup cast type as "geometry" for schema dumper compatibility
170
+ # Schema dumper validates cast_type, and only "geometry" is registered as table method
171
+ # Actual type is preserved in sql_type_metadata and limit hash
172
+ cast_type = lookup_cast_type("geometry")
173
+
164
174
  SpatialColumn.new(
165
175
  field_name,
176
+ cast_type,
166
177
  extract_field_value(field, :Default, :default),
167
178
  type_metadata,
168
179
  extract_field_value(field, :Null, :null) == "YES",
@@ -180,14 +191,14 @@ module ActiveRecord
180
191
  def visit_ColumnDefinition(o)
181
192
  if spatial_column?(o)
182
193
  sql_type = spatial_sql_type(o.sql_type, o.options[:type])
183
- column_sql = "#{quote_column_name(o.name)} #{sql_type}"
194
+ column_sql_parts = ["#{quote_column_name(o.name)} #{sql_type}"]
184
195
 
185
196
  # Add SRID if specified (MySQL 8.0+ syntax: COLUMN TYPE SRID value)
186
- column_sql << " SRID #{o.options[:srid]}" if o.options[:srid] && o.options[:srid] != 0
197
+ column_sql_parts << " SRID #{o.options[:srid]}" if o.options[:srid] && o.options[:srid] != 0
187
198
 
188
- column_sql << " NOT NULL" unless o.null
189
- column_sql << " DEFAULT #{quote_default_expression(o.default, o)}" unless o.default.nil?
190
- column_sql
199
+ column_sql_parts << " NOT NULL" unless o.null
200
+ column_sql_parts << " DEFAULT #{quote_default_expression(o.default, o)}" unless o.default.nil?
201
+ column_sql_parts.join
191
202
  else
192
203
  super
193
204
  end
@@ -13,7 +13,7 @@ module ActiveRecord
13
13
 
14
14
  module Trilogis
15
15
  class SpatialColumn < ActiveRecord::ConnectionAdapters::MySQL::Column
16
- attr_reader :geometric_type, :srid
16
+ attr_reader :geometric_type, :srid, :geo_type_name
17
17
 
18
18
  # Map SQL type strings to RGeo type classes
19
19
  GEOMETRIC_TYPES = {
@@ -27,24 +27,26 @@ module ActiveRecord
27
27
  "geometrycollection" => RGeo::Feature::GeometryCollection
28
28
  }.freeze
29
29
 
30
- def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil,
31
- comment: nil, spatial_info: nil, **)
32
- super(name, default, sql_type_metadata, null, default_function, collation: collation, comment: comment)
30
+ def initialize(name, cast_type, default, sql_type_metadata = nil, null = true,
31
+ default_function = nil, collation: nil, comment: nil, spatial_info: nil, **)
32
+ super(name, cast_type, default, sql_type_metadata, null, default_function,
33
+ collation: collation, comment: comment)
33
34
 
34
- return unless spatial?
35
+ # Guard against nil cast_type during OID registration
36
+ return unless cast_type && spatial?
35
37
 
36
38
  if spatial_info
37
39
  # Use spatial info from INFORMATION_SCHEMA if available
38
- geo_type_str = spatial_info[:type].to_s.downcase
39
- @geometric_type = GEOMETRIC_TYPES[geo_type_str] || RGeo::Feature::Geometry
40
+ @geo_type_name = spatial_info[:type].to_s.downcase
41
+ @geometric_type = GEOMETRIC_TYPES[@geo_type_name] || RGeo::Feature::Geometry
40
42
  @srid = spatial_info[:srid] || 0
41
43
  @has_z = spatial_info[:has_z] || false
42
44
  @has_m = spatial_info[:has_m] || false
43
45
  else
44
46
  # Fallback to extracting from SQL type
45
- type_info = Type::Spatial.new(sql_type_metadata.sql_type)
46
- geo_type_str = type_info.geo_type.to_s.downcase
47
- @geometric_type = GEOMETRIC_TYPES[geo_type_str] || RGeo::Feature::Geometry
47
+ @geo_type_name = sql_type_metadata.sql_type.to_s.downcase
48
+ type_info = Type::Spatial.new(@geo_type_name)
49
+ @geometric_type = GEOMETRIC_TYPES[@geo_type_name] || RGeo::Feature::Geometry
48
50
  @srid = type_info.srid || 0
49
51
  @has_z = false
50
52
  @has_m = false
@@ -52,6 +54,9 @@ module ActiveRecord
52
54
  end
53
55
 
54
56
  def spatial?
57
+ # Guard against nil sql_type_metadata during type registration
58
+ return false unless sql_type_metadata&.sql_type
59
+
55
60
  TrilogisAdapter::SPATIAL_COLUMN_TYPES.include?(sql_type_metadata.sql_type.downcase)
56
61
  end
57
62
 
@@ -63,14 +68,25 @@ module ActiveRecord
63
68
  @has_m || false
64
69
  end
65
70
 
71
+ # Return Rails type for schema dumper
72
+ # Returns the actual geometric type (point, linestring, etc.) as symbol
73
+ # This allows schema dumper to generate t.point, t.linestring, etc.
74
+ def type
75
+ return super unless spatial?
76
+
77
+ # Return actual geometric type as symbol
78
+ # This matches PostGIS approach and enables proper schema dumping
79
+ @geo_type_name&.to_sym || :geometry
80
+ end
81
+
66
82
  # Return limit as hash with spatial metadata for schema dumper
83
+ # Only includes SRID (type is already in column type)
67
84
  def limit
68
85
  return super unless spatial?
69
86
 
70
- {
71
- type: sql_type_metadata.sql_type.downcase,
72
- srid: @srid
73
- }
87
+ # Only include SRID in limit
88
+ # Type information is in the type() method
89
+ { srid: @srid }.compact
74
90
  end
75
91
  end
76
92
  end
@@ -104,9 +104,6 @@ module ActiveRecord
104
104
  # Override the visitor for spatial support
105
105
  @visitor = Arel::Visitors::Trilogis.new(self)
106
106
 
107
- # Register spatial types
108
- register_spatial_types
109
-
110
107
  # Configure RGeo factory generator for SRID-based factory selection
111
108
  configure_rgeo_factory_generator
112
109
  end
@@ -138,6 +135,11 @@ module ActiveRecord
138
135
  Trilogis::SchemaCreation.new(self)
139
136
  end
140
137
 
138
+ # Override valid_type? to include spatial types
139
+ def valid_type?(type)
140
+ SPATIAL_COLUMN_TYPES.include?(type.to_s) || super
141
+ end
142
+
141
143
  def native_database_types
142
144
  super.merge(
143
145
  geometry: { name: "geometry" },
@@ -188,16 +190,6 @@ module ActiveRecord
188
190
 
189
191
  private
190
192
 
191
- def register_spatial_types
192
- SPATIAL_COLUMN_TYPES.each do |geo_type|
193
- ActiveRecord::Type.register(
194
- geo_type.to_sym,
195
- Type::Spatial.new(geo_type),
196
- adapter: :trilogis
197
- )
198
- end
199
- end
200
-
201
193
  def configure_rgeo_factory_generator
202
194
  # Register Geographic factories for geographic SRIDs in RGeo::ActiveRecord::SpatialFactoryStore
203
195
  # This ensures the correct factory (Geographic vs Cartesian) is used based on SRID
@@ -264,6 +256,15 @@ module ActiveRecord
264
256
  end
265
257
  end
266
258
 
259
+ # Register spatial types globally
260
+ ActiveRecord::ConnectionAdapters::TrilogisAdapter::SPATIAL_COLUMN_TYPES.each do |geo_type|
261
+ ActiveRecord::Type.register(
262
+ geo_type.to_sym,
263
+ ActiveRecord::Type::Spatial,
264
+ adapter: :trilogis
265
+ )
266
+ end
267
+
267
268
  # Register the adapter with ActiveRecord
268
269
  ActiveRecord::ConnectionAdapters.register(
269
270
  "trilogis",
@@ -244,8 +244,18 @@ module ActiveRecord
244
244
  end
245
245
 
246
246
  def spatial_factory
247
- @spatial_factories ||= {}
247
+ # Rails 8.1 freezes type objects for Ractor compatibility
248
+ # If frozen, create factory without caching to avoid FrozenError
249
+ if frozen?
250
+ return RGeo::ActiveRecord::SpatialFactoryStore.instance.factory(
251
+ geo_type: @geo_type,
252
+ sql_type: @sql_type,
253
+ srid: @srid
254
+ )
255
+ end
248
256
 
257
+ # For non-frozen objects, use instance variable caching
258
+ @spatial_factories ||= {}
249
259
  @spatial_factories[@srid] ||= RGeo::ActiveRecord::SpatialFactoryStore.instance.factory(
250
260
  geo_type: @geo_type,
251
261
  sql_type: @sql_type,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-trilogis-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.0
4
+ version: 8.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ether Moon
@@ -13,22 +13,16 @@ dependencies:
13
13
  name: activerecord
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - ">="
17
- - !ruby/object:Gem::Version
18
- version: '8.0'
19
- - - "<"
16
+ - - "~>"
20
17
  - !ruby/object:Gem::Version
21
- version: '9.0'
18
+ version: '8.1'
22
19
  type: :runtime
23
20
  prerelease: false
24
21
  version_requirements: !ruby/object:Gem::Requirement
25
22
  requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- version: '8.0'
29
- - - "<"
23
+ - - "~>"
30
24
  - !ruby/object:Gem::Version
31
- version: '9.0'
25
+ version: '8.1'
32
26
  - !ruby/object:Gem::Dependency
33
27
  name: rgeo
34
28
  requirement: !ruby/object:Gem::Requirement
@@ -49,14 +43,14 @@ dependencies:
49
43
  requirements:
50
44
  - - "~>"
51
45
  - !ruby/object:Gem::Version
52
- version: '8.0'
46
+ version: '8.1'
53
47
  type: :runtime
54
48
  prerelease: false
55
49
  version_requirements: !ruby/object:Gem::Requirement
56
50
  requirements:
57
51
  - - "~>"
58
52
  - !ruby/object:Gem::Version
59
- version: '8.0'
53
+ version: '8.1'
60
54
  - !ruby/object:Gem::Dependency
61
55
  name: minitest
62
56
  requirement: !ruby/object:Gem::Requirement
@@ -185,7 +179,7 @@ dependencies:
185
179
  version: '2.9'
186
180
  description: ActiveRecord connection adapter for MySQL. It extends the Rails built-in
187
181
  Trilogy adapter and adds spatial extensions support via RGeo. Compatible with Rails
188
- 8.0+ native Trilogy adapter. Requires Ruby 3.2+ and Rails 8.0+.
182
+ 8.1+ native Trilogy adapter. Requires Ruby 3.2+ and Rails 8.1+.
189
183
  email: chipseru@gmail.com
190
184
  executables: []
191
185
  extensions: []