Skip to content

Latest commit

 

History

History
338 lines (262 loc) · 12.3 KB

schema.md

File metadata and controls

338 lines (262 loc) · 12.3 KB

Schema Builder Reference

Use Schema (a thin facade over Blueprint) to create, alter and drop MySQL tables from PHP. By default the table name is used as-is (no prefix is applied); call Schema::withPrefix($prefix) to apply one.

See Defining models for the model-side $timestamps and $soft_deletes properties that rely on the columns described here.



Creating tables

use BitApps\WPDatabase\Schema;

Schema::create('orders', function ($table) {
    $table->id();
    $table->bigint('user_id')->unsigned()
        ->foreign('users', 'id')
        ->onDelete()->cascade();
    $table->varchar('status', 32)->defaultValue('pending');
    $table->decimal('total')->nullable();
    $table->timestamps();
});

The callback receives a Blueprint instance. Column-definition methods return the same Blueprint, so modifiers chain directly:

$table->varchar('slug', 100)->nullable()->unique();

Column types

All types listed below are registered in Blueprint::isValidType() and exposed as magic methods via Blueprint::__call(). The first argument is always the column name; the optional second argument sets the length (or, for ENUM/SET, the list of allowed values as an array).

String / binary

Method SQL type Notes
char($name, $length = null) CHAR
varchar($name, $length = null) VARCHAR
binary($name, $length = null) BINARY Column type — see note
varbinary($name, $length = null) VARBINARY Column type — see note
json($name, $length = null) JSON

binary / varbinary are column types, not modifiers. These define columns with the BINARY / VARBINARY SQL type. A chained binary() modifier (which would have flagged an existing column as binary) was removed in an earlier refactor; only the type declarations remain. Use $table->binary('data', 16) to define a BINARY(16) column.

Text / blob

Method SQL type
tinytext($name) TINYTEXT
text($name) TEXT
mediumtext($name) MEDIUMTEXT
longtext($name) LONGTEXT
tinyblob($name) TINYBLOB
blob($name) BLOB
mediumblob($name) MEDIUMBLOB
longblob($name) LONGBLOB

Numeric

Method SQL type Notes
bit($name, $length = null) BIT
tinyint($name, $length = null) TINYINT
bool($name) BOOL
boolean($name) BOOLEAN Alias of bool
smallint($name, $length = null) SMALLINT
mediumint($name, $length = null) MEDIUMINT
int($name, $length = null) INT
integer($name, $length = null) INTEGER Alias of int
bigint($name, $length = null) BIGINT
float($name, $length = null) FLOAT
double($name, $length = null) DOUBLE
double_precision($name, $length = null) DOUBLE PRECISION Underscore maps to space
decimal($name, $length = null) DECIMAL
dec($name, $length = null) DEC Alias of decimal

Enumerated

Method SQL type Notes
enum($name, array $enum) ENUM Second arg is an array of allowed string values
set($name, array $set) SET Second arg is an array of allowed string values
$table->enum('status', ['draft', 'published', 'archived']);
$table->set('permissions', ['read', 'write', 'delete']);

Date / time

Method SQL type
date($name) DATE
datetime($name) DATETIME
timestamp($name) TIMESTAMP
time($name) TIME
year($name) YEAR

Column modifiers

Chain any of these immediately after a type call. Each returns the Blueprint so multiple modifiers can be stacked.

Modifier Effect
nullable() Emits NULL instead of NOT NULL.
defaultValue($value) Adds DEFAULT $value. Integers are emitted unquoted; CURRENT_TIMESTAMP and NULL are also unquoted; all other strings are single-quoted automatically.
unsigned() Adds UNSIGNED (meaningful on numeric columns).
zeroFill() Adds ZEROFILL.
primary() Registers the column in the PRIMARY KEY clause and forces NOT NULL.
unique($column = null) Registers a UNIQUE INDEX. Without an argument it indexes the current column. Pass an explicit column name or an array of column names to create a named or composite unique index.
index($type = null) Registers an INDEX on the current column. Pass an index-type prefix string (e.g. 'FULLTEXT ') to customise the index clause.
length($length) Sets the column length. Accepts an array for ENUM/SET allowed values — each element is single-quoted and the list is comma-joined automatically.

Column helpers

Higher-level helpers that expand to one or more fully configured column definitions.

id()

$table->id();

Defines id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT and registers it as the PRIMARY KEY. Shorthand for:

$table->bigint('id')->unsigned()->increments()->primary();

increments()

$table->bigint('sort_order')->increments();
// or pass a name to create the column and apply AUTO_INCREMENT in one call:
$table->increments('sort_order');   // creates BIGINT sort_order NOT NULL AUTO_INCREMENT

Adds AUTO_INCREMENT to the most recently defined column. When called with a column name argument it first creates a BIGINT column with that name, then applies AUTO_INCREMENT.

string()

$table->string('email');
$table->string('slug')->unique();

Defines a VARCHAR(255) column. Equivalent to $table->varchar($name)->length(255).

timestamps()

$table->timestamps();

Adds two nullable TIMESTAMP columns — created_at and updated_at — both defaulting to NULL.

The model-side $timestamps = true property (see Defining models) instructs the ORM to auto-populate these columns on every insert and update. The table must contain these two columns for $timestamps to function.

