@mikro-orm/sql 7.1.0-dev.2 → 7.1.0-dev.21
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/AbstractSqlConnection.d.ts +1 -1
- package/AbstractSqlConnection.js +2 -2
- package/AbstractSqlDriver.d.ts +25 -1
- package/AbstractSqlDriver.js +315 -15
- package/PivotCollectionPersister.js +13 -2
- package/SqlEntityManager.d.ts +5 -1
- package/SqlEntityManager.js +36 -1
- package/dialects/mssql/MsSqlNativeQueryBuilder.js +4 -0
- package/dialects/mysql/BaseMySqlPlatform.d.ts +1 -0
- package/dialects/mysql/BaseMySqlPlatform.js +3 -0
- package/dialects/mysql/MySqlNativeQueryBuilder.js +11 -0
- package/dialects/mysql/MySqlSchemaHelper.d.ts +9 -3
- package/dialects/mysql/MySqlSchemaHelper.js +102 -4
- package/dialects/oracledb/OracleDialect.d.ts +1 -1
- package/dialects/oracledb/OracleDialect.js +2 -1
- package/dialects/postgresql/BasePostgreSqlPlatform.d.ts +2 -0
- package/dialects/postgresql/BasePostgreSqlPlatform.js +21 -3
- package/dialects/postgresql/PostgreSqlSchemaHelper.d.ts +21 -1
- package/dialects/postgresql/PostgreSqlSchemaHelper.js +200 -4
- package/dialects/sqlite/SqlitePlatform.d.ts +1 -0
- package/dialects/sqlite/SqlitePlatform.js +4 -0
- package/dialects/sqlite/SqliteSchemaHelper.d.ts +8 -2
- package/dialects/sqlite/SqliteSchemaHelper.js +131 -19
- package/package.json +3 -3
- package/query/CriteriaNode.d.ts +1 -1
- package/query/CriteriaNode.js +2 -2
- package/query/NativeQueryBuilder.d.ts +6 -0
- package/query/NativeQueryBuilder.js +16 -1
- package/query/ObjectCriteriaNode.js +1 -1
- package/query/QueryBuilder.d.ts +77 -0
- package/query/QueryBuilder.js +170 -6
- package/schema/DatabaseSchema.js +26 -4
- package/schema/DatabaseTable.d.ts +13 -1
- package/schema/DatabaseTable.js +171 -31
- package/schema/SchemaComparator.d.ts +1 -0
- package/schema/SchemaComparator.js +86 -1
- package/schema/SchemaHelper.d.ts +51 -1
- package/schema/SchemaHelper.js +192 -3
- package/schema/SqlSchemaGenerator.js +7 -0
- package/schema/partitioning.d.ts +13 -0
- package/schema/partitioning.js +326 -0
- package/typings.d.ts +32 -1
package/query/QueryBuilder.js
CHANGED
|
@@ -159,6 +159,41 @@ export class QueryBuilder {
|
|
|
159
159
|
insert(data) {
|
|
160
160
|
return this.init(QueryType.INSERT, data);
|
|
161
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Creates an INSERT ... SELECT query that copies rows from the source query.
|
|
164
|
+
*
|
|
165
|
+
* Column resolution (3 tiers):
|
|
166
|
+
* 1. No explicit select on source, no explicit columns → all cloneable columns derived from entity metadata
|
|
167
|
+
* 2. Explicit select on source, no explicit columns → columns derived from selected field names
|
|
168
|
+
* 3. Explicit `columns` option → user-provided column list
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* // Clone all fields (columns auto-derived from metadata)
|
|
173
|
+
* const source = em.createQueryBuilder(User).where({ id: 1 });
|
|
174
|
+
* await em.createQueryBuilder(User).insertFrom(source).execute();
|
|
175
|
+
*
|
|
176
|
+
* // Clone with overrides via raw() aliases
|
|
177
|
+
* const source = em.createQueryBuilder(User)
|
|
178
|
+
* .select(['name', raw("'new@email.com'").as('email')])
|
|
179
|
+
* .where({ id: 1 });
|
|
180
|
+
* await em.createQueryBuilder(User).insertFrom(source).execute();
|
|
181
|
+
*
|
|
182
|
+
* // Explicit columns for full control
|
|
183
|
+
* await em.createQueryBuilder(User)
|
|
184
|
+
* .insertFrom(source, { columns: ['name', 'email'] })
|
|
185
|
+
* .execute();
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
insertFrom(subQuery, options) {
|
|
189
|
+
this.ensureNotFinalized();
|
|
190
|
+
this.#state.type = QueryType.INSERT;
|
|
191
|
+
this.#state.insertSubQuery = subQuery;
|
|
192
|
+
if (options?.columns) {
|
|
193
|
+
this.#state.insertColumns = Utils.asArray(options.columns);
|
|
194
|
+
}
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
162
197
|
/**
|
|
163
198
|
* Creates an UPDATE query with the given data.
|
|
164
199
|
* Use `where()` to specify which rows to update.
|
|
@@ -686,6 +721,12 @@ export class QueryBuilder {
|
|
|
686
721
|
hasFlag(flag) {
|
|
687
722
|
return this.#state.flags.has(flag);
|
|
688
723
|
}
|
|
724
|
+
/** @internal */
|
|
725
|
+
setPartitionLimit(opts) {
|
|
726
|
+
this.ensureNotFinalized();
|
|
727
|
+
this.#state.partitionLimit = opts;
|
|
728
|
+
return this;
|
|
729
|
+
}
|
|
689
730
|
cache(config = true) {
|
|
690
731
|
this.ensureNotFinalized();
|
|
691
732
|
this.#state.cache = config;
|
|
@@ -789,12 +830,18 @@ export class QueryBuilder {
|
|
|
789
830
|
if (this.#state.lockMode) {
|
|
790
831
|
this.helper.getLockSQL(qb, this.#state.lockMode, this.#state.lockTables, this.#state.joins);
|
|
791
832
|
}
|
|
792
|
-
this.processReturningStatement(qb, this.mainAlias.meta, this.#state.data, this.#state.returning);
|
|
833
|
+
this.processReturningStatement(qb, this.mainAlias.meta, this.#state.insertSubQuery ? undefined : this.#state.data, this.#state.returning);
|
|
834
|
+
if (this.#state.partitionLimit) {
|
|
835
|
+
return (this.#query.qb = this.wrapPartitionLimitSubQuery(qb));
|
|
836
|
+
}
|
|
793
837
|
return (this.#query.qb = qb);
|
|
794
838
|
}
|
|
795
839
|
processReturningStatement(qb, meta, data, returning) {
|
|
796
840
|
const usesReturningStatement = this.platform.usesReturningStatement() || this.platform.usesOutputStatement();
|
|
797
|
-
if (!meta || !
|
|
841
|
+
if (!meta || !usesReturningStatement) {
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if (!data && !this.#state.insertSubQuery) {
|
|
798
845
|
return;
|
|
799
846
|
}
|
|
800
847
|
// always respect explicit returning hint
|
|
@@ -805,13 +852,13 @@ export class QueryBuilder {
|
|
|
805
852
|
if (this.type === QueryType.INSERT) {
|
|
806
853
|
const returningProps = meta.hydrateProps
|
|
807
854
|
.filter(prop => prop.returning || (prop.persist !== false && ((prop.primary && prop.autoincrement) || prop.defaultRaw)))
|
|
808
|
-
.filter(prop => !(prop.name in data));
|
|
855
|
+
.filter(prop => !data || !(prop.name in data));
|
|
809
856
|
if (returningProps.length > 0) {
|
|
810
857
|
qb.returning(Utils.flatten(returningProps.map(prop => prop.fieldNames)));
|
|
811
858
|
}
|
|
812
859
|
return;
|
|
813
860
|
}
|
|
814
|
-
if (this.type === QueryType.UPDATE) {
|
|
861
|
+
if (this.type === QueryType.UPDATE && data) {
|
|
815
862
|
const returningProps = meta.hydrateProps.filter(prop => prop.fieldNames && isRaw(data[prop.fieldNames[0]]));
|
|
816
863
|
if (returningProps.length > 0) {
|
|
817
864
|
qb.returning(returningProps.flatMap((prop) => {
|
|
@@ -1017,9 +1064,10 @@ export class QueryBuilder {
|
|
|
1017
1064
|
options ??= {};
|
|
1018
1065
|
options.mergeResults ??= true;
|
|
1019
1066
|
options.mapResults ??= true;
|
|
1067
|
+
const chunkSize = options.chunkSize ?? 100;
|
|
1020
1068
|
const query = this.toQuery();
|
|
1021
1069
|
const loggerContext = { id: this.em?.id, ...this.loggerContext };
|
|
1022
|
-
const res = this.getConnection().stream(query.sql, query.params, this.context, loggerContext);
|
|
1070
|
+
const res = this.getConnection().stream(query.sql, query.params, this.context, loggerContext, chunkSize);
|
|
1023
1071
|
const meta = this.mainAlias.meta;
|
|
1024
1072
|
if (options.rawResults || !meta) {
|
|
1025
1073
|
yield* res;
|
|
@@ -1603,7 +1651,14 @@ export class QueryBuilder {
|
|
|
1603
1651
|
break;
|
|
1604
1652
|
}
|
|
1605
1653
|
case QueryType.INSERT:
|
|
1606
|
-
|
|
1654
|
+
if (this.#state.insertSubQuery) {
|
|
1655
|
+
const columns = this.resolveInsertFromColumns();
|
|
1656
|
+
const compiled = this.#state.insertSubQuery.toQuery();
|
|
1657
|
+
qb.insertSelect(columns, raw(compiled.sql, compiled.params));
|
|
1658
|
+
}
|
|
1659
|
+
else {
|
|
1660
|
+
qb.insert(this.#state.data);
|
|
1661
|
+
}
|
|
1607
1662
|
break;
|
|
1608
1663
|
case QueryType.UPDATE:
|
|
1609
1664
|
qb.update(this.#state.data);
|
|
@@ -1619,6 +1674,78 @@ export class QueryBuilder {
|
|
|
1619
1674
|
}
|
|
1620
1675
|
return qb;
|
|
1621
1676
|
}
|
|
1677
|
+
/**
|
|
1678
|
+
* Resolves the INSERT column list for `insertFrom()`.
|
|
1679
|
+
*
|
|
1680
|
+
* Tier 1: Explicit `insertColumns` from `options.columns` → map property names to field names
|
|
1681
|
+
* Tier 2: Source QB has explicit select fields → derive from those
|
|
1682
|
+
* Tier 3: Derive from target entity metadata (all cloneable columns), auto-populate source select
|
|
1683
|
+
*/
|
|
1684
|
+
resolveInsertFromColumns() {
|
|
1685
|
+
const meta = this.mainAlias.meta;
|
|
1686
|
+
const subQuery = this.#state.insertSubQuery;
|
|
1687
|
+
// Tier 1: explicit columns
|
|
1688
|
+
if (this.#state.insertColumns?.length) {
|
|
1689
|
+
return this.#state.insertColumns.flatMap(col => {
|
|
1690
|
+
const prop = meta?.properties[col];
|
|
1691
|
+
return prop?.fieldNames ?? [col];
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
// Tier 2: source QB has explicit select fields
|
|
1695
|
+
const sourceFields = subQuery.state.fields;
|
|
1696
|
+
if (sourceFields && subQuery.state.type === QueryType.SELECT) {
|
|
1697
|
+
return sourceFields
|
|
1698
|
+
.filter((field) => typeof field === 'string' || isRaw(field))
|
|
1699
|
+
.flatMap((field) => {
|
|
1700
|
+
if (typeof field === 'string') {
|
|
1701
|
+
// Strip alias prefix like 'a0.'
|
|
1702
|
+
const bare = field.replace(/^\w+\./, '');
|
|
1703
|
+
const prop = meta?.properties[bare];
|
|
1704
|
+
return prop?.fieldNames ?? [bare];
|
|
1705
|
+
}
|
|
1706
|
+
// RawQueryFragment with alias: raw('...').as('name')
|
|
1707
|
+
const alias = String(field.params[field.params.length - 1]);
|
|
1708
|
+
const prop = meta?.properties[alias];
|
|
1709
|
+
return prop?.fieldNames ?? [alias];
|
|
1710
|
+
});
|
|
1711
|
+
}
|
|
1712
|
+
// Tier 3: derive from metadata — all cloneable columns
|
|
1713
|
+
const cloneableProps = this.getCloneableProps(meta);
|
|
1714
|
+
const selectFields = [];
|
|
1715
|
+
const columns = [];
|
|
1716
|
+
for (const prop of cloneableProps) {
|
|
1717
|
+
for (const fieldName of prop.fieldNames) {
|
|
1718
|
+
columns.push(fieldName);
|
|
1719
|
+
selectFields.push(fieldName);
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
// Auto-populate source select with matching fields
|
|
1723
|
+
if (!sourceFields) {
|
|
1724
|
+
subQuery.select(selectFields);
|
|
1725
|
+
}
|
|
1726
|
+
return columns;
|
|
1727
|
+
}
|
|
1728
|
+
/** Returns properties that are safe to clone (persistable, non-PK, non-generated). */
|
|
1729
|
+
getCloneableProps(meta) {
|
|
1730
|
+
return meta.props.filter(prop => {
|
|
1731
|
+
if (prop.persist === false) {
|
|
1732
|
+
return false;
|
|
1733
|
+
}
|
|
1734
|
+
if (prop.primary) {
|
|
1735
|
+
return false;
|
|
1736
|
+
}
|
|
1737
|
+
if (!prop.fieldNames?.length) {
|
|
1738
|
+
return false;
|
|
1739
|
+
}
|
|
1740
|
+
if ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
|
|
1741
|
+
return false;
|
|
1742
|
+
}
|
|
1743
|
+
if (prop.kind === ReferenceKind.EMBEDDED && !prop.object) {
|
|
1744
|
+
return false;
|
|
1745
|
+
}
|
|
1746
|
+
return true;
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1622
1749
|
applyDiscriminatorCondition() {
|
|
1623
1750
|
const meta = this.mainAlias.meta;
|
|
1624
1751
|
if (meta.root.inheritanceType !== 'sti' || !meta.discriminatorValue) {
|
|
@@ -1782,6 +1909,9 @@ export class QueryBuilder {
|
|
|
1782
1909
|
(this.#state.limit > 0 || this.#state.offset > 0)) {
|
|
1783
1910
|
this.wrapPaginateSubQuery(meta);
|
|
1784
1911
|
}
|
|
1912
|
+
if (this.#state.partitionLimit) {
|
|
1913
|
+
this.preparePartitionLimit();
|
|
1914
|
+
}
|
|
1785
1915
|
if (meta &&
|
|
1786
1916
|
(this.#state.flags.has(QueryFlag.UPDATE_SUB_QUERY) || this.#state.flags.has(QueryFlag.DELETE_SUB_QUERY))) {
|
|
1787
1917
|
this.wrapModifySubQuery(meta);
|
|
@@ -2001,6 +2131,40 @@ export class QueryBuilder {
|
|
|
2001
2131
|
[Utils.getPrimaryKeyHash(meta.primaryKeys)]: { $in: raw(sql, params) },
|
|
2002
2132
|
});
|
|
2003
2133
|
}
|
|
2134
|
+
/**
|
|
2135
|
+
* Wraps the inner query (which has ROW_NUMBER in SELECT) with an outer query
|
|
2136
|
+
* that filters by the __rn column to apply per-parent limiting.
|
|
2137
|
+
*/
|
|
2138
|
+
wrapPartitionLimitSubQuery(innerQb) {
|
|
2139
|
+
const { limit, offset = 0 } = this.#state.partitionLimit;
|
|
2140
|
+
const rnCol = this.platform.quoteIdentifier('__rn');
|
|
2141
|
+
innerQb.as(this.mainAlias.aliasName);
|
|
2142
|
+
const outerQb = this.platform.createNativeQueryBuilder();
|
|
2143
|
+
outerQb.select('*').from(innerQb);
|
|
2144
|
+
outerQb.where(`${rnCol} > ? and ${rnCol} <= ?`, [offset, offset + limit]);
|
|
2145
|
+
outerQb.orderBy(rnCol);
|
|
2146
|
+
return outerQb;
|
|
2147
|
+
}
|
|
2148
|
+
/**
|
|
2149
|
+
* Adds ROW_NUMBER() OVER (PARTITION BY ...) to the SELECT list and prepares
|
|
2150
|
+
* the query state for per-parent limiting. The actual wrapping into a subquery
|
|
2151
|
+
* with __rn filtering happens in getNativeQuery().
|
|
2152
|
+
*/
|
|
2153
|
+
preparePartitionLimit() {
|
|
2154
|
+
const { partitionBy } = this.#state.partitionLimit;
|
|
2155
|
+
// `partitionBy` is always a declared property name, so mapper returns a string here.
|
|
2156
|
+
const partitionCol = this.helper.mapper(partitionBy, this.type, undefined, null);
|
|
2157
|
+
const quotedPartition = partitionCol
|
|
2158
|
+
.split('.')
|
|
2159
|
+
.map(e => this.platform.quoteIdentifier(e))
|
|
2160
|
+
.join('.');
|
|
2161
|
+
const queryOrder = this.helper.getQueryOrder(this.type, this.#state.orderBy, this.#state.populateMap, this.#state.collation);
|
|
2162
|
+
const orderBySql = queryOrder.length > 0 ? Utils.unique(queryOrder).join(', ') : quotedPartition;
|
|
2163
|
+
const rnAlias = this.platform.quoteIdentifier('__rn');
|
|
2164
|
+
this.#state.fields.push(raw(`row_number() over (partition by ${quotedPartition} order by ${orderBySql}) as ${rnAlias}`));
|
|
2165
|
+
// Moved into the OVER clause; outer query re-applies via wrapPartitionLimitSubQuery
|
|
2166
|
+
this.#state.orderBy = [];
|
|
2167
|
+
}
|
|
2004
2168
|
/**
|
|
2005
2169
|
* Computes the set of populate paths from the _populate hints.
|
|
2006
2170
|
*/
|
package/schema/DatabaseSchema.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReferenceKind, isRaw, } from '@mikro-orm/core';
|
|
2
2
|
import { DatabaseTable } from './DatabaseTable.js';
|
|
3
|
+
import { getTablePartitioning } from './partitioning.js';
|
|
3
4
|
/**
|
|
4
5
|
* @internal
|
|
5
6
|
*/
|
|
@@ -173,6 +174,9 @@ export class DatabaseSchema {
|
|
|
173
174
|
}
|
|
174
175
|
const table = schema.addTable(meta.collection, this.getSchemaName(meta, config, schemaName));
|
|
175
176
|
table.comment = meta.comment;
|
|
177
|
+
if (meta.partitionBy) {
|
|
178
|
+
table.setPartitioning(getTablePartitioning(meta, this.getSchemaName(meta, config, schemaName), id => platform.quoteIdentifier(id)));
|
|
179
|
+
}
|
|
176
180
|
// For TPT child entities, only use ownProps (properties defined in this entity only)
|
|
177
181
|
// For all other entities (including TPT root), use all props
|
|
178
182
|
const propsToProcess = meta.inheritanceType === 'tpt' && meta.tptParent && meta.ownProps ? meta.ownProps : meta.props;
|
|
@@ -220,6 +224,20 @@ export class DatabaseSchema {
|
|
|
220
224
|
columnName,
|
|
221
225
|
});
|
|
222
226
|
}
|
|
227
|
+
for (const trigger of meta.triggers) {
|
|
228
|
+
const body = isRaw(trigger.body)
|
|
229
|
+
? platform.formatQuery(trigger.body.sql, trigger.body.params)
|
|
230
|
+
: trigger.body;
|
|
231
|
+
table.addTrigger({
|
|
232
|
+
name: trigger.name,
|
|
233
|
+
timing: trigger.timing,
|
|
234
|
+
events: trigger.events,
|
|
235
|
+
forEach: trigger.forEach ?? 'row',
|
|
236
|
+
body: body ?? '',
|
|
237
|
+
when: trigger.when,
|
|
238
|
+
expression: trigger.expression,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
223
241
|
}
|
|
224
242
|
return schema;
|
|
225
243
|
}
|
|
@@ -323,12 +341,16 @@ export class DatabaseSchema {
|
|
|
323
341
|
(prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner));
|
|
324
342
|
}
|
|
325
343
|
toJSON() {
|
|
344
|
+
// locale-independent comparison so the snapshot is stable across machines
|
|
345
|
+
const byString = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
346
|
+
const tableKey = (t) => `${t.schema ?? ''}.${t.name}`;
|
|
347
|
+
const byTable = (a, b) => byString(tableKey(a), tableKey(b));
|
|
326
348
|
return {
|
|
327
349
|
name: this.name,
|
|
328
|
-
namespaces: [...this.#namespaces],
|
|
329
|
-
tables: this.#tables,
|
|
330
|
-
views: this.#views,
|
|
331
|
-
nativeEnums: this.#nativeEnums,
|
|
350
|
+
namespaces: [...this.#namespaces].sort(),
|
|
351
|
+
tables: [...this.#tables].sort(byTable),
|
|
352
|
+
views: [...this.#views].sort(byTable),
|
|
353
|
+
nativeEnums: Object.fromEntries(Object.entries(this.#nativeEnums).sort(([a], [b]) => byString(a, b))),
|
|
332
354
|
};
|
|
333
355
|
}
|
|
334
356
|
prune(schema, wildcardSchemaTables) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Configuration, type DeferMode, type Dictionary, type EntityMetadata, type EntityProperty, type IndexCallback, type NamingStrategy } from '@mikro-orm/core';
|
|
2
2
|
import type { SchemaHelper } from './SchemaHelper.js';
|
|
3
|
-
import type { CheckDef, Column, ForeignKey, IndexDef } from '../typings.js';
|
|
3
|
+
import type { CheckDef, Column, ForeignKey, IndexDef, TablePartitioning, SqlTriggerDef } from '../typings.js';
|
|
4
4
|
import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
|
|
5
5
|
/**
|
|
6
6
|
* @internal
|
|
@@ -15,6 +15,7 @@ export declare class DatabaseTable {
|
|
|
15
15
|
items: string[];
|
|
16
16
|
}>;
|
|
17
17
|
comment?: string;
|
|
18
|
+
partitioning?: TablePartitioning;
|
|
18
19
|
constructor(platform: AbstractSqlPlatform, name: string, schema?: string | undefined);
|
|
19
20
|
getQuotedName(): string;
|
|
20
21
|
getColumns(): Column[];
|
|
@@ -22,11 +23,17 @@ export declare class DatabaseTable {
|
|
|
22
23
|
removeColumn(name: string): void;
|
|
23
24
|
getIndexes(): IndexDef[];
|
|
24
25
|
getChecks(): CheckDef[];
|
|
26
|
+
getPartitioning(): TablePartitioning | undefined;
|
|
27
|
+
/** @internal */
|
|
28
|
+
setPartitioning(partitioning?: TablePartitioning): void;
|
|
29
|
+
getTriggers(): SqlTriggerDef[];
|
|
25
30
|
/** @internal */
|
|
26
31
|
setIndexes(indexes: IndexDef[]): void;
|
|
27
32
|
/** @internal */
|
|
28
33
|
setChecks(checks: CheckDef[]): void;
|
|
29
34
|
/** @internal */
|
|
35
|
+
setTriggers(triggers: SqlTriggerDef[]): void;
|
|
36
|
+
/** @internal */
|
|
30
37
|
setForeignKeys(fks: Dictionary<ForeignKey>): void;
|
|
31
38
|
init(cols: Column[], indexes: IndexDef[] | undefined, checks: CheckDef[] | undefined, pks: string[], fks?: Dictionary<ForeignKey>, enums?: Dictionary<string[]>): void;
|
|
32
39
|
addColumn(column: Column): void;
|
|
@@ -47,6 +54,8 @@ export declare class DatabaseTable {
|
|
|
47
54
|
hasIndex(indexName: string): boolean;
|
|
48
55
|
getCheck(checkName: string): CheckDef | undefined;
|
|
49
56
|
hasCheck(checkName: string): boolean;
|
|
57
|
+
getTrigger(triggerName: string): SqlTriggerDef | undefined;
|
|
58
|
+
hasTrigger(triggerName: string): boolean;
|
|
50
59
|
getPrimaryKey(): IndexDef | undefined;
|
|
51
60
|
hasPrimaryKey(): boolean;
|
|
52
61
|
private getForeignKeyDeclaration;
|
|
@@ -62,6 +71,7 @@ export declare class DatabaseTable {
|
|
|
62
71
|
name?: string;
|
|
63
72
|
type?: string;
|
|
64
73
|
expression?: string | IndexCallback<any>;
|
|
74
|
+
where?: string | Dictionary;
|
|
65
75
|
deferMode?: DeferMode | `${DeferMode}`;
|
|
66
76
|
options?: Dictionary;
|
|
67
77
|
columns?: {
|
|
@@ -77,6 +87,8 @@ export declare class DatabaseTable {
|
|
|
77
87
|
disabled?: boolean;
|
|
78
88
|
clustered?: boolean;
|
|
79
89
|
}, type: 'index' | 'unique' | 'primary'): void;
|
|
90
|
+
private processIndexWhere;
|
|
80
91
|
addCheck(check: CheckDef): void;
|
|
92
|
+
addTrigger(trigger: SqlTriggerDef): void;
|
|
81
93
|
toJSON(): Dictionary;
|
|
82
94
|
}
|