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

aimeos / aimeos-core / 49de7a0c-b4a5-425d-afa5-a9869aae879f

10 Jun 2024 06:55AM UTC coverage: 89.326% (+0.09%) from 89.241%
49de7a0c-b4a5-425d-afa5-a9869aae879f

push

circleci

aimeos
Fixed test

14076 of 15758 relevant lines covered (89.33%)

114.2 hits per line

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

37.5
/lib/mwlib/src/MW/Setup/Task/Base.php
1
<?php
2

3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2020
6
 * @package MW
7
 * @subpackage Setup
8
 */
9

10

11
namespace Aimeos\MW\Setup\Task;
12

13

14
/**
15
 * Base class for all setup tasks
16
 *
17
 * @package MW
18
 * @subpackage Setup
19
 */
20
abstract class Base implements \Aimeos\MW\Setup\Task\Iface
21
{
22
        private $dbm;
23
        private $paths = [];
24
        private $schemas = [];
25
        private $connections = [];
26
        protected $additional;
27

28
        /** @deprecated Use getSchema() instead */
29
        protected $schema;
30

31
        /** @deprecated Use acquire() and release() instead */
32
        protected $conn;
33

34

35
        /**
36
         * Initializes the task object.
37
         *
38
         * @param \Aimeos\MW\Setup\DBSchema\Iface $schema Database schema object
39
         * @param \Aimeos\MW\DB\Connection\Iface $conn Database connection
40
         * @param mixed $additional Additionally provided information for the setup tasks if required
41
         * @param string[] $paths List of paths of the setup tasks ordered by dependencies
42
         */
43
        public function __construct( \Aimeos\MW\Setup\DBSchema\Iface $schema, \Aimeos\MW\DB\Connection\Iface $conn,
44
                $additional = null, array $paths = [] )
45
        {
46
                $this->connections['db'] = $conn;
21✔
47
                $this->schema = $schema;
21✔
48
                $this->conn = $conn;
21✔
49
                $this->paths = $paths;
21✔
50
                $this->additional = $additional;
21✔
51
        }
52

53

54
        /**
55
         * Returns the list of task names which this task depends on
56
         *
57
         * @return string[] List of task names
58
         */
59
        public function getPreDependencies() : array
60
        {
61
                return [];
×
62
        }
63

64

65
        /**
66
         * Returns the list of task names which depends on this task.
67
         *
68
         * @return string[] List of task names
69
         */
70
        public function getPostDependencies() : array
71
        {
72
                return [];
3✔
73
        }
74

75

76
        /**
77
         * Updates the schema and migrates the data
78
         *
79
         * @return void
80
         */
81
        public function migrate()
82
        {
83
        }
×
84

85

86
        /**
87
         * Sets the database manager object
88
         *
89
         * @param \Aimeos\MW\DB\Manager\Iface $dbm Database manager
90
         * @return \Aimeos\MW\Setup\Task\Iface Task object for fluent interface
91
         */
92
        public function setDatabaseManager( \Aimeos\MW\DB\Manager\Iface $dbm ) : Iface
93
        {
94
                $this->dbm = $dbm;
3✔
95
                return $this;
3✔
96
        }
97

98

99
        /**
100
         * Sets the associative list of schemas with the resource name as key.
101
         *
102
         * @param \Aimeos\MW\Setup\DBSchema\Iface[] $schemas Associative list of schemas
103
         * @return \Aimeos\MW\Setup\Task\Iface Task object for fluent interface
104
         */
105
        public function setSchemas( array $schemas ) : Iface
106
        {
107
                $this->schemas = $schemas;
3✔
108
                return $this;
3✔
109
        }
110

111

112
        /**
113
         * Returns the database connection
114
         *
115
         * @param string $name Name from the resource configuration
116
         * @return \Aimeos\MW\DB\Connection\Iface Database connection
117
         */
118
        protected function acquire( $name = 'db' ) : \Aimeos\MW\DB\Connection\Iface
119
        {
120
                return $this->dbm->acquire( $name );
×
121
        }
122

123

124
        /**
125
         * Releases the database connection
126
         *
127
         * @param \Aimeos\MW\DB\Connection\Iface $conn Database connection
128
         * @param string $name Name from the resource configuration
129
         */
130
        protected function release( \Aimeos\MW\DB\Connection\Iface $conn, $name = 'db' )
131
        {
132
                return $this->dbm->release( $conn, $name );
×
133
        }
134

135

136
        /**
137
         * Executes a given SQL statement.
138
         *
139
         * @param string $sql SQL statement to execute
140
         * @param string $name Name from the resource configuration
141
         * @return \Aimeos\MW\Setup\Task\Iface Task object for fluent interface
142
         */
143
        protected function execute( string $sql, string $name = 'db' ) : Iface
144
        {
145
                $conn = $this->acquire( $name );
×
146
                $conn->create( $sql )->execute()->finish();
×
147
                $this->release( $conn, $name );
×
148
                return $this;
×
149
        }
150

151

152
        /**
153
         * Executes a list of given SQL statements.
154
         *
155
         * @param string[] $list List of SQL statement to execute
156
         * @param string $name Name from the resource configuration
157
         * @return \Aimeos\MW\Setup\Task\Iface Task object for fluent interface
158
         */
159
        protected function executeList( array $list, string $name = 'db' ) : Iface
160
        {
161
                $conn = $this->acquire( $name );
×
162

163
                foreach( $list as $sql ) {
×
164
                        $conn->create( $sql )->execute()->finish();
×
165
                }
166

167
                $this->release( $conn, $name );
×
168
                return $this;
×
169
        }
170

171

172
        /**
173
         * Returns the schemas specified by the given resource name.
174
         *
175
         * @param \Aimeos\MW\DB\Connection\Iface $conn Connection with insert statement executed at last
176
         * @param string $rname Resource name of the connection the table belongs to
177
         * @param string|null $sequence Name of the sequence which generated the last ID (only Oracle)
178
         * @return string|null Last inserted ID or null if not available
179
         */
180
        protected function getLastId( \Aimeos\MW\DB\Connection\Iface $conn, string $rname, string $sequence = null ) : ?string
181
        {
182
                $adapter = $this->getSchema( $rname )->getName();
×
183
                $map = [
×
184
                        'db2' => 'SELECT IDENTITY_VAL_LOCAL()',
×
185
                        'mysql' => 'SELECT LAST_INSERT_ID()',
×
186
                        'oracle' => 'SELECT ' . $sequence . '.CURRVAL FROM DUAL',
×
187
                        'pgsql' => 'SELECT lastval()',
×
188
                        'sqlite' => 'SELECT last_insert_rowid()',
×
189
                        'sqlsrv' => 'SELECT @@IDENTITY',
×
190
                        'sqlanywhere' => 'SELECT @@IDENTITY',
×
191
                ];
×
192

193
                if( !isset( $map[$adapter] ) ) {
×
194
                        throw new \Aimeos\MW\Setup\Exception( sprintf( 'Unsupported adapter: %1$s', $adapter ) );
×
195
                }
196

197
                $result = $conn->create( str_replace( ':seq:', $sequence, $map[$adapter] ) )->execute();
×
198
                $row = $result->fetch( \Aimeos\MW\DB\Result\Base::FETCH_NUM );
×
199
                $result->finish();
×
200

201
                return $row && isset( $row[0] ) ? $row[0] : null;
×
202
        }
203

204

205
        /**
206
         * Returns the schemas specified by the given resource name.
207
         *
208
         * @param string $name Name from resource configuration
209
         * @return \Aimeos\MW\Setup\DBSchema\Iface
210
         */
211
        protected function getSchema( string $name ) : \Aimeos\MW\Setup\DBSchema\Iface
212
        {
213
                if( !isset( $this->schemas[$name] ) ) {
3✔
214
                        return $this->schema;
3✔
215
                }
216

217
                return $this->schemas[$name];
×
218
        }
219

220

221
        /**
222
         * Returns the DBAL schema manager for the given resource name
223
         *
224
         * @param string $name Name from resource configuration
225
         * @return \Doctrine\DBAL\Schema\AbstractSchemaManager DBAL schema manager
226
         */
227
        protected function getSchemaManager( string $rname ) : \Doctrine\DBAL\Schema\AbstractSchemaManager
228
        {
229
                $conn = $this->acquire( $rname );
×
230
                $dbal = $conn->getRawObject();
×
231
                $this->release( $conn, $rname );
×
232

233
                if( !( $dbal instanceof \Doctrine\DBAL\Connection ) ) {
×
234
                        throw new \Aimeos\MW\Setup\Exception( 'Not a DBAL connection' );
×
235
                }
236

237
                return $dbal->getSchemaManager();
×
238
        }
239

240

241
        /**
242
         * Returns the setup task paths ordered by their dependencies
243
         *
244
         * @return string[] List of file system paths
245
         */
246
        protected function getSetupPaths() : array
247
        {
248
                return $this->paths;
×
249
        }
250

251

252
        /**
253
         * Executes a given SQL statement and returns the value of the named column and first row.
254
         *
255
         * @param string $sql SQL statement to execute
256
         * @param string $column Column name to retrieve
257
         * @param string $name Name from the resource configuration
258
         * @return mixed Column value
259
         */
260
        protected function getValue( string $sql, string $column, string $name = 'db' )
261
        {
262
                $conn = $this->acquire( $name );
×
263

264
                try
265
                {
266
                        $result = $conn->create( $sql )->execute();
×
267

268
                        if( ( $row = $result->fetch() ) === null ) {
×
269
                                throw new \Aimeos\MW\Setup\Exception( sprintf( 'No rows found: %1$s', $sql ) );
×
270
                        }
271

272
                        $result->finish();
×
273

274
                        if( array_key_exists( $column, $row ) === false ) {
×
275
                                throw new \Aimeos\MW\Setup\Exception( sprintf( 'No column "%1$s" found: %2$s', $column, $sql ) );
×
276
                        }
277

278
                        $this->release( $conn, $name );
×
279
                }
280
                catch( \Exception $e )
×
281
                {
282
                        $this->release( $conn, $name );
×
283
                        throw $e;
×
284
                }
285

286
                return $row[$column];
×
287
        }
288

289

290
        /**
291
         * Prints the message for the current test.
292
         *
293
         * @param string $msg Current message
294
         * @param int $level Indent level of the message (default: 0 )
295
         * @param string|null $status Current status
296
         * @return \Aimeos\MW\Setup\Task\Iface Task object for fluent interface
297
         */
298
        protected function msg( string $msg, int $level = 0, string $status = null ) : Iface
299
        {
300
                $pre = '';
3✔
301
                for( $i = 0; $i < 2 * $level; $i++ ) {
3✔
302
                        $pre .= ' ';
×
303
                }
304

305
                echo str_pad( $pre . $msg, 70 ) . ( $status !== null ? $status . PHP_EOL : '' );
3✔
306
                return $this;
3✔
307
        }
308

309

310
        /**
311
         * Prints the status for the current test.
312
         *
313
         * @param string $status Current status
314
         * @return \Aimeos\MW\Setup\Task\Iface Task object for fluent interface
315
         */
316
        protected function status( string $status ) : Iface
317
        {
318
                echo $status . PHP_EOL;
3✔
319
                return $this;
3✔
320
        }
321

322

323
        /**
324
         * Extracts the table definitions from the given content.
325
         *
326
         * @param string $content Content of the file to parse
327
         * @return string[] Associative list of table names with table create statements ordered like in the file
328
         */
329
        protected function getTableDefinitions( string $content ) : array
330
        {
331
                $defs = [];
3✔
332
                $matches = [];
3✔
333

334
                $regex = '/CREATE TABLE \"?([a-zA-Z0-9_]+)\"? .*([\r\n]{2,4}|$)/sU';
3✔
335
                if( preg_match_all( $regex, $content, $matches, PREG_SET_ORDER ) === false ) {
3✔
336
                        throw new \Aimeos\MW\Setup\Exception( 'Unable to get table definitions' );
×
337
                }
338

339
                foreach( $matches as $match ) {
3✔
340
                        $defs[$match[1]] = $match[0];
3✔
341
                }
342

343
                return $defs;
3✔
344
        }
345

346

347
        /**
348
         * Extracts the index definitions from the given content.
349
         *
350
         * @param string $content Content of the file to parse
351
         * @return string[] Associative list of index names with index create statements ordered like in the file
352
         */
353
        protected function getIndexDefinitions( string $content ) : array
354
        {
355
                $defs = [];
3✔
356
                $matches = [];
3✔
357

358
                if( preg_match_all( '/CREATE [a-zA-Z]* ?INDEX \"?([a-zA-Z0-9_]+)\"? ON \"?([a-zA-Z0-9_]+)\"? .+([\r\n]{2,4}|$)/sU', $content, $matches, PREG_SET_ORDER ) === false ) {
3✔
359
                        throw new \Aimeos\MW\Setup\Exception( 'Unable to get index definitions' );
×
360
                }
361

362
                foreach( $matches as $match ) {
3✔
363
                        $name = $match[2] . '.' . $match[1];
3✔
364
                        $defs[$name] = $match[0];
3✔
365
                }
366

367
                return $defs;
3✔
368
        }
369

370

371
        /**
372
         * Extracts the trigger definitions from the given content.
373
         *
374
         * @param string $content Content of the file to parse
375
         * @return string[] Associative list of trigger names with trigger create statements ordered like in the file
376
         */
377
        protected function getTriggerDefinitions( string $content ) : array
378
        {
379
                $defs = [];
3✔
380
                $matches = [];
3✔
381

382
                $regex = '/CREATE TRIGGER \"?([a-zA-Z0-9_]+)\"? .*([\r\n]{2,4}|$)/sU';
3✔
383
                if( preg_match_all( $regex, $content, $matches, PREG_SET_ORDER ) === false ) {
3✔
384
                        throw new \Aimeos\MW\Setup\Exception( 'Unable to get trigger definitions' );
×
385
                }
386

387
                foreach( $matches as $match ) {
3✔
388
                        $defs[$match[1]] = $match[0];
3✔
389
                }
390

391
                return $defs;
3✔
392
        }
393

394

395
        /**
396
         * Updates the database to get from the source schema to the destination schema
397
         *
398
         * @param \Doctrine\DBAL\Schema\Schema $src Source schema object
399
         * @param \Doctrine\DBAL\Schema\Schema $dest Destination schema object
400
         * @param string $rname Resource name of the connection the table belongs to
401
         * @return \Aimeos\MW\Setup\Task\Iface Task object for fluent interface
402
         */
403
        protected function update( \Doctrine\DBAL\Schema\Schema $src, \Doctrine\DBAL\Schema\Schema $dest, string $rname )
404
        {
405
                $conn = $this->acquire( $rname );
×
406

407
                try
408
                {
409
                        $dbal = $conn->getRawObject();
×
410

411
                        if( !( $dbal instanceof \Doctrine\DBAL\Connection ) ) {
×
412
                                throw new \Aimeos\MW\Setup\Exception( 'Not a DBAL connection' );
×
413
                        }
414

415
                        $platform = $dbal->getDatabasePlatform();
×
416

417
                        foreach( $src->getMigrateToSql( $dest, $platform ) as $sql ) {
×
418
                                $conn->create( $sql )->execute()->finish();
×
419
                        }
420
                }
421
                catch( \Exception $e )
×
422
                {
423
                        $this->release( $conn, $rname );
×
424
                        throw $e;
×
425
                }
426

427
                $this->release( $conn, $rname );
×
428
                return $this;
×
429
        }
430
}
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