Skip to content

Commit 66d8f86

Browse files
committed
docs: add usage docs
1 parent 096a0a9 commit 66d8f86

File tree

1 file changed

+167
-12
lines changed

1 file changed

+167
-12
lines changed

README.md

Lines changed: 167 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ prone to unknown conflicts, and difficult to track over time.
2020

2121
`laravel-sql-entities` solves this by offering:
2222

23-
- 📦 Class-based definitions for SQL entities: bringing views, functions, triggers, and more into your application code.
24-
- 🧠 First-class source control: definitions live in PHP files, so you can track changes, review diffs in PRs, and resolve conflicts easily.
25-
- 🧱 Decoupled grammars per database: letting you support multiple drivers (e.g., PostgreSQL) without cluttering your logic with dialect-specific SQL.
26-
- 🔁 Lifecycle hooks: run logic before/after an entity is created or dropped, enabling logging, auditing, or cleanup.
23+
- 📦 Class-based definitions: bringing views, functions, triggers, and more into your application code.
24+
- 🧠 First-class source control: you can easily track changes, review diffs, and resolve conflicts.
25+
- 🧱 Decoupled grammars: letting you support multiple drivers without needing dialect-specific SQL.
26+
- 🔁 Lifecycle hooks: run logic at various points, enabling logging, auditing, and more.
2727
- 🚀 Batch operations: easily create or drop all entities in a single command or lifecycle event.
28-
- 🧪 Testability: because definitions are just code, they’re easy to test, validate, and keep consistent with your schema.
28+
- 🧪 Testability: definitions are just code so they’re easy to test, validate, and keep consistent.
2929

