164 lines
4.2 KiB
Markdown
164 lines
4.2 KiB
Markdown
Here is a fully rewritten version of the entire **Tables + Columns + Floating Mapping** section — accurate, simplified, and without over-emphasizing the “floating” term, while still explaining why it matters.
|
||
|
||
---
|
||
|
||
## Tables & Columns
|
||
|
||
### Automatic SQL Mapping from UI Components
|
||
|
||
In Unify, **your UI defines your data model**.
|
||
|
||
Every data entity in an application is a **table object**:
|
||
|
||
```js
|
||
import table from '/unify/table.js';
|
||
|
||
export default class user extends table {
|
||
|
||
username = new username(); // column
|
||
email = new email(); // column
|
||
groups = new groups(); // relation
|
||
}
|
||
```
|
||
|
||
Any child object that extends `column` is automatically treated as a **database column** belonging to its nearest table ancestor.
|
||
|
||
There is no need to write schemas, migrations, or model config files.
|
||
Unify inspects the structure at runtime and understands:
|
||
|
||
* Table name → class name (`user`)
|
||
* Column names → field names (`username`, `email`, …)
|
||
* Relationships → nested collections
|
||
* Permissions → defined on the table
|
||
|
||
No duplication. No ORM setup.
|
||
Your UI code **is** your data model.
|
||
|
||
---
|
||
|
||
### Columns Can Live Anywhere in the UI Tree
|
||
|
||
Columns do not need to be direct children of the table.
|
||
|
||
You can design your UI freely:
|
||
|
||
```js
|
||
export default class userEditPanel extends panel {
|
||
accountPanel = new accountPanel();
|
||
contactPanel = new contactPanel();
|
||
}
|
||
|
||
class accountPanel extends panel {
|
||
username = new username(); // column
|
||
}
|
||
|
||
class contactPanel extends panel {
|
||
email = new email(); // column
|
||
}
|
||
```
|
||
|
||
Unify automatically discovers these fields because they appear **under a table instance** in the object tree.
|
||
|
||
So you are free to:
|
||
|
||
* Split a screen into panels
|
||
* Reuse complex component hierarchies
|
||
* Move UI structure without refactoring SQL code
|
||
|
||
This enables **UI-first design** without breaking the data layer.
|
||
|
||
---
|
||
|
||
### CRUD Without CRUD Code
|
||
|
||
Unify provides two primary data operations:
|
||
|
||
| Action | Developer code | Result |
|
||
| ------ | ------------------- | ----------------------------------- |
|
||
| Save | `await user.save()` | INSERT or UPDATE depending on `id` |
|
||
| Load | `await user.sync()` | SELECT + populate all child columns |
|
||
|
||
Example: Editing a profile
|
||
|
||
```js
|
||
async click() {
|
||
const form = this.parents('userEdit');
|
||
await form.save(); // automatically writes username & email
|
||
form.hide();
|
||
}
|
||
```
|
||
|
||
And for loading:
|
||
|
||
```js
|
||
user.id = 42;
|
||
await user.sync(); // loads username/email into the UI automatically
|
||
```
|
||
|
||
No setters.
|
||
No binding boilerplate.
|
||
No DTOs.
|
||
No form libraries.
|
||
|
||
The table object is both:
|
||
|
||
* Data source
|
||
* UI container
|
||
* Binding layer
|
||
|
||
---
|
||
|
||
### Why This Matters
|
||
|
||
| Traditional Full-Stack | With Unify |
|
||
| --------------------------- | -------------------------- |
|
||
| Write database schema | Skip — inferred |
|
||
| Write backend model | Skip — inferred |
|
||
| Write API controllers | Skip — RPC auto-generation |
|
||
| Write validation logic | Built into column objects |
|
||
| Build UI → manually connect | UI *is* the data model |
|
||
| Keep everything in sync | `.sync()` + `.save()` |
|
||
|
||
This eliminates the friction between backend + frontend and replaces it with one unified codebase.
|
||
|
||
---
|
||
|
||
### Minimal Mental Model
|
||
|
||
> A **table** object represents a database row.
|
||
> Any **column** object inside that table’s UI subtree automatically becomes a database column.
|
||
> `sync()` loads data into the UI.
|
||
> `save()` writes UI data back to SQL.
|
||
|
||
Nothing more is needed to build and ship real applications.
|
||
|
||
---
|
||
|
||
### Example Recap
|
||
|
||
```js
|
||
user.id = 7;
|
||
await user.sync(); // load existing row → UI updates
|
||
|
||
user.username.value = "kaj";
|
||
await user.save(); // update DB row with new values
|
||
```
|
||
|
||
One line to fetch, one line to commit.
|
||
|
||
---
|
||
|
||
If you'd like, the next chapter can flow directly into **Render Collections & Lists**, since they demonstrate the same philosophy at scale:
|
||
|
||
* UI defines queries (pagination, filtering)
|
||
* Changes propagate automatically across the app
|
||
|
||
Should I continue with:
|
||
|
||
A) Render Collections + Filtering/Searching
|
||
B) Permissions (groups, scopes, READ/WRITE/DELETE)
|
||
C) Routing + Animated Page State
|
||
D) Server RPC Communication Model (socket commands)
|
||
|
||
Just tell me which one comes next.
|