softDeletes()

$table->softDeletes();

Adds a single nullable TIMESTAMP column named deleted_at, defaulting to NULL.

The model-side $soft_deletes = true property (see Defining models) instructs delete() to set deleted_at rather than removing the row. Reads return all rows by default — including trashed ones. To enable automatic filtering, also declare public $soft_delete_scope = true; on the model: reads then exclude trashed rows automatically. Use ->withTrashed() to include them, or ->onlyTrashed() to return only trashed rows. See Limitations for the refresh() edge case.


Foreign keys

Foreign key constraints are declared by chaining on the column that holds the FK value:

$table->bigint('user_id')->unsigned()
    ->foreign('users', 'id')       // references users(id)
    ->onDelete()->cascade()        // ON DELETE CASCADE
    ->onUpdate()->restrict();      // ON UPDATE RESTRICT
Method Description
foreign($ref, $refCol) Declares a FOREIGN KEY from the current column to column $refCol on table $ref. $ref is used as-is — pass the full (already-prefixed) table name; no prefix is applied.
onDelete() Selects the ON DELETE slot for the next action modifier.
onUpdate() Selects the ON UPDATE slot for the next action modifier.
cascade() Applies CASCADE. If onDelete() or onUpdate() was called first, only that slot is set; otherwise both ON DELETE and ON UPDATE are set to CASCADE.
restrict() Applies RESTRICT. Same scoping rules as cascade().
setNull() Applies SET NULL. Same scoping rules as cascade().

Altering & dropping

Use Schema::edit to alter an existing table. Inside the callback, call the same column definitions as in Schema::create to add columns, and use the drop/rename helpers to modify or remove existing ones.

Schema::edit('orders', function ($table) {
    $table->varchar('reference', 64)->nullable();   // ADD COLUMN
    $table->tinyint('priority')->defaultValue(0);   // ADD COLUMN
    $table->dropColumn('legacy_notes');             // DROP COLUMN
    $table->dropTimestamps();                       // DROP created_at + updated_at
});

Modifying an existing column

Chain change() on a column definition inside Schema::edit to emit MODIFY COLUMN instead of ADD COLUMN:

Schema::edit('orders', function ($table) {
    $table->varchar('reference', 128)->change();    // MODIFY COLUMN — widen the length
});

Drop helpers

Method Emitted SQL
dropColumn($column) DROP $column
dropTimestamps() DROP COLUMN created_at, DROP COLUMN updated_at
dropIndex($indexes) DROP INDEX \name`` — accepts a single name string or an array of names
dropUnique($indexes) Alias of dropIndex — unique indexes are dropped the same way as regular indexes, by name
dropForeign($keys) DROP FOREIGN KEY \name`` — accepts a single key name string or an array
dropPrimary() DROP PRIMARY KEY

renameColumn()

// Direct call — renames a single column on the table
Schema::renameColumn('orders', 'fname', 'first_name');
// Emits: ALTER TABLE `orders` CHANGE fname first_name
// (wp_ prefix appears only if withPrefix was used, e.g. Schema::withPrefix('wp_')->renameColumn(...))

Renames a column via MySQL's CHANGE clause. Note that this implementation emits CHANGE old_name new_name without repeating the column definition, which is accepted by MySQL 8.0+ (which supports bare RENAME COLUMN) but may require the full type specification on older MySQL / MariaDB versions.


Table operations

All methods are available as static calls (Schema::create(...)) and as instance calls on (new Schema())->create(...) — both are equivalent thanks to __callStatic.

Method Description
Schema::create($table, Closure $callback) CREATE TABLE IF NOT EXISTS. The callback receives the Blueprint.
Schema::edit($table, Closure $callback) ALTER TABLE. Use to add columns, drop columns, add/drop indexes and foreign keys.
Schema::drop($table) DROP TABLE IF EXISTS.
Schema::rename($table, $newName) ALTER TABLE … RENAME TO. Both names are used as-is unless Schema::withPrefix() is used (no prefix by default).
Schema::withPrefix($prefix) Sets the prefix applied for this call (there is no prefix by default). Returns a Schema instance; chain .create(), .edit(), etc.
Schema::withWpPrefix() Sets the prefix to Connection::getPrefix() (WordPress prefix + plugin prefix), so the table matches what Models use. Returns a Schema instance; chain .create(), .edit(), etc.
// Literal prefix — table resolves as "custom_orders"
// (without withPrefix/withWpPrefix, the bare name "orders" is used — no prefix is applied)
Schema::withPrefix('custom_')->create('orders', function ($table) {
    $table->id();
    $table->string('reference');
    $table->timestamps();
});

// Match the Model prefix (e.g. wp_ or wp_myplugin_) — table resolves as "wp_orders"
Schema::withWpPrefix()->create('orders', function ($table) {
    $table->id();
    $table->string('reference');
    $table->timestamps();
});

Limitations & known issues

  • Schema builder uses the literal table name by design. Schema::create() passes the name through as-is — no WordPress prefix is added automatically, so existing tables are never relocated. Use Schema::withPrefix('your_prefix_') for a literal prefix, or Schema::withWpPrefix() to match the prefix Models use (Connection::getPrefix()). The $prefix property intentionally defaults to null (not '') to preserve bare-table behaviour for plugins that rely on it.