Skip to content

Commit ba2a7aa

Browse files
committed
Add MySQL spatial type support
Extends AbstractMySQLPlatform with GEOMETRY type support and enhances MySQLSchemaManager to introspect spatial columns with geometryType and SRID properties. MySQL supports GEOMETRY types (POINT, LINESTRING, POLYGON, etc.) with optional SRID constraints using the conditional comment syntax for MySQL 8.0.3+.
1 parent 0f33956 commit ba2a7aa

File tree

7 files changed

+541
-53
lines changed

7 files changed

+541
-53
lines changed

src/Platforms/AbstractMySQLPlatform.php

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use function sprintf;
3535
use function str_replace;
3636
use function strtolower;
37+
use function strtoupper;
3738

3839
/**
3940
* Provides the base implementation for the lowest versions of supported MySQL-like database platforms.
@@ -224,17 +225,27 @@ public function getBooleanTypeDeclarationSQL(array $column): string
224225
*/
225226
public function getGeometryTypeDeclarationSQL(array $column): string
226227
{
227-
throw NotSupported::new(__METHOD__);
228+
$geometryType = $column['geometryType'] ?? 'GEOMETRY';
229+
$srid = $column['srid'] ?? null;
230+
231+
$sql = strtoupper($geometryType);
232+
233+
if ($srid !== null) {
234+
// MySQL 8.0.3+ supports SRID attribute using conditional comment syntax
235+
$sql .= sprintf(' /*!80003 SRID %d */', $srid);
236+
}
237+
238+
return $sql;
228239
}
229240

230241
public function getGeometryFromTextSQL(string $sqlExpr): string
231242
{
232-
throw NotSupported::new(__METHOD__);
243+
return sprintf('ST_GeomFromText(%s)', $sqlExpr);
233244
}
234245

235246
public function getGeometryAsTextSQL(string $sqlExpr): string
236247
{
237-
throw NotSupported::new(__METHOD__);
248+
return sprintf('ST_AsText(%s)', $sqlExpr);
238249
}
239250

