Migrations¶
LacePHP’s migration subsystem lets you version and evolve your database schema in code, keeping every change tracked in your version control system rather than in ad-hoc SQL scripts. It comprises:
MigrationManager: handles discovery, execution and tracking of migration classes.
Blueprint: a fluent PHP API to describe tables, columns and indexes without raw SQL.
Grammar: compiles Blueprint definitions into executable SQL statements.
Welt: a simple façade that ties Blueprint + Grammar + ConnectionManager together for common operations.
Why Migrations Matter¶
Version control: schema changes live in code, so your entire team applies the same updates.
Reproducible deployments: new environments build the required schema automatically (php lace cobble run).
Readable definitions: Blueprint methods (increments, string, timestamps) read like intent, not opaque SQL.
MigrationManager¶
use Lacebox\Sole\Cobble\MigrationManager;
// Run all pending migrations
MigrationManager::runAll();
How it works:
Ensures a cobblestones table exists, which records each migration class name.
Scans shoebox/migrations/*.php for classes under Shoebox/Migrations/.
Skips any class already recorded in cobblestones.
Instantiates each new class and calls its up() method.
Records the class name in the database so it never runs twice.
Example migration stub generated by php lace cobble create CreateUsersTable:
<?php
namespace Shoebox\Migrations;
class CreateUsersTable
{
public function up(): void
{
// your schema changes here
}
}
Blueprint¶
The Blueprint class helps you define a table in PHP:
use Lacebox\Sole\Cobble\Blueprint;
use Lacebox\Sole\Cobble\Welt;
class CreateUsersTable
{
public function up(): void
{
Welt::create('users', function(Blueprint $bp) {
$bp->increments('id')
->string('name', 100)
->string('email', 150)
->timestamps()
->unique('email');
});
}
}
Common methods:
increments($col): auto-increment primary key.
string($col, $length=255): VARCHAR column.
integer($col, $auto=false, $unsigned=false): INT column.
timestamps(): nullable created_at + updated_at.
softDeletes(): nullable deleted_at.
unique($cols, $name=null) / index(…) / primary(…): index definitions.
dropColumn($col) / renameColumn($from,$to): schema alterations.
Welt¶
Welt provides shorthand methods that combine Blueprint + Grammar + PDO execution:
use Lacebox\Sole\Cobble\Welt;
// Create a new table
Welt::create('comments', function($bp) {
$bp->increments('id')
->text('body')
->integer('post_id', false, true)
->timestamps();
});
// Alter an existing table
Welt::table('users', function($bp) {
$bp->string('nickname', 50);
});
// Drop a table if it exists
Welt::dropIfExists('old_logs');
Taking Full Advantage¶
Use Welt in migrations to avoid boilerplate SQL.
Compose multiple alterations in one migration by chaining Blueprint calls.
Track changes: run php lace cobble run in CI/CD to apply pending migrations automatically.
Review SQL: if you need fine control, inspect $grammar->compileCreate() output before execution.
Best Practices¶
Atomic migrations: one change per file (create table, add column, seed data).
Readable names: prefix classes/files with date/time or descriptive titles (e.g. AddPostsTable_20250715).
Peer review: treat migrations like code—review carefully before merging.
Back up production data before applying migrations that drop or rename columns.
Warning
No automatic rollback: migrations only define up()—if you require down-methods, extend the manager.
Data loss: dropping or renaming columns can delete data—migrate data in stages if needed.
Database compatibility: ensure your SQL and types work across your target DBMS (SQLite, MySQL, PostgreSQL).
With MigrationManager, Blueprint, Grammar and Welt, you can define, run and track schema changes entirely in PHP, keeping database evolution as part of their normal development workflow.