metal-orm 1.0.40 → 1.0.42
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 +53 -14
- package/dist/index.cjs +1298 -126
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +676 -30
- package/dist/index.d.ts +676 -30
- package/dist/index.js +1293 -126
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/codegen/typescript.ts +6 -2
- package/src/core/ast/expression-builders.ts +25 -4
- package/src/core/ast/expression-nodes.ts +3 -1
- package/src/core/ast/expression.ts +2 -2
- package/src/core/ast/query.ts +24 -2
- package/src/core/dialect/abstract.ts +6 -2
- package/src/core/dialect/base/join-compiler.ts +9 -12
- package/src/core/dialect/base/sql-dialect.ts +98 -17
- package/src/core/dialect/mssql/index.ts +30 -62
- package/src/core/dialect/sqlite/index.ts +39 -34
- package/src/core/execution/db-executor.ts +46 -6
- package/src/core/execution/executors/mssql-executor.ts +39 -22
- package/src/core/execution/executors/mysql-executor.ts +23 -6
- package/src/core/execution/executors/sqlite-executor.ts +29 -3
- package/src/core/execution/pooling/pool-types.ts +30 -0
- package/src/core/execution/pooling/pool.ts +268 -0
- package/src/decorators/bootstrap.ts +7 -7
- package/src/index.ts +6 -0
- package/src/orm/domain-event-bus.ts +49 -0
- package/src/orm/entity-metadata.ts +9 -9
- package/src/orm/entity.ts +58 -0
- package/src/orm/orm-session.ts +465 -270
- package/src/orm/orm.ts +61 -11
- package/src/orm/pooled-executor-factory.ts +131 -0
- package/src/orm/query-logger.ts +6 -12
- package/src/orm/relation-change-processor.ts +75 -0
- package/src/orm/relations/many-to-many.ts +4 -2
- package/src/orm/save-graph.ts +303 -0
- package/src/orm/transaction-runner.ts +3 -3
- package/src/orm/unit-of-work.ts +128 -0
- package/src/query-builder/delete-query-state.ts +67 -38
- package/src/query-builder/delete.ts +37 -1
- package/src/query-builder/insert-query-state.ts +131 -61
- package/src/query-builder/insert.ts +27 -1
- package/src/query-builder/update-query-state.ts +114 -77
- package/src/query-builder/update.ts +38 -1
- package/src/schema/table.ts +210 -115
package/README.md
CHANGED
|
@@ -171,6 +171,7 @@ MetalORM can be just a straightforward query builder.
|
|
|
171
171
|
import mysql from 'mysql2/promise';
|
|
172
172
|
import {
|
|
173
173
|
defineTable,
|
|
174
|
+
tableRef,
|
|
174
175
|
col,
|
|
175
176
|
SelectQueryBuilder,
|
|
176
177
|
eq,
|
|
@@ -187,15 +188,14 @@ const todos = defineTable('todos', {
|
|
|
187
188
|
todos.columns.title.notNull = true;
|
|
188
189
|
todos.columns.done.default = false;
|
|
189
190
|
|
|
191
|
+
// Optional: opt-in ergonomic column access
|
|
192
|
+
const t = tableRef(todos);
|
|
193
|
+
|
|
190
194
|
// 2) Build a simple query
|
|
191
195
|
const listOpenTodos = new SelectQueryBuilder(todos)
|
|
192
|
-
.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
done: todos.columns.done,
|
|
196
|
-
})
|
|
197
|
-
.where(eq(todos.columns.done, false))
|
|
198
|
-
.orderBy(todos.columns.id, 'ASC');
|
|
196
|
+
.selectColumns('id', 'title', 'done')
|
|
197
|
+
.where(eq(t.done, false))
|
|
198
|
+
.orderBy(t.id, 'ASC');
|
|
199
199
|
|
|
200
200
|
// 3) Compile to SQL + params
|
|
201
201
|
const dialect = new MySqlDialect();
|
|
@@ -214,6 +214,48 @@ console.log(rows);
|
|
|
214
214
|
|
|
215
215
|
That’s it: schema, query, SQL, done.
|
|
216
216
|
|
|
217
|
+
#### Column pickers (preferred selection helpers)
|
|
218
|
+
|
|
219
|
+
`defineTable` still exposes the full `table.columns` map for schema metadata and constraint tweaks, but modern queries usually benefit from higher-level helpers instead of spelling `todo.columns.*` everywhere.
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
const t = tableRef(todos);
|
|
223
|
+
|
|
224
|
+
const listOpenTodos = new SelectQueryBuilder(todos)
|
|
225
|
+
.selectColumns('id', 'title', 'done') // typed shorthand for the same fields
|
|
226
|
+
.where(eq(t.done, false))
|
|
227
|
+
.orderBy(t.id, 'ASC');
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`selectColumns`, `selectRelationColumns`, `includePick`, `selectColumnsDeep`, the `sel()` helpers for tables, and `esel()` for entities all build typed selection maps without repeating `table.columns.*`. Use those helpers when building query selections and reserve `table.columns.*` for schema definition, relations, or rare cases where you need a column reference outside of a picker. See the [Query Builder docs](./docs/query-builder.md#selection-helpers) for the reference, examples, and best practices for these helpers.
|
|
231
|
+
|
|
232
|
+
#### Ergonomic column access (opt-in) with `tableRef`
|
|
233
|
+
|
|
234
|
+
If you still want the convenience of accessing columns without spelling `.columns`, you can opt-in with `tableRef()`:
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
import { tableRef, eq } from 'metal-orm';
|
|
238
|
+
|
|
239
|
+
// Existing style (always works)
|
|
240
|
+
const listOpenTodos = new SelectQueryBuilder(todos)
|
|
241
|
+
.selectColumns('id', 'title', 'done')
|
|
242
|
+
.where(eq(todos.columns.done, false))
|
|
243
|
+
.orderBy(todos.columns.id, 'ASC');
|
|
244
|
+
|
|
245
|
+
// Opt-in ergonomic style
|
|
246
|
+
const t = tableRef(todos);
|
|
247
|
+
|
|
248
|
+
const listOpenTodos2 = new SelectQueryBuilder(todos)
|
|
249
|
+
.selectColumns('id', 'title', 'done')
|
|
250
|
+
.where(eq(t.done, false))
|
|
251
|
+
.orderBy(t.id, 'ASC');
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Collision rule: real table fields win.
|
|
255
|
+
|
|
256
|
+
- `t.name` is the table name (string)
|
|
257
|
+
- `t.$.name` is the column definition for a colliding column name (escape hatch)
|
|
258
|
+
|
|
217
259
|
#### 2. Relations & hydration (still no ORM)
|
|
218
260
|
|
|
219
261
|
Now add relations and get nested objects, still without committing to a runtime.
|
|
@@ -227,6 +269,7 @@ import {
|
|
|
227
269
|
eq,
|
|
228
270
|
count,
|
|
229
271
|
rowNumber,
|
|
272
|
+
sel,
|
|
230
273
|
hydrateRows,
|
|
231
274
|
} from 'metal-orm';
|
|
232
275
|
|
|
@@ -257,19 +300,15 @@ users.columns.email.unique = true;
|
|
|
257
300
|
// Build a query with relation & window function
|
|
258
301
|
const builder = new SelectQueryBuilder(users)
|
|
259
302
|
.select({
|
|
260
|
-
|
|
261
|
-
name: users.columns.name,
|
|
262
|
-
email: users.columns.email,
|
|
303
|
+
...sel(users, 'id', 'name', 'email'),
|
|
263
304
|
postCount: count(posts.columns.id),
|
|
264
|
-
rank: rowNumber(),
|
|
305
|
+
rank: rowNumber(), // window function helper
|
|
265
306
|
})
|
|
266
307
|
.leftJoin(posts, eq(posts.columns.userId, users.columns.id))
|
|
267
308
|
.groupBy(users.columns.id, users.columns.name, users.columns.email)
|
|
268
309
|
.orderBy(count(posts.columns.id), 'DESC')
|
|
269
310
|
.limit(10)
|
|
270
|
-
.
|
|
271
|
-
columns: [posts.columns.id, posts.columns.title, posts.columns.createdAt],
|
|
272
|
-
}); // eager relation for hydration
|
|
311
|
+
.includePick('posts', ['id', 'title', 'createdAt']); // eager relation for hydration
|
|
273
312
|
|
|
274
313
|
const { sql, params } = builder.compile(dialect);
|
|
275
314
|
const [rows] = await connection.execute(sql, params);
|