• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

brick / geo / 14057076899

25 Mar 2025 10:14AM UTC coverage: 52.154% (-13.7%) from 65.828%
14057076899

push

github

BenMorel
Wip

0 of 383 new or added lines in 14 files covered. (0.0%)

141 existing lines in 12 files now uncovered.

1634 of 3133 relevant lines covered (52.15%)

396.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Engine/MysqlEngine.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Brick\Geo\Engine;
6

7
use Brick\Geo\Curve;
8
use Brick\Geo\Engine\Database\DatabaseDriver;
9
use Brick\Geo\Engine\Database\Query\BinaryValue;
10
use Brick\Geo\Engine\Database\Query\ScalarValue;
11
use Brick\Geo\Engine\Database\Result\Row;
12
use Brick\Geo\Exception\GeometryEngineException;
13
use Brick\Geo\Geometry;
14
use Brick\Geo\Io\WkbReader;
15
use Brick\Geo\Io\WkbWriter;
16
use Brick\Geo\Point;
17
use Override;
18

19
/**
20
 * Database engine based on MySQL.
21
 */
22
final readonly class MysqlEngine extends DatabaseEngine
23
{
24
    private WkbReader $wkbReader;
25
    private WkbWriter $wkbWriter;
26

27
    public function __construct(
28
        // TODO private
29
        public DatabaseDriver $driver,
30
        // TODO
31
        private bool $useProxy = true,
32
    ) {
NEW
33
        $this->wkbReader = new WkbReader();
×
NEW
34
        $this->wkbWriter = new WkbWriter();
×
35
    }
36

37
    /**
38
     * Builds and executes a SQL query for a GIS function.
39
     *
40
     * @param string                $function        The SQL GIS function to execute.
41
     * @param list<Geometry|scalar> $parameters      The Geometry objects or scalar values to pass as parameters.
42
     * @param bool                  $returnsGeometry Whether the GIS function returns a Geometry.
43
     *
44
     * @throws GeometryEngineException
45
     */
46
    private function query(string $function, array $parameters, bool $returnsGeometry) : Row
47
    {
NEW
48
        $query = ['SELECT '];
×
49

NEW
50
        if ($returnsGeometry) {
×
NEW
51
            $query[] = 'ST_AsWKB(g), ST_SRID(g) FROM (SELECT ';
×
52
        }
53

NEW
54
        $query[] = $function . '(';
×
55

NEW
56
        foreach ($parameters as $key => $parameter) {
×
NEW
57
            if ($key !== 0) {
×
NEW
58
                $query[] = ',';
×
59
            }
60

NEW
61
            if ($parameter instanceof Geometry) {
×
NEW
62
                if ($parameter instanceof Point && $parameter->isEmpty()) {
×
63
                    // WKB does not support empty points, and MySQL does not support them either.
NEW
64
                    throw new GeometryEngineException('MySQL does not support empty points');
×
65
                }
NEW
66
                $query[] = 'ST_GeomFromWKB(';
×
NEW
67
                $query[] = new BinaryValue($this->wkbWriter->write($parameter));
×
NEW
68
                $query[] = ',';
×
NEW
69
                $query[] = new ScalarValue($parameter->srid());
×
NEW
70
                $query[] = ')';
×
71
            } else {
NEW
72
                $query[] = new ScalarValue($parameter);
×
73
            }
74
        }
75

NEW
76
        $query[] = ')';
×
77

NEW
78
        if ($returnsGeometry) {
×
NEW
79
            $query[] = ' AS g) AS q';
×
80
        }
81

NEW
82
        return $this->driver->executeQuery(...$query);
×
83
    }
84

85
    /**
86
     * Queries a GIS function returning a boolean value.
87
     *
88
     * @param string          $function      The SQL GIS function to execute.
89
     * @param Geometry|scalar ...$parameters The Geometry objects or scalar values to pass as parameters.
90
     *
91
     * @throws GeometryEngineException
92
     */
93
    #[Override]
94
    protected function queryBool(string $function, Geometry|string|float|int|bool ...$parameters) : bool
95
    {
NEW
96
        return $this->query($function, $parameters, false)->get(0)->asBool();
×
97
    }
98

99
    /**
100
     * Queries a GIS function returning a floating point value.
101
     *
102
     * @param string          $function      The SQL GIS function to execute.
103
     * @param Geometry|scalar ...$parameters The Geometry objects or scalar values to pass as parameters.
104
     *
105
     * @throws GeometryEngineException
106
     */
107
    #[Override]
108
    protected function queryFloat(string $function, Geometry|string|float|int|bool ...$parameters) : float
109
    {
NEW
110
        return $this->query($function, $parameters, false)->get(0)->asFloat();
×
111
    }
112

113
    /**
114
     * Queries a GIS function returning a Geometry object.
115
     *
116
     * @param string             $function   The SQL GIS function to execute.
117
     * @param Geometry|scalar ...$parameters The Geometry objects or scalar values to pass as parameters.
118
     *
119
     * @throws GeometryEngineException
120
     */
121
    #[Override]
122
    protected function queryGeometry(string $function, Geometry|string|float|int|bool ...$parameters) : Geometry
123
    {
NEW
124
        $row = $this->query($function, $parameters, true);
×
125

NEW
126
        $wkb = $row->get(0)->asBinary();
×
NEW
127
        $srid = $row->get(1)->asInt();
×
128

NEW
129
        return $this->wkbReader->read($wkb, $srid);
×
130
    }
131

132
//    /**
133
//     * @return class-string<Proxy\ProxyInterface&Geometry>
134
//     *
135
//     * @throws GeometryEngineException
136
//     */
137
//    private function getProxyClassName(string $geometryType) : string
138
//    {
139
//        $proxyClasses = [
140
//            'CIRCULARSTRING'     => Proxy\CircularStringProxy::class,
141
//            'COMPOUNDCURVE'      => Proxy\CompoundCurveProxy::class,
142
//            'CURVE'              => Proxy\CurveProxy::class,
143
//            'CURVEPOLYGON'       => Proxy\CurvePolygonProxy::class,
144
//            'GEOMCOLLECTION'     => Proxy\GeometryCollectionProxy::class, /* MySQL 8 - https://github.com/brick/geo/pull/33 */
145
//            'GEOMETRY'           => Proxy\GeometryProxy::class,
146
//            'GEOMETRYCOLLECTION' => Proxy\GeometryCollectionProxy::class,
147
//            'LINESTRING'         => Proxy\LineStringProxy::class,
148
//            'MULTICURVE'         => Proxy\MultiCurveProxy::class,
149
//            'MULTILINESTRING'    => Proxy\MultiLineStringProxy::class,
150
//            'MULTIPOINT'         => Proxy\MultiPointProxy::class,
151
//            'MULTIPOLYGON'       => Proxy\MultiPolygonProxy::class,
152
//            'MULTISURFACE'       => Proxy\MultiSurfaceProxy::class,
153
//            'POINT'              => Proxy\PointProxy::class,
154
//            'POLYGON'            => Proxy\PolygonProxy::class,
155
//            'POLYHEDRALSURFACE'  => Proxy\PolyhedralSurfaceProxy::class,
156
//            'SURFACE'            => Proxy\SurfaceProxy::class,
157
//            'TIN'                => Proxy\TinProxy::class,
158
//            'TRIANGLE'           => Proxy\TriangleProxy::class
159
//        ];
160
//
161
//        $geometryType = strtoupper($geometryType);
162
//        $geometryType = preg_replace('/^ST_/', '', $geometryType);
163
//        assert($geometryType !== null);
164
//        $geometryType = preg_replace('/ .*/', '', $geometryType);
165
//        assert($geometryType !== null);
166
//
167
//        if (! isset($proxyClasses[$geometryType])) {
168
//            throw new GeometryEngineException('Unknown geometry type: ' . $geometryType);
169
//        }
170
//
171
//        return $proxyClasses[$geometryType];
172
//    }
173

174
    #[Override]
175
    public function isRing(Curve $curve) : bool
176
    {
177
        // MySQL does not support ST_IsRing(), but we have an easy fallback.
NEW
178
        return $this->isClosed($curve) && $this->isSimple($curve);
×
179
    }
180
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc