metal-orm 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -121
- package/dist/decorators/index.cjs +2564 -0
- package/dist/decorators/index.cjs.map +1 -0
- package/dist/decorators/index.d.cts +53 -0
- package/dist/decorators/index.d.ts +53 -0
- package/dist/decorators/index.js +2530 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/index.cjs +4227 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +701 -0
- package/dist/index.d.ts +701 -0
- package/dist/index.js +4131 -0
- package/dist/index.js.map +1 -0
- package/dist/select-654m4qy8.d.cts +1522 -0
- package/dist/select-654m4qy8.d.ts +1522 -0
- package/package.json +27 -20
- package/src/codegen/typescript.ts +405 -393
- package/src/core/ast/aggregate-functions.ts +30 -0
- package/src/core/ast/builders.ts +43 -0
- package/src/core/ast/expression-builders.ts +310 -0
- package/src/core/ast/expression-nodes.ts +211 -0
- package/src/core/ast/expression-visitor.ts +99 -0
- package/src/core/ast/expression.ts +5 -0
- package/src/{utils → core/ast}/join-node.ts +20 -20
- package/src/{ast → core/ast}/join.ts +18 -18
- package/src/{ast → core/ast}/query.ts +113 -113
- package/src/core/ast/window-functions.ts +140 -0
- package/src/{dialect → core/dialect}/abstract.ts +94 -94
- package/src/{dialect → core/dialect}/mssql/index.ts +31 -31
- package/src/{dialect → core/dialect}/mysql/index.ts +31 -31
- package/src/{dialect → core/dialect}/postgres/index.ts +45 -45
- package/src/{dialect → core/dialect}/sqlite/index.ts +45 -45
- package/src/{constants → core/sql}/sql-operator-config.ts +39 -39
- package/src/decorators/bootstrap.ts +126 -0
- package/src/decorators/column.ts +78 -0
- package/src/decorators/entity.ts +36 -0
- package/src/decorators/index.ts +4 -0
- package/src/decorators/relations.ts +107 -0
- package/src/global.d.ts +1 -0
- package/src/index.ts +22 -22
- package/src/orm/db-executor.ts +11 -0
- package/src/orm/domain-event-bus.ts +52 -0
- package/src/{runtime → orm}/entity-meta.ts +52 -52
- package/src/orm/entity-metadata.ts +140 -0
- package/src/{runtime → orm}/entity.ts +252 -252
- package/src/{runtime → orm}/execute.ts +36 -36
- package/src/{runtime → orm}/hydration.ts +103 -103
- package/src/orm/identity-map.ts +37 -0
- package/src/{runtime → orm}/lazy-batch.ts +205 -205
- package/src/orm/orm-context.ts +154 -0
- package/src/orm/relation-change-processor.ts +140 -0
- package/src/{runtime → orm}/relations/belongs-to.ts +92 -92
- package/src/{runtime → orm}/relations/has-many.ts +111 -111
- package/src/{runtime → orm}/relations/many-to-many.ts +149 -149
- package/src/orm/runtime-types.ts +39 -0
- package/src/orm/transaction-runner.ts +17 -0
- package/src/orm/unit-of-work.ts +232 -0
- package/src/{builder/operations → query-builder}/column-selector.ts +78 -78
- package/src/{builder → query-builder}/delete-query-state.ts +38 -42
- package/src/{builder → query-builder}/delete.ts +46 -57
- package/src/{builder → query-builder}/hydration-manager.ts +87 -87
- package/src/{builder → query-builder}/hydration-planner.ts +182 -182
- package/src/{builder → query-builder}/insert-query-state.ts +51 -62
- package/src/{builder → query-builder}/insert.ts +48 -59
- package/src/{builder → query-builder}/query-ast-service.ts +208 -226
- package/src/{utils → query-builder}/raw-column-parser.ts +32 -32
- package/src/{builder → query-builder}/relation-conditions.ts +112 -112
- package/src/{builder/operations → query-builder}/relation-manager.ts +82 -82
- package/src/{builder → query-builder}/relation-projection-helper.ts +101 -101
- package/src/{builder → query-builder}/relation-service.ts +284 -284
- package/src/{builder → query-builder}/relation-types.ts +21 -21
- package/src/{builder → query-builder}/relation-utils.ts +12 -12
- package/src/{builder → query-builder}/select-query-builder-deps.ts +112 -94
- package/src/{builder → query-builder}/select-query-state.ts +179 -179
- package/src/{builder → query-builder}/select.ts +78 -69
- package/src/{builder → query-builder}/update-query-state.ts +55 -59
- package/src/{builder → query-builder}/update.ts +50 -61
- package/src/schema/column.ts +25 -25
- package/src/schema/relation.ts +116 -116
- package/src/schema/table.ts +34 -34
- package/src/schema/types.ts +76 -76
- package/.github/workflows/publish-metal-orm.yml +0 -38
- package/ROADMAP.md +0 -125
- package/docs/CHANGES.md +0 -104
- package/docs/advanced-features.md +0 -176
- package/docs/api-reference.md +0 -31
- package/docs/dml-operations.md +0 -156
- package/docs/getting-started.md +0 -171
- package/docs/hydration.md +0 -115
- package/docs/index.md +0 -36
- package/docs/multi-dialect-support.md +0 -59
- package/docs/query-builder.md +0 -135
- package/docs/runtime.md +0 -105
- package/docs/schema-definition.md +0 -112
- package/metadata.json +0 -5
- package/playground/api/playground-api.ts +0 -94
- package/playground/index.html +0 -15
- package/playground/src/App.css +0 -1
- package/playground/src/App.tsx +0 -114
- package/playground/src/components/CodeDisplay.tsx +0 -43
- package/playground/src/components/QueryExecutor.tsx +0 -189
- package/playground/src/components/ResultsTable.tsx +0 -67
- package/playground/src/components/ResultsTabs.tsx +0 -105
- package/playground/src/components/ScenarioList.tsx +0 -56
- package/playground/src/components/logo.svg +0 -45
- package/playground/src/data/scenarios.ts +0 -2
- package/playground/src/main.tsx +0 -9
- package/playground/src/services/PlaygroundApiService.ts +0 -60
- package/postcss.config.cjs +0 -5
- package/sql_sql-ansi-cheatsheet-2025.md +0 -264
- package/src/ast/expression.ts +0 -658
- package/src/builder/operations/cte-manager.ts +0 -34
- package/src/builder/operations/filter-manager.ts +0 -68
- package/src/builder/operations/join-manager.ts +0 -36
- package/src/builder/operations/pagination-manager.ts +0 -36
- package/src/playground/features/playground/api/types.ts +0 -16
- package/src/playground/features/playground/clients/MockClient.ts +0 -17
- package/src/playground/features/playground/clients/SqliteClient.ts +0 -57
- package/src/playground/features/playground/common/IDatabaseClient.ts +0 -10
- package/src/playground/features/playground/data/scenarios/aggregation.ts +0 -36
- package/src/playground/features/playground/data/scenarios/basics.ts +0 -25
- package/src/playground/features/playground/data/scenarios/edge_cases.ts +0 -57
- package/src/playground/features/playground/data/scenarios/filtering.ts +0 -94
- package/src/playground/features/playground/data/scenarios/hydration.ts +0 -27
- package/src/playground/features/playground/data/scenarios/index.ts +0 -29
- package/src/playground/features/playground/data/scenarios/ordering.ts +0 -25
- package/src/playground/features/playground/data/scenarios/pagination.ts +0 -16
- package/src/playground/features/playground/data/scenarios/relationships.ts +0 -75
- package/src/playground/features/playground/data/scenarios/types.ts +0 -70
- package/src/playground/features/playground/data/schema.ts +0 -91
- package/src/playground/features/playground/data/seed.ts +0 -104
- package/src/playground/features/playground/services/QueryExecutionService.ts +0 -121
- package/src/runtime/orm-context.ts +0 -539
- package/tests/belongs-to-many.test.ts +0 -57
- package/tests/between.test.ts +0 -43
- package/tests/case-expression.test.ts +0 -58
- package/tests/complex-exists.test.ts +0 -230
- package/tests/cte.test.ts +0 -118
- package/tests/dml.test.ts +0 -206
- package/tests/exists.test.ts +0 -127
- package/tests/like.test.ts +0 -33
- package/tests/orm-runtime.test.ts +0 -254
- package/tests/postgres.test.ts +0 -30
- package/tests/right-join.test.ts +0 -89
- package/tests/subquery-having.test.ts +0 -193
- package/tests/window-function.test.ts +0 -151
- package/tsconfig.json +0 -30
- package/tsup.config.ts +0 -10
- package/vite.config.ts +0 -22
- package/vitest.config.ts +0 -14
- /package/src/{constants → core/sql}/sql.ts +0 -0
- /package/src/{runtime → orm}/als.ts +0 -0
- /package/src/{utils → query-builder}/relation-alias.ts +0 -0
package/README.md
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
MetalORM is a TypeScript-first, AST-driven SQL toolkit:
|
|
10
10
|
|
|
11
|
-
- At the **base level**, it's a clear, deterministic query builder with schema definitions and relation-aware hydration
|
|
12
|
-
- At the **next level**, it becomes an **ORM runtime** with entities, lazy/batched relations, and a Unit of Work (`OrmContext`) that flushes graph changes in one `saveChanges()`.
|
|
11
|
+
- At the **base level**, it's a clear, deterministic query builder with schema definitions and relation-aware hydration.
|
|
12
|
+
- At the **next level**, it becomes an **ORM runtime** with entities, lazy/batched relations, and a Unit of Work (`OrmContext`) that flushes graph changes in one `saveChanges()`.
|
|
13
13
|
|
|
14
14
|
Use only the parts you need: query builder + hydration for read-heavy/reporting code, or the full ORM runtime for application/business logic.
|
|
15
15
|
|
|
@@ -17,18 +17,18 @@ Use only the parts you need: query builder + hydration for read-heavy/reporting
|
|
|
17
17
|
|
|
18
18
|
## Documentation
|
|
19
19
|
|
|
20
|
-
Full docs live in the `docs/` folder:
|
|
21
|
-
|
|
22
|
-
- [Introduction](docs/index.md)
|
|
23
|
-
- [Getting Started](docs/getting-started.md)
|
|
24
|
-
- [Schema Definition](docs/schema-definition.md)
|
|
25
|
-
- [Query Builder](docs/query-builder.md)
|
|
26
|
-
- [DML Operations](docs/dml-operations.md)
|
|
27
|
-
- [Hydration & Entities](docs/hydration.md)
|
|
28
|
-
- [Runtime & Unit of Work](docs/runtime.md)
|
|
29
|
-
- [Advanced Features](docs/advanced-features.md)
|
|
30
|
-
- [Multi-Dialect Support](docs/multi-dialect-support.md)
|
|
31
|
-
- [API Reference](docs/api-reference.md)
|
|
20
|
+
Full docs live in the `docs/` folder:
|
|
21
|
+
|
|
22
|
+
- [Introduction](https://github.com/celsowm/metal-orm/blob/main/docs/index.md)
|
|
23
|
+
- [Getting Started](https://github.com/celsowm/metal-orm/blob/main/docs/getting-started.md)
|
|
24
|
+
- [Schema Definition](https://github.com/celsowm/metal-orm/blob/main/docs/schema-definition.md)
|
|
25
|
+
- [Query Builder](https://github.com/celsowm/metal-orm/blob/main/docs/query-builder.md)
|
|
26
|
+
- [DML Operations](https://github.com/celsowm/metal-orm/blob/main/docs/dml-operations.md)
|
|
27
|
+
- [Hydration & Entities](https://github.com/celsowm/metal-orm/blob/main/docs/hydration.md)
|
|
28
|
+
- [Runtime & Unit of Work](https://github.com/celsowm/metal-orm/blob/main/docs/runtime.md)
|
|
29
|
+
- [Advanced Features](https://github.com/celsowm/metal-orm/blob/main/docs/advanced-features.md)
|
|
30
|
+
- [Multi-Dialect Support](https://github.com/celsowm/metal-orm/blob/main/docs/multi-dialect-support.md)
|
|
31
|
+
- [API Reference](https://github.com/celsowm/metal-orm/blob/main/docs/api-reference.md)
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -36,12 +36,12 @@ Full docs live in the `docs/` folder:
|
|
|
36
36
|
|
|
37
37
|
**As a query builder:**
|
|
38
38
|
|
|
39
|
-
- **Declarative schema definition** with `defineTable`, `col.*`, and typed relations
|
|
40
|
-
- **Fluent query builder** over a real SQL AST (`SelectQueryBuilder`, `InsertQueryBuilder`, `UpdateQueryBuilder`, `DeleteQueryBuilder`).
|
|
41
|
-
- **Advanced SQL**: CTEs, aggregates, window functions, subqueries, JSON, CASE, EXISTS.
|
|
42
|
-
- **Relation hydration**: turn flat rows into nested objects (`user.posts`, `user.roles`, etc.)
|
|
43
|
-
- **Multi-dialect**: compile once, run on MySQL, PostgreSQL, SQLite, or SQL Server
|
|
44
|
-
- **DML**: type-safe INSERT / UPDATE / DELETE with `RETURNING` where supported
|
|
39
|
+
- **Declarative schema definition** with `defineTable`, `col.*`, and typed relations.
|
|
40
|
+
- **Fluent query builder** over a real SQL AST (`SelectQueryBuilder`, `InsertQueryBuilder`, `UpdateQueryBuilder`, `DeleteQueryBuilder`).
|
|
41
|
+
- **Advanced SQL**: CTEs, aggregates, window functions, subqueries, JSON, CASE, EXISTS.
|
|
42
|
+
- **Relation hydration**: turn flat rows into nested objects (`user.posts`, `user.roles`, etc.).
|
|
43
|
+
- **Multi-dialect**: compile once, run on MySQL, PostgreSQL, SQLite, or SQL Server.
|
|
44
|
+
- **DML**: type-safe INSERT / UPDATE / DELETE with `RETURNING` where supported.
|
|
45
45
|
|
|
46
46
|
**As an ORM runtime (optional):**
|
|
47
47
|
|
|
@@ -62,27 +62,40 @@ npm install metal-orm
|
|
|
62
62
|
# yarn
|
|
63
63
|
yarn add metal-orm
|
|
64
64
|
|
|
65
|
-
# pnpm
|
|
66
|
-
pnpm add metal-orm
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
MetalORM compiles SQL; you bring your own driver:
|
|
70
|
-
|
|
71
|
-
Dialect
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
65
|
+
# pnpm
|
|
66
|
+
pnpm add metal-orm
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
MetalORM compiles SQL; you bring your own driver:
|
|
70
|
+
|
|
71
|
+
| Dialect | Driver | Install |
|
|
72
|
+
| --- | --- | --- |
|
|
73
|
+
| MySQL / MariaDB | `mysql2` | `npm install mysql2` |
|
|
74
|
+
| SQLite | `sqlite3` | `npm install sqlite3` |
|
|
75
|
+
| PostgreSQL | `pg` | `npm install pg` |
|
|
76
|
+
| SQL Server | `tedious` | `npm install tedious` |
|
|
77
|
+
|
|
78
|
+
Pick the matching dialect (MySqlDialect, SQLiteDialect, PostgresDialect, MSSQLDialect) when compiling queries.
|
|
79
|
+
|
|
80
|
+
> Drivers are declared as optional peer dependencies. Install only the ones you actually use in your project.
|
|
81
|
+
|
|
82
|
+
### Playground (optional)
|
|
83
|
+
|
|
84
|
+
The React playground lives in `playground/` and is no longer part of the published package or its dependency tree. To run it locally:
|
|
85
|
+
|
|
86
|
+
1. `cd playground && npm install`
|
|
87
|
+
2. `npm run dev` (uses the root `vite.config.ts`)
|
|
88
|
+
|
|
89
|
+
It boots against an in-memory SQLite database seeded from the fixtures under `playground/shared/`.
|
|
90
|
+
|
|
91
|
+
## Quick start
|
|
92
|
+
|
|
93
|
+
1. Start simple: tiny table, tiny query
|
|
94
|
+
|
|
95
|
+
MetalORM can be just a straightforward query builder.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import mysql from 'mysql2/promise';
|
|
86
99
|
import {
|
|
87
100
|
defineTable,
|
|
88
101
|
col,
|
|
@@ -114,22 +127,24 @@ const { sql, params } = listOpenTodos.compile(dialect);
|
|
|
114
127
|
|
|
115
128
|
// 4) Run with your favorite driver
|
|
116
129
|
const connection = await mysql.createConnection({ /* ... */ });
|
|
117
|
-
const [rows] = await connection.execute(sql, params);
|
|
118
|
-
|
|
119
|
-
console.log(rows);
|
|
120
|
-
// [
|
|
121
|
-
// { id: 1, title: 'Write docs', done: 0 },
|
|
122
|
-
// { id: 2, title: 'Ship feature', done: 0 },
|
|
123
|
-
// ]
|
|
130
|
+
const [rows] = await connection.execute(sql, params);
|
|
131
|
+
|
|
132
|
+
console.log(rows);
|
|
133
|
+
// [
|
|
134
|
+
// { id: 1, title: 'Write docs', done: 0 },
|
|
135
|
+
// { id: 2, title: 'Ship feature', done: 0 },
|
|
136
|
+
// ]
|
|
137
|
+
```
|
|
124
138
|
|
|
125
139
|
|
|
126
140
|
That’s it: schema, query, SQL, done.
|
|
127
141
|
|
|
128
142
|
2. Relations & hydration: nested results without an ORM
|
|
129
143
|
|
|
130
|
-
Now let
|
|
131
|
-
|
|
132
|
-
|
|
144
|
+
Now let's add relations and get nested objects, still without committing to a full ORM.
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import {
|
|
133
148
|
defineTable,
|
|
134
149
|
col,
|
|
135
150
|
hasMany,
|
|
@@ -172,41 +187,43 @@ const builder = new SelectQueryBuilder(users)
|
|
|
172
187
|
columns: [posts.columns.id, posts.columns.title, posts.columns.createdAt],
|
|
173
188
|
}); // eager relation for hydration
|
|
174
189
|
|
|
175
|
-
const { sql, params } = builder.compile(dialect);
|
|
176
|
-
const [rows] = await connection.execute(sql, params);
|
|
177
|
-
|
|
178
|
-
// Turn flat rows into nested objects
|
|
179
|
-
const hydrated = hydrateRows(
|
|
180
|
-
rows as Record<string, unknown>[],
|
|
181
|
-
builder.getHydrationPlan(),
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
console.log(hydrated);
|
|
185
|
-
// [
|
|
186
|
-
// {
|
|
187
|
-
// id: 1,
|
|
188
|
-
// name: 'John Doe',
|
|
189
|
-
// email: 'john@example.com',
|
|
190
|
-
// postCount: 15,
|
|
191
|
-
// rank: 1,
|
|
192
|
-
// posts: [
|
|
193
|
-
// { id: 101, title: 'Latest Post', createdAt: '2023-05-15T10:00:00Z' },
|
|
194
|
-
// // ...
|
|
195
|
-
// ],
|
|
196
|
-
// },
|
|
197
|
-
// // ...
|
|
198
|
-
// ]
|
|
190
|
+
const { sql, params } = builder.compile(dialect);
|
|
191
|
+
const [rows] = await connection.execute(sql, params);
|
|
192
|
+
|
|
193
|
+
// Turn flat rows into nested objects
|
|
194
|
+
const hydrated = hydrateRows(
|
|
195
|
+
rows as Record<string, unknown>[],
|
|
196
|
+
builder.getHydrationPlan(),
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
console.log(hydrated);
|
|
200
|
+
// [
|
|
201
|
+
// {
|
|
202
|
+
// id: 1,
|
|
203
|
+
// name: 'John Doe',
|
|
204
|
+
// email: 'john@example.com',
|
|
205
|
+
// postCount: 15,
|
|
206
|
+
// rank: 1,
|
|
207
|
+
// posts: [
|
|
208
|
+
// { id: 101, title: 'Latest Post', createdAt: '2023-05-15T10:00:00Z' },
|
|
209
|
+
// // ...
|
|
210
|
+
// ],
|
|
211
|
+
// },
|
|
212
|
+
// // ...
|
|
213
|
+
// ]
|
|
214
|
+
```
|
|
199
215
|
|
|
200
216
|
|
|
201
217
|
Use this mode anywhere you want powerful SQL + nice nested results, without changing how you manage your models.
|
|
202
218
|
|
|
203
219
|
3. Turn it up: entities + Unit of Work (ORM mode)
|
|
204
220
|
|
|
205
|
-
When you
|
|
206
|
-
|
|
207
|
-
Instead of
|
|
208
|
-
|
|
209
|
-
|
|
221
|
+
When you're ready, you can let MetalORM manage entities and relations for you.
|
|
222
|
+
|
|
223
|
+
Instead of "naked objects", your queries can return entities attached to an OrmContext:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
import {
|
|
210
227
|
OrmContext,
|
|
211
228
|
MySqlDialect,
|
|
212
229
|
SelectQueryBuilder,
|
|
@@ -251,49 +268,44 @@ const newPost = user.posts.add({ title: 'Hello from ORM mode' });
|
|
|
251
268
|
// Many-to-many via pivot:
|
|
252
269
|
await user.roles.syncByIds([1, 2, 3]);
|
|
253
270
|
|
|
254
|
-
// 3) Persist the entire graph
|
|
255
|
-
await ctx.saveChanges();
|
|
256
|
-
// INSERT/UPDATE/DELETE + pivot updates happen in a single Unit of Work.
|
|
257
|
-
|
|
271
|
+
// 3) Persist the entire graph
|
|
272
|
+
await ctx.saveChanges();
|
|
273
|
+
// INSERT/UPDATE/DELETE + pivot updates happen in a single Unit of Work.
|
|
274
|
+
```
|
|
258
275
|
|
|
259
|
-
Here’s what the runtime gives you:
|
|
260
276
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
Relation tracking: add/remove/sync on relation collections emits relation changes.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
Single flush: ctx.saveChanges() figures out inserts, updates, deletes, and pivot changes.
|
|
277
|
+
Here's what the runtime gives you:
|
|
278
|
+
|
|
279
|
+
- Identity map: the same row becomes the same entity instance within a context.
|
|
280
|
+
- Change tracking: field writes mark entities as dirty.
|
|
281
|
+
- Relation tracking: add/remove/sync on relation collections emits relation changes.
|
|
282
|
+
- Cascades: relation definitions can opt into cascade: 'all' | 'persist' | 'remove' | 'link'.
|
|
283
|
+
- Single flush: `ctx.saveChanges()` figures out inserts, updates, deletes, and pivot changes.
|
|
270
284
|
|
|
271
285
|
You can start your project using only the query builder + hydration and gradually migrate hot paths to entities as you implement the runtime primitives.
|
|
272
286
|
|
|
273
|
-
When to use which mode?
|
|
274
|
-
|
|
275
|
-
Query builder + hydration only
|
|
276
|
-
|
|
277
|
-
Great for reporting, analytics, and places where you already have a model layer.
|
|
278
|
-
|
|
279
|
-
You keep full control over how objects map to rows.
|
|
280
|
-
|
|
281
|
-
Entity + Unit of Work runtime
|
|
282
|
-
|
|
283
|
-
Great for request-scoped application logic and domain modeling.
|
|
284
|
-
|
|
285
|
-
You want lazy relations, cascades, and less boilerplate around update/delete logic.
|
|
286
|
-
|
|
287
|
-
Both modes share the same schema, AST, and dialects, so you don't have to pick one forever.
|
|
288
|
-
|
|
289
|
-
Contributing
|
|
290
|
-
|
|
291
|
-
Issues and PRs are welcome! If you're interested in pushing the runtime/ORM side further (soft deletes, multi-tenant filters, outbox patterns, etc.), contributions are especially appreciated.
|
|
292
|
-
|
|
293
|
-
See the
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
MetalORM is MIT licensed
|
|
299
|
-
.
|
|
287
|
+
## When to use which mode?
|
|
288
|
+
|
|
289
|
+
### Query builder + hydration only
|
|
290
|
+
|
|
291
|
+
Great for reporting, analytics, and places where you already have a model layer.
|
|
292
|
+
|
|
293
|
+
You keep full control over how objects map to rows.
|
|
294
|
+
|
|
295
|
+
### Entity + Unit of Work runtime
|
|
296
|
+
|
|
297
|
+
Great for request-scoped application logic and domain modeling.
|
|
298
|
+
|
|
299
|
+
You want lazy relations, cascades, and less boilerplate around update/delete logic.
|
|
300
|
+
|
|
301
|
+
Both modes share the same schema, AST, and dialects, so you don't have to pick one forever.
|
|
302
|
+
|
|
303
|
+
## Contributing
|
|
304
|
+
|
|
305
|
+
Issues and PRs are welcome! If you're interested in pushing the runtime/ORM side further (soft deletes, multi-tenant filters, outbox patterns, etc.), contributions are especially appreciated.
|
|
306
|
+
|
|
307
|
+
See the contributing guide for details.
|
|
308
|
+
|
|
309
|
+
## License
|
|
310
|
+
|
|
311
|
+
MetalORM is MIT licensed.
|