oak-db 3.3.13 → 4.0.0

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.
@@ -53,7 +53,11 @@ export declare abstract class SqlTranslator<ED extends EntityDict & BaseEntityDi
53
53
  };
54
54
  private translateSorter;
55
55
  private translateProjection;
56
- private translateSelectInner;
56
+ protected translateSelectInner<T extends keyof ED, OP extends SqlSelectOption>(entity: T, selection: ED[T]['Selection'], initialNumber: number, refAlias: Record<string, [string, keyof ED]>, option?: OP): {
57
+ filterStmt: string;
58
+ stmt: string;
59
+ currentNumber: number;
60
+ };
57
61
  translateSelect<T extends keyof ED, OP extends SqlSelectOption>(entity: T, selection: ED[T]['Selection'], option?: OP): string;
58
62
  translateWhere<T extends keyof ED, OP extends SqlSelectOption>(entity: T, selection: ED[T]['Selection'], option?: OP): string;
59
63
  translateAggregate<T extends keyof ED, OP extends SqlSelectOption>(entity: T, aggregation: ED[T]['Aggregation'], option?: OP): string;
@@ -564,10 +564,10 @@ class SqlTranslator {
564
564
  translateFilter(entity, filter, aliasDict, filterRefAlias, initialNumber, option) {
565
565
  const { schema } = this;
566
566
  let currentNumber = initialNumber;
567
- const translateInner = (entity2, path, filter2, type) => {
567
+ const translateInner = (entity2, path, filter2, skipDeletePhy) => {
568
568
  const alias = aliasDict[path];
569
569
  const { attributes } = schema[entity2];
570
- let whereText = type ? '' : this.getDefaultSelectFilter(alias, option);
570
+ let whereText = skipDeletePhy ? '' : this.getDefaultSelectFilter(alias, option);
571
571
  if (filter2) {
572
572
  const attrs = Object.keys(filter2).filter(ele => !ele.startsWith('#'));
573
573
  attrs.forEach((attr) => {
@@ -582,7 +582,7 @@ class SqlTranslator {
582
582
  case '$xor': {
583
583
  const logicQueries = filter2[attr];
584
584
  logicQueries.forEach((logicQuery, index) => {
585
- const sql = translateInner(entity2, path, logicQuery, 'ref'); // 只要传个值就行了,应该无所谓
585
+ const sql = translateInner(entity2, path, logicQuery, true); // 只要传个值就行了,应该无所谓
586
586
  if (sql) {
587
587
  whereText += ` (${sql})`;
588
588
  if (index < logicQueries.length - 1) {
@@ -595,7 +595,7 @@ class SqlTranslator {
595
595
  default: {
596
596
  (0, assert_1.default)(attr === '$not');
597
597
  const logicQuery = filter2[attr];
598
- const sql = translateInner(entity2, path, logicQuery, 'ref'); // 只要传个值就行了,应该无所谓
598
+ const sql = translateInner(entity2, path, logicQuery, true); // 只要传个值就行了,应该无所谓
599
599
  if (sql) {
600
600
  whereText += ` not (${sql})`;
601
601
  break;
@@ -965,6 +965,10 @@ class SqlTranslator {
965
965
  const { data, filter, sorter, indexFrom, count } = operation;
966
966
  (0, assert_1.default)(!sorter, '当前remove不支持sorter行为');
967
967
  const { aliasDict, filterRefAlias, from: fromText, currentNumber } = this.analyzeJoin(entity, { filter, sorter });
968
+ // 对于limit,如果有indexForm则一定有count
969
+ if (typeof indexFrom === 'number') {
970
+ (0, assert_1.default)(typeof count === 'number' && count > 0);
971
+ }
968
972
  const alias = aliasDict['./'];
969
973
  // 这里原来includeDeleted传的是true,不知道原因,但不合理
970
974
  const { stmt: filterText } = this.translateFilter(entity, filter, aliasDict, filterRefAlias, currentNumber, { includedDeleted: option?.includedDeleted });
@@ -992,6 +996,10 @@ class SqlTranslator {
992
996
  const { filter, sorter, indexFrom, count, data } = operation;
993
997
  (0, assert_1.default)(!sorter, '当前update不支持sorter行为');
994
998
  const { aliasDict, filterRefAlias, from: fromText, currentNumber } = this.analyzeJoin(entity, { filter, sorter });
999
+ // 对于limit,如果有indexForm则一定有count
1000
+ if (typeof indexFrom === 'number') {
1001
+ (0, assert_1.default)(typeof count === 'number' && count > 0);
1002
+ }
995
1003
  const alias = aliasDict['./'];
996
1004
  let updateText = '';
997
1005
  for (const attr in data) {
@@ -1,23 +1,16 @@
1
- import { Attribute, EntityDict, Index, OperateOption, OperationResult, StorageSchema, TxnOption } from 'oak-domain/lib/types';
1
+ import { EntityDict, OperateOption, OperationResult, StorageSchema, TxnOption } from 'oak-domain/lib/types';
2
2
  import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
3
3
  import { AsyncContext, AsyncRowStore } from "oak-domain/lib/store/AsyncRowStore";
4
4
  import { CreateEntityOption } from "./Translator";
5
5
  import { AggregationResult, SelectOption } from "oak-domain/lib/types";
6
- export type Plan = {
7
- newTables: Record<string, {
8
- attributes: Record<string, Attribute>;
9
- }>;
10
- newIndexes: Record<string, Index<any>[]>;
11
- updatedTables: Record<string, {
12
- attributes: Record<string, Attribute & {
13
- isNew: boolean;
14
- }>;
15
- }>;
16
- updatedIndexes: Record<string, Index<any>[]>;
17
- };
6
+ export type { Plan } from './migration';
7
+ import type { MigrationPlanningOptions, Plan } from './migration';
18
8
  export interface DbStore<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> extends AsyncRowStore<ED, Cxt> {
9
+ checkRelationAsync<T extends keyof ED, Cxt extends AsyncContext<ED>>(entity: T, operation: Omit<ED[T]['Operation'] | ED[T]['Selection'], 'id'>, context: Cxt): Promise<void>;
19
10
  connect: () => Promise<void>;
20
11
  disconnect: () => Promise<void>;
12
+ exec(script: string, txnId?: string): Promise<void>;
13
+ supportsTransactionalDdl(): boolean;
21
14
  initialize(options: CreateEntityOption): Promise<void>;
22
15
  aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
23
16
  operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OperateOption): Promise<OperationResult<ED>>;
@@ -27,6 +20,6 @@ export interface DbStore<ED extends EntityDict & BaseEntityDict, Cxt extends Asy
27
20
  commit(txnId: string): Promise<void>;
28
21
  rollback(txnId: string): Promise<void>;
29
22
  readSchema(): Promise<StorageSchema<ED>>;
30
- makeUpgradePlan(): Promise<Plan>;
31
- diffSchema(schemaOld: StorageSchema<any>, schemaNew: StorageSchema<any>): Plan;
23
+ makeUpgradePlan(options?: MigrationPlanningOptions): Promise<Plan>;
24
+ diffSchema(schemaOld: StorageSchema<ED>, schemaNew: StorageSchema<ED>, options?: MigrationPlanningOptions): Plan;
32
25
  }
@@ -0,0 +1,251 @@
1
+ import { Attribute, EntityDict, GeneralEntityShape, Index, StorageDesc, StorageSchema } from 'oak-domain/lib/types';
2
+ export type MigrationEntityDict = EntityDict;
3
+ export type MigrationEntityKey = keyof MigrationEntityDict & string;
4
+ export type MigrationSchema<ED extends MigrationEntityDict = MigrationEntityDict> = StorageSchema<ED>;
5
+ export type MigrationTableDef<SH extends GeneralEntityShape = GeneralEntityShape> = StorageDesc<SH>;
6
+ export type MigrationIndex<SH extends GeneralEntityShape = GeneralEntityShape> = Index<SH>;
7
+ export interface MigrationIndexMetadata {
8
+ __originName?: string;
9
+ __originNames?: string[];
10
+ }
11
+ export type MigrationIndexWithOrigin = MigrationIndex & MigrationIndexMetadata;
12
+ export type MigrationWarningLevel = 'info' | 'warning';
13
+ export type MigrationWarningCode = 'rename-candidate' | 'manual-column-change' | 'manual-index-change' | 'manual-foreign-key-change' | 'manual-enum-change' | 'manual-constraint-change' | 'large-table-index-change';
14
+ export interface MigrationWarning {
15
+ code: MigrationWarningCode;
16
+ level: MigrationWarningLevel;
17
+ message: string;
18
+ table?: string;
19
+ column?: string;
20
+ sql?: string[];
21
+ }
22
+ export interface RenameCandidate {
23
+ table: string;
24
+ from: string;
25
+ to: string;
26
+ reason: string;
27
+ sql: string[];
28
+ }
29
+ export interface ForeignKeyDef {
30
+ name: string;
31
+ column: string;
32
+ refTable: string;
33
+ refColumn: string;
34
+ onDelete: 'cascade' | 'set null' | 'no action';
35
+ }
36
+ export interface TableStats {
37
+ rowCount?: number;
38
+ approximate?: boolean;
39
+ }
40
+ export interface SchemaInspectionResult<ED extends MigrationEntityDict = MigrationEntityDict> {
41
+ schema: MigrationSchema<ED>;
42
+ tableStats: Record<string, TableStats>;
43
+ }
44
+ export interface MigrationPlanningOptions {
45
+ currentTableStats?: Record<string, TableStats>;
46
+ largeTableRowThreshold?: number;
47
+ compareForeignKeys?: boolean;
48
+ }
49
+ export interface IndexPlanContext {
50
+ isNewTable: boolean;
51
+ tableStats?: TableStats;
52
+ largeTableRowThreshold: number;
53
+ }
54
+ export interface MigrationPlanSummary {
55
+ newTables: number;
56
+ removedTables: number;
57
+ addedColumns: number;
58
+ removedColumns: number;
59
+ changedColumns: number;
60
+ addedIndexes: number;
61
+ removedIndexes: number;
62
+ changedIndexes: number;
63
+ addedForeignKeys: number;
64
+ removedForeignKeys: number;
65
+ changedForeignKeys: number;
66
+ manualActions: number;
67
+ onlineActions: number;
68
+ largeTableIndexes: number;
69
+ }
70
+ export type MigrationSqlCategory = 'prepareSql' | 'forwardSql' | 'onlineSql' | 'manualSql' | 'backwardSql';
71
+ export interface MigrationSqlByCategory {
72
+ prepareSql: string[];
73
+ forwardSql: string[];
74
+ onlineSql: string[];
75
+ manualSql: string[];
76
+ backwardSql: string[];
77
+ }
78
+ export interface MigrationTableColumnAddition {
79
+ name: string;
80
+ categories: MigrationSqlCategory[];
81
+ reason?: string;
82
+ definition: AttributeSnapshot;
83
+ sql: MigrationSqlByCategory;
84
+ }
85
+ export interface MigrationTableColumnRemoval {
86
+ name: string;
87
+ categories: MigrationSqlCategory[];
88
+ definition: AttributeSnapshot;
89
+ sql: MigrationSqlByCategory;
90
+ }
91
+ export interface MigrationTableColumnChange {
92
+ name: string;
93
+ categories: MigrationSqlCategory[];
94
+ reason?: string;
95
+ before: AttributeSnapshot;
96
+ after: AttributeSnapshot;
97
+ sql: MigrationSqlByCategory;
98
+ }
99
+ export interface MigrationTableColumnRename {
100
+ from: string;
101
+ to: string;
102
+ categories: MigrationSqlCategory[];
103
+ reason: string;
104
+ before: AttributeSnapshot;
105
+ after: AttributeSnapshot;
106
+ sql: MigrationSqlByCategory;
107
+ }
108
+ export interface MigrationTableIndexAddition {
109
+ name: string;
110
+ categories: MigrationSqlCategory[];
111
+ definition: IndexSnapshot;
112
+ sql: MigrationSqlByCategory;
113
+ }
114
+ export interface MigrationTableIndexRemoval {
115
+ name: string;
116
+ categories: MigrationSqlCategory[];
117
+ definition: IndexSnapshot;
118
+ sql: MigrationSqlByCategory;
119
+ }
120
+ export interface MigrationTableIndexChange {
121
+ name: string;
122
+ categories: MigrationSqlCategory[];
123
+ before: IndexSnapshot;
124
+ after: IndexSnapshot;
125
+ sql: MigrationSqlByCategory;
126
+ }
127
+ export interface MigrationTableIndexRename {
128
+ from: string;
129
+ to: string;
130
+ categories: MigrationSqlCategory[];
131
+ before: IndexSnapshot;
132
+ after: IndexSnapshot;
133
+ sql: MigrationSqlByCategory;
134
+ }
135
+ export interface MigrationTableForeignKeyAddition {
136
+ name: string;
137
+ categories: MigrationSqlCategory[];
138
+ definition: ForeignKeyDef;
139
+ sql: MigrationSqlByCategory;
140
+ }
141
+ export interface MigrationTableForeignKeyRemoval {
142
+ name: string;
143
+ categories: MigrationSqlCategory[];
144
+ definition: ForeignKeyDef;
145
+ sql: MigrationSqlByCategory;
146
+ }
147
+ export interface MigrationTableForeignKeyChange {
148
+ name: string;
149
+ categories: MigrationSqlCategory[];
150
+ before?: ForeignKeyDef;
151
+ after?: ForeignKeyDef;
152
+ sql: MigrationSqlByCategory;
153
+ }
154
+ export interface MigrationTableChange {
155
+ entity: string;
156
+ table: string;
157
+ lifecycle: 'create' | 'alter' | 'drop';
158
+ summary: MigrationPlanSummary;
159
+ sql: MigrationSqlByCategory;
160
+ columns: {
161
+ added: MigrationTableColumnAddition[];
162
+ removed: MigrationTableColumnRemoval[];
163
+ changed: MigrationTableColumnChange[];
164
+ renamed: MigrationTableColumnRename[];
165
+ };
166
+ indexes: {
167
+ added: MigrationTableIndexAddition[];
168
+ removed: MigrationTableIndexRemoval[];
169
+ changed: MigrationTableIndexChange[];
170
+ renamed: MigrationTableIndexRename[];
171
+ };
172
+ foreignKeys: {
173
+ added: MigrationTableForeignKeyAddition[];
174
+ removed: MigrationTableForeignKeyRemoval[];
175
+ changed: MigrationTableForeignKeyChange[];
176
+ };
177
+ warnings: MigrationWarning[];
178
+ renameCandidates: RenameCandidate[];
179
+ }
180
+ export interface MigrationPlan<ED extends MigrationEntityDict = MigrationEntityDict> {
181
+ currentSchema: MigrationSchema<ED>;
182
+ targetSchema: MigrationSchema<ED>;
183
+ prepareSql: string[];
184
+ forwardSql: string[];
185
+ onlineSql: string[];
186
+ manualSql: string[];
187
+ backwardSql: string[];
188
+ warnings: MigrationWarning[];
189
+ renameCandidates: RenameCandidate[];
190
+ summary: MigrationPlanSummary;
191
+ tableChanges: MigrationTableChange[];
192
+ }
193
+ export type Plan<ED extends MigrationEntityDict = MigrationEntityDict> = MigrationPlan<ED>;
194
+ export interface MigrationChangePlan {
195
+ prepareSql?: string[];
196
+ forwardSql?: string[];
197
+ deferredForwardSql?: string[];
198
+ onlineSql?: string[];
199
+ manualSql?: string[];
200
+ backwardSql?: string[];
201
+ warnings?: MigrationWarning[];
202
+ renameCandidates?: RenameCandidate[];
203
+ summary?: Partial<MigrationPlanSummary>;
204
+ }
205
+ export interface AttributeSnapshot {
206
+ type: string;
207
+ params?: Record<string, number>;
208
+ enumeration?: string[];
209
+ ref?: string | string[];
210
+ onRefDelete?: 'delete' | 'setNull' | 'ignore';
211
+ default?: string | number | boolean;
212
+ notNull: boolean;
213
+ unique: boolean;
214
+ sequence: boolean;
215
+ }
216
+ export interface IndexSnapshot {
217
+ name: string;
218
+ attributes: Array<{
219
+ name: string;
220
+ direction?: 'ASC' | 'DESC';
221
+ size?: number;
222
+ }>;
223
+ config: {
224
+ unique: boolean;
225
+ type: 'btree' | 'hash' | 'spatial' | 'fulltext';
226
+ parser?: string;
227
+ tsConfig?: string | string[];
228
+ chineseParser?: string;
229
+ };
230
+ }
231
+ export interface AttributeChangeClassification {
232
+ mode: 'none' | 'forward' | 'manual';
233
+ reason?: string;
234
+ enumAppendOnly?: true;
235
+ }
236
+ export interface SchemaMigrationAdapter<ED extends MigrationEntityDict = MigrationEntityDict> {
237
+ readonly dialect: 'mysql' | 'postgresql';
238
+ normalizeIdentifier(name: string): string;
239
+ getTableName(table: string, tableDef?: {
240
+ storageName?: string;
241
+ }): string;
242
+ buildPrepareSql(currentSchema: MigrationSchema<ED>, targetSchema: MigrationSchema<ED>): string[];
243
+ buildNewTablePlan(table: string, tableDef: MigrationTableDef): MigrationChangePlan;
244
+ buildDropTablePlan(tableName: string): MigrationChangePlan;
245
+ buildRenamePlan(tableName: string, from: string, to: string, oldAttr: Attribute, newAttr: Attribute): MigrationChangePlan;
246
+ buildColumnPlan(tableName: string, column: string, oldAttr: Attribute | undefined, newAttr: Attribute | undefined, classification: AttributeChangeClassification): MigrationChangePlan;
247
+ buildIndexPlan(tableName: string, table: string, oldIndex: MigrationIndexWithOrigin | undefined, newIndex: MigrationIndexWithOrigin | undefined, context: IndexPlanContext): MigrationChangePlan;
248
+ buildRenameIndexPlan(tableName: string, table: string, oldIndex: MigrationIndexWithOrigin, newIndex: MigrationIndexWithOrigin, context: IndexPlanContext): MigrationChangePlan;
249
+ buildForeignKeyPlan(tableName: string, oldForeignKey: ForeignKeyDef | undefined, newForeignKey: ForeignKeyDef | undefined, isNewTable: boolean): MigrationChangePlan;
250
+ getForeignKeys(table: string, tableDef: MigrationTableDef, fullSchema: MigrationSchema<ED>): Record<string, ForeignKeyDef>;
251
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ import { MigrationIndexWithOrigin } from '../types/migration';
2
+ export declare function getIndexOriginNames(index: MigrationIndexWithOrigin): string[];
3
+ export declare function mergeIndexOriginName(index: MigrationIndexWithOrigin, originName: string): void;
4
+ export declare function areEquivalentInspectedIndexes(left: MigrationIndexWithOrigin, right: MigrationIndexWithOrigin): boolean;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getIndexOriginNames = getIndexOriginNames;
4
+ exports.mergeIndexOriginName = mergeIndexOriginName;
5
+ exports.areEquivalentInspectedIndexes = areEquivalentInspectedIndexes;
6
+ function getIndexOriginNames(index) {
7
+ return index.__originNames?.length
8
+ ? [...index.__originNames]
9
+ : (index.__originName
10
+ ? [index.__originName]
11
+ : [index.name]);
12
+ }
13
+ function mergeIndexOriginName(index, originName) {
14
+ const originNames = new Set();
15
+ if (index.__originName) {
16
+ originNames.add(index.__originName);
17
+ }
18
+ (index.__originNames || []).forEach((name) => originNames.add(name));
19
+ originNames.add(originName);
20
+ const merged = Array.from(originNames);
21
+ delete index.__originName;
22
+ index.__originNames = merged;
23
+ }
24
+ function areEquivalentInspectedIndexes(left, right) {
25
+ return JSON.stringify({
26
+ attributes: left.attributes,
27
+ config: left.config || {},
28
+ }) === JSON.stringify({
29
+ attributes: right.attributes,
30
+ config: right.config || {},
31
+ });
32
+ }
@@ -0,0 +1,15 @@
1
+ export declare function buildEntityIndexPrefix(name: string): string;
2
+ export declare function shortenIdentifierWithHash(identifier: string, maxLength: number): string;
3
+ export interface CompactIndexNameOptions {
4
+ entityName: string;
5
+ tableName?: string;
6
+ logicalName: string;
7
+ suffix?: string;
8
+ maxLength: number;
9
+ }
10
+ export interface LegacyIndexNameOptions extends CompactIndexNameOptions {
11
+ serverTruncatesWhenOverflow?: boolean;
12
+ }
13
+ export declare function buildCompactPhysicalIndexName(options: CompactIndexNameOptions): string;
14
+ export declare function buildLegacyPhysicalIndexNames(options: LegacyIndexNameOptions): string[];
15
+ export declare function matchesPhysicalIndexName(actualName: string, options: LegacyIndexNameOptions): boolean;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildEntityIndexPrefix = buildEntityIndexPrefix;
4
+ exports.shortenIdentifierWithHash = shortenIdentifierWithHash;
5
+ exports.buildCompactPhysicalIndexName = buildCompactPhysicalIndexName;
6
+ exports.buildLegacyPhysicalIndexNames = buildLegacyPhysicalIndexNames;
7
+ exports.matchesPhysicalIndexName = matchesPhysicalIndexName;
8
+ const crypto_1 = require("crypto");
9
+ function uniqueNonEmpty(values) {
10
+ return Array.from(new Set(values.filter(Boolean)));
11
+ }
12
+ function splitIdentifier(name) {
13
+ const normalized = name
14
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
15
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
16
+ .replace(/[_\-\s]+/g, ' ')
17
+ .trim();
18
+ return normalized ? normalized.split(/\s+/).filter(Boolean) : [];
19
+ }
20
+ function stripLogicalIndexPrefix(logicalName, prefixes) {
21
+ for (const prefix of uniqueNonEmpty(prefixes)) {
22
+ if (logicalName.startsWith(`${prefix}_`)) {
23
+ return logicalName.slice(prefix.length + 1);
24
+ }
25
+ }
26
+ return logicalName;
27
+ }
28
+ function buildEntityIndexPrefix(name) {
29
+ const parts = splitIdentifier(name);
30
+ if (parts.length === 0) {
31
+ return 'i';
32
+ }
33
+ const [first, ...rest] = parts;
34
+ return `${first.slice(0, Math.min(3, first.length)).toLowerCase()}${rest.map((part) => part[0].toUpperCase()).join('')}`;
35
+ }
36
+ function shortenIdentifierWithHash(identifier, maxLength) {
37
+ if (identifier.length <= maxLength) {
38
+ return identifier;
39
+ }
40
+ const hash = (0, crypto_1.createHash)('sha1')
41
+ .update(identifier)
42
+ .digest('hex')
43
+ .slice(0, 8);
44
+ const prefixLength = Math.max(1, maxLength - hash.length - 1);
45
+ return `${identifier.slice(0, prefixLength)}_${hash}`;
46
+ }
47
+ function buildCompactPhysicalIndexName(options) {
48
+ const { entityName, tableName, logicalName, suffix = '', maxLength, } = options;
49
+ const compactPrefix = buildEntityIndexPrefix(entityName || tableName || logicalName);
50
+ const baseName = stripLogicalIndexPrefix(logicalName, uniqueNonEmpty([entityName, tableName]));
51
+ return shortenIdentifierWithHash(`${compactPrefix}_${baseName}${suffix}`, maxLength);
52
+ }
53
+ function buildLegacyPhysicalIndexNames(options) {
54
+ const { entityName, tableName, logicalName, suffix = '', maxLength, serverTruncatesWhenOverflow, } = options;
55
+ const names = new Set();
56
+ const prefixedBases = uniqueNonEmpty([entityName, tableName]);
57
+ names.add(`${logicalName}${suffix}`);
58
+ prefixedBases.forEach((base) => {
59
+ names.add(`${base}_${logicalName}${suffix}`);
60
+ names.add(logicalName.startsWith(`${base}_`)
61
+ ? `${logicalName}${suffix}`
62
+ : `${base}_${logicalName}${suffix}`);
63
+ });
64
+ names.add(buildCompactPhysicalIndexName(options));
65
+ const resolved = new Set();
66
+ names.forEach((name) => {
67
+ resolved.add(name);
68
+ if (serverTruncatesWhenOverflow && name.length > maxLength) {
69
+ resolved.add(name.slice(0, maxLength));
70
+ }
71
+ });
72
+ return Array.from(resolved);
73
+ }
74
+ function matchesPhysicalIndexName(actualName, options) {
75
+ return buildLegacyPhysicalIndexNames(options).includes(actualName);
76
+ }
@@ -0,0 +1,13 @@
1
+ import { Attribute } from 'oak-domain/lib/types';
2
+ import { MigrationEntityDict, MigrationSchema, MigrationTableDef } from '../types/migration';
3
+ export interface InspectionTypeHintRule {
4
+ actualTypes: string[];
5
+ semanticTypes: string[];
6
+ }
7
+ export declare function buildTargetTableHintMap<ED extends MigrationEntityDict>(schema: MigrationSchema<ED>): Map<string, {
8
+ key: string;
9
+ tableDef: MigrationTableDef;
10
+ }>;
11
+ export declare function applyInspectionAttributeHint(attr: Attribute, hint: Attribute | undefined, rules: InspectionTypeHintRule[]): Attribute;
12
+ export declare function applyOakManagedAttributeFallback(attr: Attribute, columnName: string, hint?: Attribute): Attribute;
13
+ export declare function isOakManagedTable(attributes: Record<string, Attribute>, hasTableHint: boolean): boolean;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildTargetTableHintMap = buildTargetTableHintMap;
4
+ exports.applyInspectionAttributeHint = applyInspectionAttributeHint;
5
+ exports.applyOakManagedAttributeFallback = applyOakManagedAttributeFallback;
6
+ exports.isOakManagedTable = isOakManagedTable;
7
+ const oakManagedColumns = ['id', '$$createAt$$', '$$updateAt$$', '$$deleteAt$$'];
8
+ const oakDatetimeColumns = new Set(['$$createAt$$', '$$updateAt$$', '$$deleteAt$$']);
9
+ function normalizeTypeName(type) {
10
+ return String(type).toLowerCase();
11
+ }
12
+ function buildTargetTableHintMap(schema) {
13
+ const tableHints = new Map();
14
+ Object.keys(schema).forEach((table) => {
15
+ const tableDef = schema[table];
16
+ tableHints.set(tableDef.storageName || table, {
17
+ key: table,
18
+ tableDef,
19
+ });
20
+ });
21
+ return tableHints;
22
+ }
23
+ function applyInspectionAttributeHint(attr, hint, rules) {
24
+ if (!hint) {
25
+ return attr;
26
+ }
27
+ const actualType = normalizeTypeName(attr.type);
28
+ const semanticType = normalizeTypeName(hint.type);
29
+ const matchedRule = rules.find((rule) => rule.actualTypes.includes(actualType)
30
+ && rule.semanticTypes.includes(semanticType));
31
+ if (!matchedRule) {
32
+ return attr;
33
+ }
34
+ return {
35
+ ...attr,
36
+ type: hint.type,
37
+ };
38
+ }
39
+ function applyOakManagedAttributeFallback(attr, columnName, hint) {
40
+ if (hint) {
41
+ return attr;
42
+ }
43
+ if (attr.type === 'bigint' && oakDatetimeColumns.has(columnName)) {
44
+ return {
45
+ ...attr,
46
+ type: 'datetime',
47
+ };
48
+ }
49
+ return attr;
50
+ }
51
+ function isOakManagedTable(attributes, hasTableHint) {
52
+ if (hasTableHint) {
53
+ return true;
54
+ }
55
+ return oakManagedColumns.every((column) => !!attributes[column]);
56
+ }
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "oak-db",
3
- "version": "3.3.13",
3
+ "version": "4.0.0",
4
4
  "description": "oak-db",
5
+ "oak": {
6
+ "package": true
7
+ },
5
8
  "main": "lib/index",
6
9
  "author": {
7
10
  "name": "XuChang"
@@ -18,7 +21,7 @@
18
21
  "lodash": "^4.17.21",
19
22
  "mysql": "^2.18.1",
20
23
  "mysql2": "^2.3.3",
21
- "oak-domain": "^5.1.34",
24
+ "oak-domain": "file:../oak-domain",
22
25
  "pg": "^8.16.3",
23
26
  "uuid": "^8.3.2"
24
27
  },