inovxapp / dbstate
Declarative database schema-as-code for Laravel.
Requires
- php: ^8.2|^8.3|^8.4
- laravel/framework: ^10.0|^11.0|^12.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^9.0|^10.0
- phpunit/phpunit: ^10.5
README
DBState is a Laravel tool for managing database schemas using a declarative, schema-as-code approach.
Describe your tables using simple, versionable .dbstate.php files, then DBState synchronizes your database schema β no manual migrations required.
Inspired by the declarative approaches of Ansible and Docker Compose: you declare the desired state, and DBState applies the diff.
π Features
- Declarative schema : describe the desired structure and DBState applies the diff.
- Automatic table diffs (add, delete, modify columns).
- No SQL required.
- Custom root folder via
DBSTATE_FOLDER. - Schema import : automatically generate .dbstate.php files from your existing database.
π¦ Installation
composer require inovxapp/dbstate
Publish config and base structure (honoring DBSTATE_FOLDER if set):
php artisan vendor:publish --tag=dbstate
# or publish separated
php artisan vendor:publish --tag=dbstate-config
php artisan vendor:publish --tag=dbstate-database
Set DBSTATE_FOLDER in your .env before publishing if you want to customize the destination folder for all generated files (see below).
βοΈ Configuration
A config file is published to:
config/dbstate.php
π‘ Custom Root Folder
Set a custom root folder (optional) in .env files using :
DBSTATE_FOLDER=dbstate
This lets you place DBState files anywhere in your project.
π Folder Structure
Default structure :
config/dbstate.php
database/dbstate/
βββ actions/
βββ backups/
βββ import/
βββ tables/
βββ *.dbstate.php
The published configuration file lives in config/dbstate.php.
With DBSTATE_FOLDER=dbstate:
dbstate/
βββ config/dbstate.php
βββ database/
βββ actions/
βββ backups/
βββ import/
βββ tables/
βββ *.dbstate.php
β¨ Quick Start
- Start DBState in terminal:
php artisan dbstate
Need a quieter diff or to include package tables?
php artisan dbstate --compact # compact output php artisan dbstate --with-package-tables # include tables listed in packages_tables when running CheckDiff
- Import your existing tables:
4/7 - ImportMyDB - Create all DBState table from your DB
This will automatically generate .dbstate.php files from your existing database in the /import folder.
Then you can decide to move automatically all this file in the /tables folder
- Create a table definition:
/tables/posts.dbstate.php <= create *.dbstate.php in the tables folder
<?php // 1 - TABLE NAME $TableName = "posts"; // 2 - DESIRED STATE $DesiredTableState = [ 'id' => 'id', 'title' => ['string' => 255, 'nullable'], 'type' => ['string' => 255], 'created_at' => ['timestamp', 'nullable'], 'updated_at' => ['timestamp', 'nullable'], ];
- Apply the desired schema: 1- CheckDiff to create Actions files (migration-like)
1/7 - CheckDiff - Check diff between DBState table and DB, then plan actions
2- RunActions to apply Actions files in your database
2/7 - RunActions - Apply pending action files (migration-like) to the database
- AuditModels - Used to prevent false positives or missing $casts definitions
5/7 - AuditModels - Detect DB tables without Laravel models and $cast missing (TableFromPackage, $cast)
- Delete a table:
/tables/posts.dbstate.php <= delete *.dbstate.php from the tables folder
π Commands
β β 1/5 - CheckDiff - Check diff between DBState table and DB, then plan actions
β β 2/5 - RunActions - Apply pending action files (migration-like) to the database
β β 3/5 - ImportMyDB - Create all DBState table from your DB
β β 4/5 - AuditModels - Detect DB tables without Laravel models and $cast missing (TableFromPackage, $cast)
β β 5/5 - RestoreTable
β β Exit DBState
π Writing Schema Files
Each .dbstate.php must return an array describing the table.
Available column types:
- id
- string
- integer
- boolean
- json
- text
- timestamp
- etc.
Example with indexes:
return [ 'table' => 'products', 'columns' => [ 'id' => ['type' => 'id'], 'name' => ['type' => 'string'], 'price' => ['type' => 'decimal', 'precision' => 8, 'scale' => 2], ], 'indexes' => [ ['columns' => ['name'], 'unique' => true], ], ];
π Examples
More examples are available in:
src/exemples/
β¨ Advanced usage
Advanced usage are available in:
docs/
π‘ Compatibility/Support
Framework :
- Laravel 10
- Laravel 11
- Laravel 12
Database : mysql, mariadb
π§ͺ Testing
DBState ships with two commands designed for testing and exploration:
ImportMyDB β generates .dbstate.php files from your existing database structure (read-only, does not modify the database). CheckDiff β shows the diff between your declared schema and the actual database and can generate action files (migration-like files) (read-only, does not modify the database).
π€ Contributing
Issues and PRs welcome. Please format code according to PSR-12.
π§± Section βRoadmap / Planned Featuresβ
We are actively expanding DbState. If you need additional features, feel free to open an issue or request one
π License
dbstate is source-available under the Business Source License 1.1.
You may use it in production and within your company, but you may not use it to create or offer a competing product or service.
See the LICENSE file for full details.
β Support
If DBState saves you time, consider starring the repository!