Installation
composer require ascetic-soft/rowcast-schema
Requires PHP 8.4+ and a PDO-compatible database.
Define Your Schema
Create a PHP file (e.g., database/schema.php) with a Schema class extending \RowcastSchema\Schema:
use RowcastSchema\Schema;
use RowcastSchema\Types\ColumnType;
return new class extends Schema {
public function define(): void {
$this->table('users', function ($table) {
$table->id();
$table->string('name', 255);
$table->timestamp('created_at')->useCurrent();
});
}
};
First Migration Generate a migration from your schema:
php vendor/bin/rowcast-schema generate:migration --schema=database/schema.php
This creates a reversible migration file (e.g., migrations/2024_05_01_000000_create_users_table.php).
Run the Migration
Use Laravel’s migrate artisan command:
php artisan migrate
Sync your live database with the schema definition:
php vendor/bin/rowcast-schema diff --schema=database/schema.php --connection=mysql
This outputs SQL to align the live schema with your definition.
Modular Schema Files
Split schema definitions across files (e.g., database/schema/users.php, database/schema/posts.php) and merge them in a root schema file:
return new class extends Schema {
public function define(): void {
$this->loadSchemaFromFile(__DIR__.'/users.php');
$this->loadSchemaFromFile(__DIR__.'/posts.php');
}
};
Reusable Schema Components Extract common table structures into helper methods:
protected function defineUserTable(): void {
$this->table('users', function ($table) {
$table->id();
$table->string('email', 255)->unique();
$table->timestamps();
});
}
Environment-Specific Config Use Laravel’s config to override schema behavior (e.g., disable foreign key checks):
// config/rowcast-schema.php
return [
'disable_foreign_keys' => env('DB_CONNECTION') === 'testing',
];
Custom Migration Naming Override the default migration naming convention:
php vendor/bin/rowcast-schema generate:migration --schema=database/schema.php --prefix=custom_
Targeted Migration Generation Generate migrations for specific tables only:
php vendor/bin/rowcast-schema generate:migration --schema=database/schema.php --tables=users,posts
Rollback Handling
Leverage the auto-generated down() method in migrations. For complex logic, extend the migration class:
use RowcastSchema\Migrations\Migration;
class CustomMigration extends Migration {
public function down(): void {
// Custom rollback logic
$this->dropForeignKey('users', 'posts_user_id');
parent::down();
}
}
Service Provider Binding Bind the schema resolver to Laravel’s container for dynamic schema loading:
// app/Providers/AppServiceProvider.php
use RowcastSchema\SchemaResolver;
public function register(): void {
$this->app->singleton(SchemaResolver::class, function ($app) {
return new SchemaResolver(__DIR__.'/../database/schema.php');
});
}
Artisan Command Integration Create a custom artisan command to wrap schema operations:
use Illuminate\Console\Command;
use RowcastSchema\Schema;
class SyncSchemaCommand extends Command {
protected $signature = 'schema:sync {--connection=mysql}';
protected $description = 'Sync database schema with definition';
public function handle(): void {
$schema = include __DIR__.'/../database/schema.php';
$diff = $schema->diff($this->option('connection'));
$diff->apply();
}
}
Event Listeners for Schema Changes Listen to migration events to trigger schema validation:
// app/Listeners/ValidateSchemaAfterMigration.php
use RowcastSchema\Schema;
use Illuminate\Database\Events\MigrationFinished;
public function handle(MigrationFinished $event): void {
$schema = include __DIR__.'/../database/schema.php';
if (!$schema->isValid($event->connection->getDatabaseName())) {
throw new \RuntimeException('Schema validation failed!');
}
}
Type-Safe Query Building Use the generated schema to build Rowcast queries:
use RowcastSchema\Schema;
use Rowcast\Rowcast;
$schema = include __DIR__.'/database/schema.php';
$query = Rowcast::table('users')
->select(['id', 'name'])
->where('active', true);
Dynamic Rowcast Casting Generate Rowcast models from your schema:
$schema = include __DIR__.'/database/schema.php';
$userModel = $schema->generateRowcastModel('users');
// Returns a Rowcast model class for the 'users' table.
Case Sensitivity in Table/Column Names
lower_case_table_names=0) treat names case-sensitively.$this->table('Users', function ($table) { ... })->setName('users');
Foreign Key Constraints
down() method or use --disable-foreign-keys flag:
php vendor/bin/rowcast-schema generate:migration --disable-foreign-keys
Schema Caching
diff() calls without changes may slow down development.$resolver = new SchemaResolver(__DIR__.'/schema.php');
$resolver->cacheFor(3600); // Cache for 1 hour
PHP 8.4+ Features
array_unpack and named arguments. Older PHP versions will fail.composer.json enforces PHP 8.4:
"require": {
"php": "^8.4"
}
Dry-Run Diffs Preview changes before applying:
php vendor/bin/rowcast-schema diff --schema=database/schema.php --dry-run
Verbose Output Enable debug mode for detailed diffs:
php vendor/bin/rowcast-schema diff --schema=database/schema.php --verbose
Schema Validation Validate your schema against a live database:
php vendor/bin/rowcast-schema validate --schema=database/schema.php
Schema Versioning
Use Git to track schema changes alongside migrations. Commit both schema.php and migration files.
Partial Migrations Generate migrations incrementally:
# Generate migration for only new tables
php vendor/bin/rowcast-schema generate:migration --only-new
Custom Column Types
Extend ColumnType for database-specific types (e.g., PostgreSQL jsonb):
use RowcastSchema\Types\ColumnType;
class JsonbType extends ColumnType {
public function getSql(): string {
return 'jsonb';
}
}
Then use it in your schema:
$table->custom('data', new JsonbType());
Index Optimization Explicitly define indexes to avoid auto-generated ones:
$table->index('email');
$table->unique('email');
Transaction Handling Wrap schema syncs in transactions for safety:
use Illuminate\Support\Facades\DB;
DB::transaction(function () {
$schema = include __DIR__.'/database/schema.php';
$diff = $schema->diff('mysql');
$diff->apply();
});
Testing
Use the --test flag to generate migrations without executing them:
php vendor/bin/rowcast-schema generate:migration --test > test_migration.php
CI/CD Integration Add schema validation
How can I help you explore Laravel packages today?