Skip to content

MigrationBackup ​

File: src/Services/MigrationBackup.php
Facade: Unusualify\Modularous\Facades\MigrationBackup

Provides data-safe migration helpers that snapshot table data and schema to the Laravel cache before running destructive migrations, then restore rows if a rollback is needed.

Supports MySQL, PostgreSQL, and SQLite. All cache keys are namespaced by the calling migration's filename, so concurrent migrations never collide.

How It Works ​

  1. Before migration — call backup(). The service snapshots the table's current rows and schema (column types, nullability, defaults, foreign keys) to the Laravel cache.
  2. Run migration — execute your Schema:: changes normally.
  3. On rollback — call restore(). The service re-inserts backed-up rows, adapting them to the current schema (new columns get type-appropriate defaults; removed columns are silently dropped).
  4. After rollback — call clearBackup() to remove the cache entries.

Key Methods ​

MethodSignatureDescription
backupbackup(string $table, ?array $columns, bool $includeRelated): voidSnapshot a table to cache. When $includeRelated is true (default), FK-referenced tables are also snapshotted.
restorerestore(?string $table): boolRestore rows from the snapshot. Pass null to restore every table backed up by this migration. Returns true on success.
clearBackupclearBackup(?string $table): voidRemove cached snapshots. Pass null to clear all snapshots for this migration.
getBackupgetBackup(?string $table): ?arrayInspect the raw snapshot data stored in cache.
getSchemaHistorygetSchemaHistory(?string $table): arrayReturn a log of column additions/removals/modifications detected during restore.

Usage in Migrations ​

php
use Unusualify\Modularous\Services\MigrationBackup;

class AddSkuToProductsTable extends Migration
{
    public function up(): void
    {
        $backup = app(MigrationBackup::class);
        $backup->backup('products');

        Schema::table('products', function (Blueprint $table) {
            $table->dropColumn('legacy_code');
            $table->string('sku')->unique();
        });
    }

    public function down(): void
    {
        $backup = app(MigrationBackup::class);
        $backup->restore('products');
        $backup->clearBackup('products');
    }
}

Foreign Key Handling ​

During restore, foreign key constraints are temporarily disabled:

DriverStatement
MySQLSET FOREIGN_KEY_CHECKS=0
PostgreSQLSET CONSTRAINTS ALL DEFERRED
SQLitePRAGMA foreign_keys=OFF

Constraints are re-enabled in a finally block, even if restore fails.

Schema Adaptation ​

When restoring rows after a schema change, the service:

  • Removes columns that no longer exist from the row data before inserting
  • Fills new columns with a type-appropriate default:
Column typeDefault
varchar, text, char''
int, bigint, smallint0
decimal, float, double0.0
boolean, tinyint(1)false
datetime, timestamp, date, jsonnull

Cache Key Format ​

migration_backup_{migration-file-slug}_{table-slug}

All backup keys for a migration are tracked under migration_backups_{migration-file-slug}, which is also cleared by clearBackup().