240251
/**
@@ -796,38 +807,46 @@ public function getSetTransactionIsolationSQL(TransactionIsolationLevel $level):
796807
protected function initializeDoctrineTypeMappings(): void
797808
{
798809
$this->doctrineTypeMapping = [
799-
'bigint' => Types::BIGINT,
800-
'binary' => Types::BINARY,
801-
'blob' => Types::BLOB,
802-
'char' => Types::STRING,
803-
'date' => Types::DATE_MUTABLE,
804-
'datetime' => Types::DATETIME_MUTABLE,
805-
'decimal' => Types::DECIMAL,
806-
'double' => Types::FLOAT,
807-
'enum' => Types::ENUM,
808-
'float' => Types::SMALLFLOAT,
809-
'int' => Types::INTEGER,
810-
'integer' => Types::INTEGER,
811-
'json' => Types::JSON,
812-
'longblob' => Types::BLOB,
813-
'longtext' => Types::TEXT,
814-
'mediumblob' => Types::BLOB,
815-
'mediumint' => Types::INTEGER,
816-
'mediumtext' => Types::TEXT,
817-
'numeric' => Types::DECIMAL,
818-
'real' => Types::FLOAT,
819-
'set' => Types::SIMPLE_ARRAY,
820-
'smallint' => Types::SMALLINT,
821-
'string' => Types::STRING,
822-
'text' => Types::TEXT,
823-
'time' => Types::TIME_MUTABLE,
824-
'timestamp' => Types::DATETIME_MUTABLE,
825-
'tinyblob' => Types::BLOB,
826-
'tinyint' => Types::BOOLEAN,
827-
'tinytext' => Types::TEXT,
828-
'varbinary' => Types::BINARY,
829-
'varchar' => Types::STRING,
830-
'year' => Types::DATE_MUTABLE,
810+
'bigint' => Types::BIGINT,
811+
'binary' => Types::BINARY,
812+
'blob' => Types::BLOB,
813+
'char' => Types::STRING,
814+
'date' => Types::DATE_MUTABLE,
815+
'datetime' => Types::DATETIME_MUTABLE,
816+
'decimal' => Types::DECIMAL,
817+
'double' => Types::FLOAT,
818+
'enum' => Types::ENUM,
819+
'float' => Types::SMALLFLOAT,
820+
'geometry' => Types::GEOMETRY,
821+
'geometrycollection' => Types::GEOMETRY,
822+
'int' => Types::INTEGER,
823+
'integer' => Types::INTEGER,
824+
'json' => Types::JSON,
825+
'linestring' => Types::GEOMETRY,
826+
'longblob' => Types::BLOB,
827+
'longtext' => Types::TEXT,
828+
'mediumblob' => Types::BLOB,
829+
'mediumint' => Types::INTEGER,
830+
'mediumtext' => Types::TEXT,
831+
'multilinestring' => Types::GEOMETRY,
832+
'multipoint' => Types::GEOMETRY,
833+
'multipolygon' => Types::GEOMETRY,
834+
'numeric' => Types::DECIMAL,
835+
'point' => Types::GEOMETRY,
836+
'polygon' => Types::GEOMETRY,
837+
'real' => Types::FLOAT,
838+
'set' => Types::SIMPLE_ARRAY,
839+
'smallint' => Types::SMALLINT,
840+
'string' => Types::STRING,
841+
'text' => Types::TEXT,
842+
'time' => Types::TIME_MUTABLE,
843+
'timestamp' => Types::DATETIME_MUTABLE,
844+
'tinyblob' => Types::BLOB,
845+
'tinyint' => Types::BOOLEAN,
846+
'tinytext' => Types::TEXT,
847+
'varbinary' => Types::BINARY,
848+
'varchar' => Types::STRING,
849+
'year' => Types::DATE_MUTABLE,
831850
];
832851
}
833852

src/Schema/MySQLSchemaManager.php

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,14 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
118118
{
119119
$tableColumn = array_change_key_case($tableColumn, CASE_LOWER);
120120

121-
$dbType = $tableColumn['type'];
122-
$length = null;
123-
$scale = 0;
124-
$precision = null;
125-
$fixed = false;
126-
$values = [];
121+
$dbType = $tableColumn['type'];
122+
$length = null;
123+
$scale = 0;
124+
$precision = null;
125+
$fixed = false;
126+
$values = [];
127+
$geometryType = null;
128+
$srid = null;
127129

128130
$type = $this->platform->getDoctrineTypeMapping($dbType);
129131

@@ -173,6 +175,23 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
173175
$scale = (int) $tableColumn['numeric_scale'];
174176
}
175177

178+
break;
179+
180+
case 'geometry':
181+
case 'point':
182+
case 'linestring':
183+
case 'polygon':
184+
case 'multipoint':
185+
case 'multilinestring':
186+
case 'multipolygon':
187+
case 'geometrycollection':
188+
// For MySQL, the dbType directly represents the geometry subtype
189+
$geometryType = $dbType;
190+
191+
if (isset($tableColumn['srs_id'])) {
192+
$srid = (int) $tableColumn['srs_id'];
193+
}
194+
176195
break;
177196
}
178197

@@ -213,6 +232,14 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
213232
$column->setPlatformOption('charset', $tableColumn['characterset']);
214233
$column->setPlatformOption('collation', $tableColumn['collation']);
215234

235+
if ($geometryType !== null) {
236+
$column->setPlatformOption('geometryType', $geometryType);
237+
}
238+
239+
if ($srid !== null) {
240+
$column->setPlatformOption('srid', $srid);
241+
}
242+
216243
return $column;
217244
}
218245

@@ -372,7 +399,8 @@ protected function selectTableColumns(string $databaseName, ?string $tableName =
372399
c.EXTRA,
373400
c.COLUMN_COMMENT AS comment,
374401
c.CHARACTER_SET_NAME AS characterset,
375-
c.COLLATION_NAME AS collation
402+
c.COLLATION_NAME AS collation,
403+
c.SRS_ID AS srs_id
376404
FROM information_schema.COLUMNS c
377405
INNER JOIN information_schema.TABLES t
378406
ON t.TABLE_NAME = c.TABLE_NAME

0 commit comments

Comments
 (0)