Skip to content

Commit 21c085d

Browse files
committed
Add transactional migration
1 parent 7ebff58 commit 21c085d

3 files changed

Lines changed: 71 additions & 34 deletions

File tree

src/Console/Command/MigrationCommand.php

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -50,46 +50,52 @@ public function reset(): void
5050
}
5151

5252
/**
53-
* Create a migration in both directions
53+
* Run migration action (up, rollback, reset)
5454
*
55-
* @param string $type
55+
* @param string $type
5656
* @return void
5757
* @throws Exception
5858
*/
5959
private function factory(string $type): void
6060
{
61-
$migrations = [];
6261

63-
// We include all migrations files and collect it for make great manage
64-
foreach ($this->getMigrationFiles() as $file) {
65-
$migrations[$file] = explode('.', basename($file))[0];
66-
}
62+
$migrations = $this->collectMigrationFiles();
6763

68-
// We create the migration database status
69-
$this->createMigrationTable();
7064

71-
$action = 'make' . strtoupper($type);
65+
$connection = $this->arg->getParameter("--connection", config("database.default"));
66+
7267

73-
$this->$action($migrations);
68+
try {
69+
Database::connection($connection);
70+
} catch (Exception $exception) {
71+
throw new MigrationException($exception->getMessage(), (int)$exception->getCode());
72+
}
73+
74+
try {
75+
Database::startTransaction();
76+
// We create the migration database status
77+
$this->createMigrationTable($connection);
78+
79+
$action = 'make' . ucfirst($type);
80+
if (!method_exists($this, $action)) {
81+
throw new MigrationException("Migration action '$action' not found.");
82+
}
83+
$this->$action($migrations);
84+
Database::commitTransaction();
85+
} catch (Exception $exception) {
86+
Database::rollbackTransaction();
87+
throw new MigrationException($exception->getMessage(), (int)$exception->getCode());
88+
}
7489
}
7590

7691
/**
77-
* Create the migration status table
92+
* Create the migration status table if it does not exist
7893
*
7994
* @return void
8095
* @throws ConnectionException
8196
*/
8297
private function createMigrationTable(): void
8398
{
84-
$connection = $this->arg->getParameter("--connection", config("database.default"));
85-
86-
try {
87-
Database::connection($connection);
88-
} catch (Exception $exception) {
89-
echo Color::red("▶ Please check your database configuration on .env.json file\n");
90-
throw new MigrationException($exception->getMessage(), (int)$exception->getCode());
91-
}
92-
9399
$adapter = Database::getConnectionAdapter();
94100

95101
$table = $adapter->getTablePrefix() . config('database.migration', 'migrations');
@@ -121,9 +127,9 @@ private function createMigrationTable(): void
121127
}
122128

123129
/**
124-
* Up migration
130+
* Run all up migrations
125131
*
126-
* @param array $migrations
132+
* @param array $migrations
127133
* @return void
128134
* @throws ConnectionException
129135
* @throws QueryBuilderException
@@ -153,6 +159,7 @@ protected function makeUp(array $migrations): void
153159
(new $migration())->up();
154160
} catch (Exception $exception) {
155161
$this->throwMigrationException($exception, $migration);
162+
break;
156163
}
157164

158165
// Create new migration status
@@ -209,7 +216,7 @@ private function printExceptionMessage(string $message, string $migration): void
209216
$message = Color::red($message);
210217
$migration = Color::yellow($migration);
211218

212-
exit(sprintf("\nOn %s\n\n%s\n\n", $migration, $message));
219+
echo sprintf("\nOn %s\n\n%s\n\n", $migration, $message);
213220
}
214221

215222
/**
@@ -249,9 +256,9 @@ private function updateMigrationStatus(string $migration, int $batch): void
249256
}
250257

251258
/**
252-
* Rollback migration
259+
* Rollback all migrations in batch 1
253260
*
254-
* @param array $migrations
261+
* @param array $migrations
255262
* @return void
256263
* @throws ConnectionException
257264
* @throws QueryBuilderException
@@ -288,6 +295,7 @@ protected function makeRollback(array $migrations): void
288295
(new $migration())->rollback();
289296
} catch (Exception $exception) {
290297
$this->throwMigrationException($exception, $migration);
298+
return;
291299
}
292300

293301
break;
@@ -311,9 +319,9 @@ protected function makeRollback(array $migrations): void
311319
}
312320

313321
/**
314-
* Reset migration
322+
* Reset all migrations
315323
*
316-
* @param array $migrations
324+
* @param array $migrations
317325
* @return void
318326
* @throws ConnectionException
319327
* @throws QueryBuilderException
@@ -347,6 +355,7 @@ protected function makeReset(array $migrations): void
347355
(new $migration())->rollback();
348356
} catch (Exception $exception) {
349357
$this->throwMigrationException($exception, $migration);
358+
break;
350359
}
351360

352361
$this->getMigrationTable()->where('migration', $migration)->delete();
@@ -358,17 +367,31 @@ protected function makeReset(array $migrations): void
358367
}
359368

360369
/**
361-
* Get migration pattern
370+
* Get migration file paths
362371
*
363372
* @return array
364373
*/
365374
private function getMigrationFiles(): array
366375
{
367376
$file_pattern = $this->setting->getMigrationDirectory() . strtolower("/*.php");
368-
369377
return glob($file_pattern);
370378
}
371379

380+
/**
381+
* Collect migration files as [file => className]
382+
*
383+
* @return array
384+
*/
385+
private function collectMigrationFiles(): array
386+
{
387+
$files = $this->getMigrationFiles();
388+
$migrations = [];
389+
foreach ($files as $file) {
390+
$migrations[$file] = explode('.', basename($file))[0];
391+
}
392+
return $migrations;
393+
}
394+
372395
/**
373396
* Get migration table
374397
*

src/Database/Database.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,14 @@ public static function inTransaction(): bool
425425
* Validate a transaction
426426
*/
427427
public static function commit(): void
428+
{
429+
static::commitTransaction();
430+
}
431+
432+
/**
433+
* Validate a transaction
434+
*/
435+
public static function commitTransaction(): void
428436
{
429437
if (static::inTransaction()) {
430438
static::$adapter->getConnection()->commit();
@@ -435,6 +443,14 @@ public static function commit(): void
435443
* Cancel a transaction
436444
*/
437445
public static function rollback(): void
446+
{
447+
static::rollbackTransaction();
448+
}
449+
450+
/**
451+
* Cancel a transaction
452+
*/
453+
public static function rollbackTransaction(): void
438454
{
439455
if (static::inTransaction()) {
440456
static::$adapter->getConnection()->rollBack();

src/Support/Env.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44

55
namespace Bow\Support;
66

7-
use Bow\Application\Exception\ApplicationException;
87
use ErrorException;
9-
use InvalidArgumentException;
108

119
/**
1210
* Class Env
@@ -82,11 +80,11 @@ public function __construct(?string $filename = null)
8280
/**
8381
* Load env file
8482
*
85-
* @param string $filename
83+
* @param ?string $filename
8684
* @return void
8785
* @throws
8886
*/
89-
public static function configure(string $filename)
87+
public static function configure(?string $filename = null): void
9088
{
9189
if (static::$instance !== null) {
9290
return;

0 commit comments

Comments
 (0)