3030
Whether you're managing reporting views, business logic functions, or automation
3131
triggers, this package helps you treat SQL entities like real, versioned parts
@@ -36,7 +36,7 @@ of your codebase---no more scattered SQL in migrations!
3636
>
3737
> ["We're never going backwards. You only go forward." -Taylor Otwell](https://www.twitch.tv/theprimeagen/clip/DrabAltruisticEggnogVoHiYo-f6CVkrqraPsWrEht)
3838
39-
## Installation
39+
## 📦 Installation
4040

4141
First pull in the package using Composer:
4242

@@ -50,7 +50,7 @@ composer require calebdw/laravel-sql-entities
5050
<!-- php artisan vendor:publish --provider="CalebDW\SqlEntities\ServiceProvider" -->
5151
<!-- ``` -->
5252

53-
The package looks for Entities under `database/entities/` so you will need to add
53+
The package looks for SQL entities under `database/entities/` so you might need to add
5454
a namespace to your `composer.json` file, for example:
5555

5656
```diff
@@ -68,21 +68,176 @@ a namespace to your `composer.json` file, for example:
6868

6969
> [!TIP]
7070
> This package looks for any files matching `database/entities` in the application's
71-
> base path. This means it should automatically work for a modular setup.
71+
> base path. This means it should automatically work for a modular setup where
72+
> the entities might be spread across multiple directories.
7273
7374
<!-- ## Configuration -->
7475

75-
## Usage
76+
## 🛠️ Usage
7677

77-
## Contributing
78+
### 🧱 SQL Entities
79+
80+
To get started, create a new class in a `database/entities/` directory
81+
(structure is up to you) and extend the appropriate entity class (e.g. `View`, etc.).
82+
83+
For example, to create a view for recent orders, you might create the following class:
84+
85+
```php
86+
<?php
87+
88+
namespace Database\Entities\Views;
89+
90+
use App\Models\Order;
91+
use CalebDW\SqlEntities\View;
92+
use Illuminate\Database\Query\Builder;
93+
use Override;
94+
95+
// will create a view named `recent_orders_view`
96+
class RecentOrdersView extends View
97+
{
98+
#[Override]
99+
public function definition(): Builder|string
100+
{
101+
return Order::query()
102+
->select(['id', 'customer_id', 'status', 'created_at'])
103+
->where('created_at', '>=', now()->subDays(30))
104+
->toBase();
105+
106+
// could also use raw SQL
107+
return <<<'SQL'
108+
SELECT id, customer_id, status, created_at
109+
FROM orders
110+
WHERE created_at >= NOW() - INTERVAL '30 days'
111+
SQL;
112+
}
113+
}
114+
```
115+
116+
You can also override the name and connection:
117+
118+
```php
119+
<?php
120+
class RecentOrdersView extends View
121+
{
122+
protected ?string $name = 'other_name';
123+
// also supports schema
124+
protected ?string $name = 'other_schema.other_name';
125+
126+
protected ?string $connection = 'other_connection';
127+
}
128+
```
129+
130+
#### 🔁 Lifecycle Hooks
131+
132+
You can also use the provided lifecycle hooks to run logic before or after an entity is created or dropped.
133+
Returning `false` from the `creating` or `dropping` methods will prevent the entity from being created or dropped, respectively.
134+
135+
```php
136+
<?php
137+
use Illuminate\Database\Connection;
138+
139+
class RecentOrdersView extends View
140+
{
141+
// ...
142+
143+
#[Override]
144+
public function creating(Connection $connection): bool
145+
{
146+
if (/** should not create */) {
147+
return false;
148+
}
149+
150+
/** other logic */
151+
152+
return true;
153+
}
154+
155+
#[Override]
156+
public function created(Connection $connection): void
157+
{
158+
$this->connection->statement(<<<SQL
159+
GRANT SELECT ON TABLE {$this->name()} TO other_user;
160+
SQL);
161+
}
162+
163+
#[Override]
164+
public function dropping(Connection $connection): bool
165+
{
166+
if (/** should not drop */) {
167+
return false;
168+
}
169+
170+
/** other logic */
171+
172+
return true;
173+
}
174+
175+
#[Override]
176+
public function dropped(Connection $connection): void
177+
{
178+
/** logic */
179+
}
180+
}
181+
```
182+
183+
### 🧠 Manager
184+
185+
The `SqlEntityManager` singleton is responsible for creating and dropping SQL entities at runtime.
186+
You can interact with it directly, or use the `SqlEntity` facade for convenience.
187+
188+
```php
189+
<?php
190+
use CalebDW\SqlEntities\Facades\SqlEntity;
191+
use CalebDW\SqlEntities\SqlEntityManager;
192+
use CalebDW\SqlEntities\View;
193+
194+
// Create a single entity by name, class, or instance
195+
SqlEntity::create('recent_orders_view');
196+
resolve(SqlEntityManager::class)->create(RecentOrdersView::class);
197+
resolve('sql-entities')->create(new RecentOrdersView());
198+
199+
// Similarly, you can drop a single entity using the name, class, or instance
200+
SqlEntity::drop(RecentOrdersView::class);
201+
202+
// Create or drop all entities
203+
SqlEntity::createAll();
204+
SqlEntity::dropAll();
205+
206+
// You can also filter by type or connection
207+
SqlEntity::createAll(type: View::class, connection: 'reporting');
208+
SqlEntity::dropAll(type: View::class, connection: 'reporting');
209+
```
210+
211+
### 🚀 Automatic syncing when migrating (Optional)
212+
213+
You may want to automatically drop all SQL entities before migrating, and then
214+
recreate them after the migrations are complete. This is helpful when the entities
215+
depend on schema changes. To do this, register the built-in subscriber in a service provider:
216+
217+
```php
218+
<?php
219+
use CalebDW\SqlEntities\Listeners\SyncSqlEntities;
220+
use Illuminate\Support\Facades\Event;
221+
use Illuminate\Support\ServiceProvider;
222+
223+
class AppServiceProvider extends ServiceProvider
224+
{
225+
public function boot(): void
226+
{
227+
Event::subscribe(SyncSqlEntities::class);
228+
}
229+
}
230+
```
231+
232+
## 🤝 Contributing
78233

79234
Thank you for considering contributing! You can read the contribution guide [here](CONTRIBUTING.md).
80235

81-
## License
236+
## ⚖️ License
82237

83238
This is open-sourced software licensed under the [MIT license](LICENSE).
84239

85-
## Alternatives
240+
## 🔀 Alternatives
86241

87242
- [laravel-sql-views](https://github.com/stats4sd/laravel-sql-views)
88243
- [laravel-migration-views](https://github.com/staudenmeir/laravel-migration-views)

0 commit comments

Comments
 (0)