Split out of #235. The shipped `Kern\View` takes its body as a trusted raw SELECT string (`$definition`). This tracks replacing that with a declarative arrays-to-SELECT builder, so a view is defined the BerlinDB way (simple arrays -> SQL), like a Query's query vars:
```php
protected $definition = array(
'select' => array( 'id', 'name' ),
'from' => 'orders',
'where' => array( 'status' => 'complete' ),
);
```
Why
Constraint (the trap)
A view body is a stable, unpaginated, stored SELECT. It must NOT reuse Query's ephemeral request string (`Traits\Query\Execution::set_request()`), which bakes in `LIMIT`/`OFFSET`/order/cache-key per fetch.
Reuse
- `Clauses\Builder` is the inert "fragments -> { join, where }" engine, built so "SELECT is just the first consumer" — reuse it for JOIN/WHERE.
- The parser path (array -> fragments) needs the schema + parser registry (Query's domain), so wiring it to emit a stable SELECT is the design work, plus new `select`-columns / `from` / `group by` rendering that `Builder` does not cover.
Scope note
No clean "minimal" version: a builder without WHERE/JOIN is not useful for real views, and WHERE/JOIN is exactly the part that pulls in Query's machinery. Recommend a design spec (array shape + what v1 supports + how it reuses `Clauses\Builder` without the ephemeral request) before implementation. Deferred until a concrete driver (e.g. the SQLite/Playground portability push) makes dialect-rendering pay off.
Related: #235 (View, shipped), #232 (Platform/portability), #214/#211 (Clauses\Builder / criteria subsystem).
Split out of #235. The shipped `Kern\View` takes its body as a trusted raw SELECT string (`$definition`). This tracks replacing that with a declarative arrays-to-SELECT builder, so a view is defined the BerlinDB way (simple arrays -> SQL), like a Query's query vars:
```php
protected $definition = array(
'select' => array( 'id', 'name' ),
'from' => 'orders',
'where' => array( 'status' => 'complete' ),
);
```
Why
Constraint (the trap)
A view body is a stable, unpaginated, stored SELECT. It must NOT reuse Query's ephemeral request string (`Traits\Query\Execution::set_request()`), which bakes in `LIMIT`/`OFFSET`/order/cache-key per fetch.
Reuse
Scope note
No clean "minimal" version: a builder without WHERE/JOIN is not useful for real views, and WHERE/JOIN is exactly the part that pulls in Query's machinery. Recommend a design spec (array shape + what v1 supports + how it reuses `Clauses\Builder` without the ephemeral request) before implementation. Deferred until a concrete driver (e.g. the SQLite/Playground portability push) makes dialect-rendering pay off.
Related: #235 (View, shipped), #232 (Platform/portability), #214/#211 (Clauses\Builder / criteria subsystem).