https://github.com/calebdw/laravel-sql-entities
:books: Manage SQL entities in Laravel with ease!
https://github.com/calebdw/laravel-sql-entities
database database-functions database-procedures database-triggers database-views laravel materialized-views php sql sql-entity views
Last synced: 3 months ago
JSON representation
:books: Manage SQL entities in Laravel with ease!
- Host: GitHub
- URL: https://github.com/calebdw/laravel-sql-entities
- Owner: calebdw
- License: mit
- Created: 2025-04-11T20:40:53.000Z (12 months ago)
- Default Branch: master
- Last Pushed: 2025-12-15T00:33:26.000Z (3 months ago)
- Last Synced: 2025-12-17T15:11:54.439Z (3 months ago)
- Topics: database, database-functions, database-procedures, database-triggers, database-views, laravel, materialized-views, php, sql, sql-entity, views
- Language: PHP
- Homepage:
- Size: 117 KB
- Stars: 29
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
Laravel's schema builder and migration system are great for managing tables and
indexes---but offer no built-in support for other SQL entities, such as
(materialized) views, procedures, functions, and triggers.
These often get handled via raw SQL in migrations, making them hard to manage,
prone to unknown conflicts, and difficult to track over time.
`laravel-sql-entities` solves this by offering:
- π¦ Class-based definitions: bringing views, functions, triggers, and more into your application code.
- π§ First-class source control: you can easily track changes, review diffs, and resolve conflicts.
- π§± Decoupled grammars: letting you support multiple drivers without needing dialect-specific SQL.
- π Lifecycle hooks: run logic at various points, enabling logging, auditing, and more.
- π Batch operations: easily create or drop all entities in a single command or lifecycle event.
- π§ͺ Testability: definitions are just code so theyβre easy to test, validate, and keep consistent.
Whether you're managing reporting views, business logic functions, or automation
triggers, this package helps you treat SQL entities like real, versioned parts
of your codebase---no more scattered SQL in migrations!
> [!NOTE]
> Migration rollbacks are not supported since the definitions always reflect the latest state.
>
> ["We're never going backwards. You only go forward." -Taylor Otwell](https://www.twitch.tv/theprimeagen/clip/DrabAltruisticEggnogVoHiYo-f6CVkrqraPsWrEht)
## π¦ Installation
First pull in the package using Composer:
```bash
composer require calebdw/laravel-sql-entities
```
The package looks for SQL entities under `database/entities/` so you might need to add
a namespace to your `composer.json` file, for example:
```diff
{
"autoload": {
"psr-4": {
"App\\": "app/",
+ "Database\\Entities\\": "database/entities/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
}
}
```
> [!TIP]
> This package looks for any files matching `database/entities` in the application's
> base path. This means it should automatically work for a modular setup where
> the entities might be spread across multiple directories.
## π οΈ Usage
### π§± SQL Entities
To get started, create a new class in a `database/entities/` directory
(structure is up to you) and extend the appropriate entity class (e.g. `View`, etc.).
For example, to create a view for recent orders, you might create the following class:
```php
select(['id', 'customer_id', 'status', 'created_at'])
->where('created_at', '>=', now()->subDays(30))
->toBase();
// could also use raw SQL
return <<<'SQL'
SELECT id, customer_id, status, created_at
FROM orders
WHERE created_at >= NOW() - INTERVAL '30 days'
SQL;
}
}
```
You can also override the name and connection:
```php
connection->statement(<<name()} TO other_user;
SQL);
}
#[Override]
public function dropping(Connection $connection): bool
{
if (/** should not drop */) {
return false;
}
/** other logic */
return true;
}
#[Override]
public function dropped(Connection $connection): void
{
/** logic */
}
}
```
#### βοΈ Handling Dependencies
Entities may depend on one another (e.g., a view that selects from another view).
To support this, each entity can declare its dependencies using the `dependencies()` method:
```php
where('created_at', '>=', now()->subDays(30))
->get();
```
#### π Function
The `Function_` class is used to create functions in the database.
> [!TIP]
> The class is named `Function_` as `function` is a reserved keyword in PHP.
In addition to the options above, you can use the following options to further customize the function:
```php
#### β‘ Trigger
The `Trigger` class is used to create triggers in the database.
In addition to the options above, you can use the following options to further customize the trigger:
```php
definition ?? <<<'SQL'
EXECUTE FUNCTION record_account_audit();
SQL;
}
}
```
### π§ Manager
The `SqlEntityManager` singleton is responsible for creating and dropping SQL entities at runtime.
You can interact with it directly, or use the `SqlEntity` facade for convenience.
```php
create(RecentOrdersView::class);
resolve('sql-entities')->create(new RecentOrdersView());
// Similarly, you can drop a single entity using the class or instance
SqlEntity::drop(RecentOrdersView::class);
// Create or drop all entities
SqlEntity::createAll();
SqlEntity::dropAll();
// You can also filter by type or connection
SqlEntity::createAll(types: View::class, connections: 'reporting');
SqlEntity::dropAll(types: View::class, connections: 'reporting');
```
#### β»οΈ `withoutEntities()`
Sometimes you need to run a block of logic (like renaming a table column) *without certain SQL entities present*.
The `withoutEntities()` method temporarily drops the selected entities, executes your callback, and then recreates them afterward.
If the database connection supports **schema transactions**, the entire operation is wrapped in one.
```php
getSchemaBuilder()->table('orders', function ($table) {
$table->renameColumn('old_customer_id', 'customer_id');
});
});
```
You can also restrict the scope to certain entity types or connections:
```php
getSchemaBuilder()->table('orders', function ($table) {
$table->renameColumn('old_customer_id', 'customer_id');
});
},
types: [RecentOrdersView::class, RecentHighValueOrdersView::class],
connections: ['reporting'],
);
```
After the callback, all affected entities are automatically recreated in dependency order.
### π» Console Commands
The package provides console commands to create and drop your SQL entities.
```bash
php artisan sql-entities:create [entities] [--connection=CONNECTION ...]
# Create all entities
php artisan sql-entities:create
# Create a specific entity
php artisan sql-entities:create 'Database\Entities\Views\RecentOrdersView'
# Create all entities on a specific connection
php artisan sql-entities:create -c reporting
# Similarly, drop all entities
php artisan sql-entities:drop
```
### π Automatic syncing when migrating (Optional)
You may want to automatically drop all SQL entities before migrating, and then
recreate them after the migrations are complete. This is helpful when the entities
depend on schema changes. To do this, register the built-in subscriber in a service provider:
```php