Skip to content

Database

Foundation Database provides three focused capabilities for WordPress applications: versioned schema migrations, a small inspectable query API, and a database-backed implementation of the Foundation Lock contract. It intentionally builds on wpdb, dbDelta(), and WordPress table prefixes instead of acting as a generic database abstraction.

Install the runtime package in the application:

composer require stellarwp/foundation-database

Foundation Database installs its Container, Lock, and WP-CLI runtime dependencies automatically. Install stellarwp/foundation-cli separately with --dev only when the project uses its migration and table generators.

Database services use the application’s existing container, provider graph, Foundation prefix, and WP-CLI command prefix:

Set a stable application prefix in the root config.php for a standalone plugin:

<?php declare(strict_types=1);

return [
	'foundation' => [
		'prefix' => 'your-plugin',
	],
];

With this prefix, Foundation uses these resources by default:

Resource Default
Migration table <wp_prefix>your_plugin_foundation_migrations
Lock table <wp_prefix>your_plugin_foundation_locks
Migration lock your-plugin-foundation-database-migrations
WP-CLI command wp your-plugin migrate

Complete WordPress applications that own the entire installation can keep the zero-configuration nx prefix. Standalone plugins should not share the default because another Foundation consumer could otherwise read the same migration ledger or contend for the same lock.

Keep the prefix stable after migrations have run. Changing it points the application at a different ledger and lock table, making every configured migration appear pending.

Package-specific settings in the root config.php override values derived from foundation.prefix:

return [
	'foundation' => [
		'prefix' => 'your-plugin',
	],
	'database' => [
		'migrations_table' => $_ENV['FOUNDATION_DATABASE_MIGRATIONS_TABLE'] ?? '',
		'locks_table'      => $_ENV['FOUNDATION_DATABASE_LOCKS_TABLE'] ?? '',
		'lock_name'        => $_ENV['FOUNDATION_DATABASE_LOCK_NAME'] ?? null,
		'lock_ttl'         => (int) ( $_ENV['FOUNDATION_DATABASE_LOCK_TTL'] ?? 300 ),
	],
];

Leave table names empty to use the scoped defaults. An overridden table name is the complete physical name and must include the WordPress table prefix itself. All physical table names must fit MySQL’s 64-character identifier limit.

The migration lock settings coordinate migration execution only. Applications selecting DatabaseLock for their own work choose each lock name and TTL when calling acquire().

In src/App.php, register WPCliProvider before DatabaseProvider, then register application providers that contribute migrations or select the database lock:

use StellarWP\Foundation\Container\Contracts\Providable;
use StellarWP\Foundation\Database;
use StellarWP\Foundation\WPCli;
use YourPlugin\Database as ApplicationDatabase;

/** @var list<class-string<Providable>> */
private const array PROVIDERS = [
	WPCli\WPCliProvider::class,
	Database\DatabaseProvider::class,
	ApplicationDatabase\Provider::class,
];

DatabaseProvider configures wpdb, schema services, migration storage, the migration lock, and the migrate command. It does not create tables, run migrations, or select DatabaseLock as the application’s general Lock implementation during WordPress bootstrap.