@sqb/connect 4.0.13 → 4.1.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.
Files changed (82) hide show
  1. package/dist/client/Adapter.d.ts +1 -1
  2. package/dist/client/Cursor.d.ts +2 -2
  3. package/dist/client/Cursor.js +3 -3
  4. package/dist/client/CursorStream.js +1 -1
  5. package/dist/client/SqbClient.d.ts +2 -2
  6. package/dist/client/SqbClient.js +5 -5
  7. package/dist/client/SqbConnection.d.ts +3 -3
  8. package/dist/client/SqbConnection.js +7 -7
  9. package/dist/client/helpers.d.ts +2 -2
  10. package/dist/client/types.d.ts +4 -4
  11. package/dist/index.d.ts +19 -15
  12. package/dist/index.js +20 -16
  13. package/dist/orm/base-entity.d.ts +8 -0
  14. package/dist/orm/base-entity.js +28 -0
  15. package/dist/orm/commands/command.helper.d.ts +4 -4
  16. package/dist/orm/commands/command.helper.js +5 -3
  17. package/dist/orm/commands/count.command.d.ts +3 -3
  18. package/dist/orm/commands/create.command.d.ts +4 -4
  19. package/dist/orm/commands/create.command.js +13 -7
  20. package/dist/orm/commands/destroy.command.d.ts +3 -3
  21. package/dist/orm/commands/find.command.d.ts +9 -9
  22. package/dist/orm/commands/find.command.js +13 -11
  23. package/dist/orm/commands/row-converter.d.ts +4 -4
  24. package/dist/orm/commands/update.command.d.ts +5 -5
  25. package/dist/orm/commands/update.command.js +7 -5
  26. package/dist/orm/decorators/column.decorator.d.ts +2 -2
  27. package/dist/orm/decorators/column.decorator.js +13 -4
  28. package/dist/orm/decorators/embedded.decorator.d.ts +3 -2
  29. package/dist/orm/decorators/embedded.decorator.js +6 -7
  30. package/dist/orm/decorators/entity.decorator.d.ts +31 -4
  31. package/dist/orm/decorators/entity.decorator.js +142 -5
  32. package/dist/orm/decorators/events.decorator.js +13 -25
  33. package/dist/orm/decorators/foreignkey.decorator.js +3 -3
  34. package/dist/orm/decorators/index.decorator.d.ts +3 -3
  35. package/dist/orm/decorators/index.decorator.js +5 -6
  36. package/dist/orm/decorators/link.decorator.d.ts +1 -1
  37. package/dist/orm/decorators/link.decorator.js +3 -3
  38. package/dist/orm/decorators/primarykey.decorator.d.ts +3 -3
  39. package/dist/orm/decorators/primarykey.decorator.js +7 -6
  40. package/dist/orm/decorators/transform.decorator.js +5 -5
  41. package/dist/orm/model/association-element-metadata.d.ts +10 -0
  42. package/dist/orm/model/association-element-metadata.js +15 -0
  43. package/dist/orm/model/association.d.ts +6 -6
  44. package/dist/orm/model/association.js +9 -8
  45. package/dist/orm/model/{entity-column-element.d.ts → column-element-metadata.d.ts} +21 -10
  46. package/dist/orm/model/column-element-metadata.js +32 -0
  47. package/dist/orm/model/element-metadata.d.ts +7 -0
  48. package/dist/orm/model/element-metadata.js +2 -0
  49. package/dist/orm/model/embedded-element-metadata.d.ts +14 -0
  50. package/dist/orm/model/embedded-element-metadata.js +28 -0
  51. package/dist/orm/model/entity-metadata.d.ts +49 -0
  52. package/dist/orm/model/entity-metadata.js +329 -0
  53. package/dist/orm/model/index-metadata.d.ts +18 -0
  54. package/dist/orm/model/index-metadata.js +2 -0
  55. package/dist/orm/orm.const.d.ts +1 -1
  56. package/dist/orm/orm.const.js +3 -3
  57. package/dist/orm/orm.type.d.ts +1 -92
  58. package/dist/orm/repository.class.d.ts +5 -4
  59. package/dist/orm/repository.class.js +27 -5
  60. package/dist/orm/util/apply-mixins.d.ts +1 -0
  61. package/dist/orm/util/apply-mixins.js +12 -0
  62. package/dist/orm/util/extract-keyvalues.d.ts +2 -2
  63. package/dist/orm/util/extract-keyvalues.js +3 -2
  64. package/dist/orm/util/orm.helper.d.ts +8 -9
  65. package/dist/orm/util/orm.helper.js +8 -9
  66. package/dist/orm/util/serialize-element.d.ts +2 -2
  67. package/package.json +10 -10
  68. package/dist/orm/base-entity.class.d.ts +0 -16
  69. package/dist/orm/base-entity.class.js +0 -56
  70. package/dist/orm/model/abstract-entityelement.d.ts +0 -8
  71. package/dist/orm/model/abstract-entityelement.js +0 -10
  72. package/dist/orm/model/entity-association-element.d.ts +0 -9
  73. package/dist/orm/model/entity-association-element.js +0 -13
  74. package/dist/orm/model/entity-column-element.js +0 -27
  75. package/dist/orm/model/entity-model.d.ts +0 -59
  76. package/dist/orm/model/entity-model.js +0 -295
  77. package/dist/orm/model/entity-object-element.d.ts +0 -12
  78. package/dist/orm/model/entity-object-element.js +0 -24
  79. package/dist/orm/model/index-meta.d.ts +0 -9
  80. package/dist/orm/model/index-meta.js +0 -16
  81. package/dist/orm/util/entity-mapping.d.ts +0 -12
  82. package/dist/orm/util/entity-mapping.js +0 -154
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Association = void 0;
4
4
  const putil_varhelpers_1 = require("putil-varhelpers");
5
5
  const orm_helper_1 = require("../util/orm.helper");
6
+ const entity_metadata_1 = require("./entity-metadata");
6
7
  class Association {
7
8
  constructor(name, args) {
8
9
  this.name = name;
@@ -59,7 +60,7 @@ class Association {
59
60
  let targetKey = this.targetKey;
60
61
  if (!(sourceKey && targetKey)) {
61
62
  // Try to determine key fields from foreign key from source to target
62
- let foreign = await source.getForeignKeyFor(target);
63
+ let foreign = await entity_metadata_1.EntityMetadata.getForeignKeyFor(source, target);
63
64
  if (foreign && foreign !== this) {
64
65
  await foreign._resolveKeys();
65
66
  this._sourceKey = foreign._sourceKey;
@@ -70,7 +71,7 @@ class Association {
70
71
  }
71
72
  else {
72
73
  // Try to determine key fields from foreign key from target to source
73
- foreign = await target.getForeignKeyFor(source);
74
+ foreign = await entity_metadata_1.EntityMetadata.getForeignKeyFor(target, source);
74
75
  if (foreign && foreign !== this) {
75
76
  await foreign._resolveKeys();
76
77
  this._sourceKey = foreign._targetKey;
@@ -97,14 +98,14 @@ class Association {
97
98
  masterKey = sourceKey || '';
98
99
  }
99
100
  if (!detailKey) {
100
- const primaryIndex = detail.primaryIndex;
101
- detailKey = primaryIndex && primaryIndex.columns.length === 1 ?
102
- primaryIndex.columns[0] : 'id';
101
+ const primaryIndexColumns = entity_metadata_1.EntityMetadata.getPrimaryIndexColumns(detail);
102
+ detailKey = primaryIndexColumns && primaryIndexColumns.length === 1 ?
103
+ primaryIndexColumns[0].name : 'id';
103
104
  }
104
105
  if (!masterKey) {
105
106
  // snake-case
106
107
  masterKey = detail.name[0].toLowerCase() + detail.name.substring(1) + '_' + detailKey;
107
- if (!master.getColumnElement(masterKey))
108
+ if (!entity_metadata_1.EntityMetadata.getColumnElement(master, masterKey))
108
109
  masterKey = (0, putil_varhelpers_1.camelCase)(masterKey);
109
110
  }
110
111
  if (this.sourceBelongsToTarget) {
@@ -116,10 +117,10 @@ class Association {
116
117
  sourceKey = masterKey;
117
118
  }
118
119
  }
119
- this._targetProperty = target.getColumnElement(targetKey);
120
+ this._targetProperty = entity_metadata_1.EntityMetadata.getColumnElement(target, targetKey);
120
121
  if (!this._targetProperty)
121
122
  throw new Error(`Can't determine target key of ${this.name}`);
122
- this._sourceProperty = source.getColumnElement(sourceKey);
123
+ this._sourceProperty = entity_metadata_1.EntityMetadata.getColumnElement(source, sourceKey);
123
124
  if (!this._sourceProperty)
124
125
  throw new Error(`Can't determine source key of ${this.name}`);
125
126
  this._targetKey = targetKey;
@@ -1,13 +1,22 @@
1
- import 'reflect-metadata';
2
1
  import { DataType } from '@sqb/builder';
3
- import type { EntityModel } from './entity-model';
4
- import { ElementKind, ColumnAutoGenerationStrategy, ColumnTransformFunction, DataPropertyOptions, EnumValue, FieldValue, DefaultValueGetter } from '../orm.type';
5
- import { AbstractEntityelement } from './abstract-entityelement';
6
- export declare class EntityColumnElement extends AbstractEntityelement {
7
- readonly kind: ElementKind;
2
+ import type { ColumnAutoGenerationStrategy, ColumnTransformFunction, DefaultValueGetter, EnumValue, FieldValue } from '../orm.type';
3
+ import { ElementMetadata } from './element-metadata';
4
+ import type { EntityMetadata } from './entity-metadata';
5
+ export declare type ColumnElementOptions = Partial<Omit<ColumnElementMetadata, 'entity' | 'name' | 'kind'>>;
6
+ export interface ColumnElementMetadata extends ElementMetadata {
7
+ readonly kind: 'column';
8
+ /**
9
+ Name of table field
10
+ */
8
11
  fieldName: string;
9
- dataType?: DataType;
12
+ /**
13
+ JS type. String, Boolean, Person etc
14
+ */
10
15
  type?: Function;
16
+ /**
17
+ * Column data type
18
+ */
19
+ dataType?: DataType;
11
20
  /**
12
21
  * Field comment
13
22
  */
@@ -62,7 +71,9 @@ export declare class EntityColumnElement extends AbstractEntityelement {
62
71
  noInsert?: boolean;
63
72
  parse?: ColumnTransformFunction;
64
73
  serialize?: ColumnTransformFunction;
65
- constructor(entity: EntityModel, name: string, options?: DataPropertyOptions);
66
- assign(options: DataPropertyOptions): void;
67
- checkEnumValue(v: FieldValue): void;
74
+ }
75
+ export declare namespace ColumnElementMetadata {
76
+ function create(entity: EntityMetadata, name: string, options?: ColumnElementOptions): ColumnElementMetadata;
77
+ function assign(target: ColumnElementMetadata, options: ColumnElementOptions): void;
78
+ function checkEnumValue(col: ColumnElementMetadata, v: FieldValue): void;
68
79
  }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ColumnElementMetadata = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
6
+ var ColumnElementMetadata;
7
+ (function (ColumnElementMetadata) {
8
+ function create(entity, name, options = {}) {
9
+ const result = {
10
+ kind: 'column',
11
+ entity,
12
+ name,
13
+ fieldName: name
14
+ };
15
+ if (options)
16
+ ColumnElementMetadata.assign(result, options);
17
+ return result;
18
+ }
19
+ ColumnElementMetadata.create = create;
20
+ function assign(target, options) {
21
+ Object.assign(target, lodash_1.default.omit(options, ['entity', 'name', 'kind']));
22
+ }
23
+ ColumnElementMetadata.assign = assign;
24
+ function checkEnumValue(col, v) {
25
+ if (v === undefined || !col.enum || (v == null && !col.notNull))
26
+ return;
27
+ const enumKeys = Array.isArray(col.enum) ? col.enum : Object.keys(col.enum);
28
+ if (!enumKeys.includes(v))
29
+ throw new Error(`${col.entity.name}.${col.name} value must be one of (${enumKeys})`);
30
+ }
31
+ ColumnElementMetadata.checkEnumValue = checkEnumValue;
32
+ })(ColumnElementMetadata = exports.ColumnElementMetadata || (exports.ColumnElementMetadata = {}));
@@ -0,0 +1,7 @@
1
+ import type { ElementKind } from '../orm.type';
2
+ import type { EntityMetadata } from './entity-metadata';
3
+ export interface ElementMetadata {
4
+ readonly entity: EntityMetadata;
5
+ readonly name: string;
6
+ readonly kind: ElementKind;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,14 @@
1
+ import { TypeThunk } from '../orm.type';
2
+ import { ElementMetadata } from './element-metadata';
3
+ import type { EntityMetadata } from './entity-metadata';
4
+ export declare type EmbeddedElementOptions = Partial<Omit<EmbeddedElementMetadata, 'entity' | 'name' | 'kind' | 'type'>>;
5
+ export interface EmbeddedElementMetadata extends ElementMetadata {
6
+ readonly kind: 'object';
7
+ type: TypeThunk;
8
+ fieldNamePrefix?: string;
9
+ fieldNameSuffix?: string;
10
+ }
11
+ export declare namespace EmbeddedElementMetadata {
12
+ function create(entity: EntityMetadata, name: string, type: TypeThunk, options?: EmbeddedElementOptions): EmbeddedElementMetadata;
13
+ function resolveType(meta: EmbeddedElementMetadata): Promise<EntityMetadata>;
14
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmbeddedElementMetadata = void 0;
4
+ const orm_helper_1 = require("../util/orm.helper");
5
+ var EmbeddedElementMetadata;
6
+ (function (EmbeddedElementMetadata) {
7
+ function create(entity, name, type, options) {
8
+ const result = {
9
+ kind: 'object',
10
+ entity,
11
+ name,
12
+ type
13
+ };
14
+ if (options?.fieldNamePrefix)
15
+ result.fieldNamePrefix = options.fieldNamePrefix;
16
+ if (options?.fieldNameSuffix)
17
+ result.fieldNameSuffix = options.fieldNameSuffix;
18
+ return result;
19
+ }
20
+ EmbeddedElementMetadata.create = create;
21
+ async function resolveType(meta) {
22
+ const typ = await (0, orm_helper_1.resolveEntityMeta)(meta.type);
23
+ if (typ)
24
+ return typ;
25
+ throw new Error(`Can't resolve type of ${meta.entity.name}.${meta.name}`);
26
+ }
27
+ EmbeddedElementMetadata.resolveType = resolveType;
28
+ })(EmbeddedElementMetadata = exports.EmbeddedElementMetadata || (exports.EmbeddedElementMetadata = {}));
@@ -0,0 +1,49 @@
1
+ import { Maybe, Type } from 'ts-gems';
2
+ import { Ctor, TypeThunk } from '../orm.type';
3
+ import { Association } from './association';
4
+ import { AssociationElementMetadata } from './association-element-metadata';
5
+ import { AssociationNode } from './association-node';
6
+ import { ColumnElementMetadata, ColumnElementOptions } from './column-element-metadata';
7
+ import { EmbeddedElementMetadata, EmbeddedElementOptions } from './embedded-element-metadata';
8
+ import { IndexMetadata } from './index-metadata';
9
+ export declare type AnyElementMetadata = ColumnElementMetadata | EmbeddedElementMetadata | AssociationElementMetadata;
10
+ export declare type EntityOptions = Partial<Pick<EntityMetadata, 'name' | 'schema' | 'comment' | 'tableName'>>;
11
+ export interface EntityMetadata {
12
+ readonly ctor: Type;
13
+ readonly name: string;
14
+ tableName?: string;
15
+ schema?: string;
16
+ comment?: string;
17
+ elements: Record<string, AnyElementMetadata>;
18
+ indexes: IndexMetadata[];
19
+ foreignKeys: Association[];
20
+ eventListeners: Record<string, Function[]>;
21
+ }
22
+ export declare namespace EntityMetadata {
23
+ function inject(ctor: Ctor): EntityMetadata;
24
+ function get(ctor: Ctor): Maybe<EntityMetadata>;
25
+ function getOwn(ctor: Ctor): Maybe<EntityMetadata>;
26
+ function getElement(entity: EntityMetadata, elementName: string): Maybe<AnyElementMetadata>;
27
+ function getColumnElement(entity: EntityMetadata, elementName: string): Maybe<ColumnElementMetadata>;
28
+ function getEmbeddedElement(entity: EntityMetadata, elementName: string): Maybe<EmbeddedElementMetadata>;
29
+ function getAssociationElement(entity: EntityMetadata, elementName: string): Maybe<AssociationElementMetadata>;
30
+ function getColumnElementByFieldName(entity: EntityMetadata, fieldName: string): Maybe<ColumnElementMetadata>;
31
+ function getElementNames(entity: EntityMetadata, filter?: (el: AnyElementMetadata) => boolean): string[];
32
+ function getColumnNames(entity: EntityMetadata): string[];
33
+ function getEmbeddedElementNames(entity: EntityMetadata): string[];
34
+ function getAssociationElementNames(entity: EntityMetadata): string[];
35
+ function getNonAssociationElementNames(entity: EntityMetadata): string[];
36
+ function getInsertColumnNames(entity: EntityMetadata): string[];
37
+ function getUpdateColumnNames(entity: EntityMetadata): string[];
38
+ function getPrimaryIndex(entity: EntityMetadata): Maybe<IndexMetadata>;
39
+ function getPrimaryIndexColumns(entity: EntityMetadata): ColumnElementMetadata[];
40
+ function getForeignKeyFor(src: EntityMetadata, trg: EntityMetadata): Promise<Maybe<Association>>;
41
+ function addIndex(entity: EntityMetadata, index: IndexMetadata): void;
42
+ function addForeignKey(entity: EntityMetadata, propertyKey: string, target: TypeThunk, targetKey?: string): void;
43
+ function addEventListener(entity: EntityMetadata, event: string, fn: Function): void;
44
+ function defineColumnElement(entity: EntityMetadata, name: string, options?: ColumnElementOptions): ColumnElementMetadata;
45
+ function defineEmbeddedElement(entity: EntityMetadata, name: string, type: TypeThunk, options?: EmbeddedElementOptions): EmbeddedElementMetadata;
46
+ function defineAssociationElement(entity: EntityMetadata, propertyKey: string, association: AssociationNode): AssociationElementMetadata;
47
+ function setPrimaryKeys(entity: EntityMetadata, column: string | string[], options?: Omit<IndexMetadata, 'columns' | 'unique' | 'primary'>): void;
48
+ function mixin(derived: EntityMetadata, base: EntityMetadata, elements?: string[]): void;
49
+ }
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntityMetadata = void 0;
4
+ const builder_1 = require("@sqb/builder");
5
+ const orm_const_1 = require("../orm.const");
6
+ const orm_helper_1 = require("../util/orm.helper");
7
+ const serialize_element_1 = require("../util/serialize-element");
8
+ const association_1 = require("./association");
9
+ const association_element_metadata_1 = require("./association-element-metadata");
10
+ const column_element_metadata_1 = require("./column-element-metadata");
11
+ const embedded_element_metadata_1 = require("./embedded-element-metadata");
12
+ var EntityMetadata;
13
+ (function (EntityMetadata) {
14
+ function inject(ctor) {
15
+ const own = getOwn(ctor);
16
+ if (own)
17
+ return own;
18
+ const baseMeta = get(ctor);
19
+ const meta = {
20
+ ctor: ctor,
21
+ name: ctor.name,
22
+ elements: {},
23
+ indexes: [],
24
+ foreignKeys: [],
25
+ eventListeners: {}
26
+ };
27
+ Reflect.defineMetadata(orm_const_1.ENTITY_METADATA_KEY, meta, ctor);
28
+ // Merge base entity columns into this one
29
+ if (baseMeta) {
30
+ EntityMetadata.mixin(meta, baseMeta);
31
+ }
32
+ ctor.prototype.toJSON = function () {
33
+ const obj = {};
34
+ const elementKeys = Object.keys(meta.elements);
35
+ const l = elementKeys.length;
36
+ let key;
37
+ let v;
38
+ for (let i = 0; i < l; i++) {
39
+ key = elementKeys[i];
40
+ const col = EntityMetadata.getElement(meta, key);
41
+ if (col) {
42
+ v = this[col.name];
43
+ if (v !== undefined)
44
+ obj[col.name] = (0, serialize_element_1.serializeColumn)(col, v);
45
+ }
46
+ }
47
+ return obj;
48
+ };
49
+ return meta;
50
+ }
51
+ EntityMetadata.inject = inject;
52
+ function get(ctor) {
53
+ return Reflect.getMetadata(orm_const_1.ENTITY_METADATA_KEY, ctor);
54
+ }
55
+ EntityMetadata.get = get;
56
+ function getOwn(ctor) {
57
+ return Reflect.getOwnMetadata(orm_const_1.ENTITY_METADATA_KEY, ctor);
58
+ }
59
+ EntityMetadata.getOwn = getOwn;
60
+ function getElement(entity, elementName) {
61
+ return elementName ? entity.elements[elementName.toLowerCase()] : undefined;
62
+ }
63
+ EntityMetadata.getElement = getElement;
64
+ function getColumnElement(entity, elementName) {
65
+ const el = getElement(entity, elementName);
66
+ return (0, orm_helper_1.isColumnElement)(el) ? el : undefined;
67
+ }
68
+ EntityMetadata.getColumnElement = getColumnElement;
69
+ function getEmbeddedElement(entity, elementName) {
70
+ const el = getElement(entity, elementName);
71
+ return (0, orm_helper_1.isEmbeddedElement)(el) ? el : undefined;
72
+ }
73
+ EntityMetadata.getEmbeddedElement = getEmbeddedElement;
74
+ function getAssociationElement(entity, elementName) {
75
+ const el = getElement(entity, elementName);
76
+ return (0, orm_helper_1.isAssociationElement)(el) ? el : undefined;
77
+ }
78
+ EntityMetadata.getAssociationElement = getAssociationElement;
79
+ function getColumnElementByFieldName(entity, fieldName) {
80
+ if (!fieldName)
81
+ return;
82
+ fieldName = fieldName.toLowerCase();
83
+ for (const prop of Object.values(entity.elements)) {
84
+ if ((0, orm_helper_1.isColumnElement)(prop) && prop.fieldName.toLowerCase() === fieldName)
85
+ return prop;
86
+ }
87
+ }
88
+ EntityMetadata.getColumnElementByFieldName = getColumnElementByFieldName;
89
+ function getElementNames(entity, filter) {
90
+ if (filter) {
91
+ const out = [];
92
+ for (const el of Object.values(entity.elements)) {
93
+ if (el && (!filter || filter(el)))
94
+ out.push(el.name);
95
+ }
96
+ return out;
97
+ }
98
+ // Create a cached name array
99
+ if (!Object.prototype.hasOwnProperty.call(entity, '_elementNames'))
100
+ Object.defineProperty(entity, '_elementNames', {
101
+ enumerable: false,
102
+ configurable: true,
103
+ writable: true,
104
+ value: Object.values(entity.elements).map(m => m.name)
105
+ });
106
+ return entity._elementNames;
107
+ }
108
+ EntityMetadata.getElementNames = getElementNames;
109
+ function getColumnNames(entity) {
110
+ return getElementNames(entity, orm_helper_1.isColumnElement);
111
+ }
112
+ EntityMetadata.getColumnNames = getColumnNames;
113
+ function getEmbeddedElementNames(entity) {
114
+ return getElementNames(entity, orm_helper_1.isEmbeddedElement);
115
+ }
116
+ EntityMetadata.getEmbeddedElementNames = getEmbeddedElementNames;
117
+ function getAssociationElementNames(entity) {
118
+ return getElementNames(entity, orm_helper_1.isAssociationElement);
119
+ }
120
+ EntityMetadata.getAssociationElementNames = getAssociationElementNames;
121
+ function getNonAssociationElementNames(entity) {
122
+ return getElementNames(entity, x => !(0, orm_helper_1.isAssociationElement)(x));
123
+ }
124
+ EntityMetadata.getNonAssociationElementNames = getNonAssociationElementNames;
125
+ function getInsertColumnNames(entity) {
126
+ return getElementNames(entity, x => (0, orm_helper_1.isColumnElement)(x) && !x.noInsert);
127
+ }
128
+ EntityMetadata.getInsertColumnNames = getInsertColumnNames;
129
+ function getUpdateColumnNames(entity) {
130
+ return getElementNames(entity, x => (0, orm_helper_1.isColumnElement)(x) && !x.noUpdate);
131
+ }
132
+ EntityMetadata.getUpdateColumnNames = getUpdateColumnNames;
133
+ function getPrimaryIndex(entity) {
134
+ return entity.indexes.find(idx => idx.primary);
135
+ }
136
+ EntityMetadata.getPrimaryIndex = getPrimaryIndex;
137
+ function getPrimaryIndexColumns(entity) {
138
+ const idx = getPrimaryIndex(entity);
139
+ const out = [];
140
+ if (idx) {
141
+ for (const k of idx.columns) {
142
+ const col = getColumnElement(entity, k);
143
+ if (!col)
144
+ throw new Error(`Data column "${k}" in primary index of ${entity.name} does not exists`);
145
+ out.push(col);
146
+ }
147
+ }
148
+ return out;
149
+ }
150
+ EntityMetadata.getPrimaryIndexColumns = getPrimaryIndexColumns;
151
+ async function getForeignKeyFor(src, trg) {
152
+ for (const f of src.foreignKeys) {
153
+ if (await f.resolveTarget() === trg)
154
+ return f;
155
+ }
156
+ }
157
+ EntityMetadata.getForeignKeyFor = getForeignKeyFor;
158
+ function addIndex(entity, index) {
159
+ entity.indexes = entity.indexes || [];
160
+ index = {
161
+ ...index,
162
+ columns: Array.isArray(index.columns) ? index.columns : [index.columns]
163
+ };
164
+ if (index.primary)
165
+ entity.indexes.forEach(idx => delete idx.primary);
166
+ entity.indexes.push(index);
167
+ }
168
+ EntityMetadata.addIndex = addIndex;
169
+ function addForeignKey(entity, propertyKey, target, targetKey) {
170
+ entity.foreignKeys = entity.foreignKeys || [];
171
+ const fk = new association_1.Association(entity.name + '.' + propertyKey, {
172
+ source: entity.ctor,
173
+ sourceKey: propertyKey,
174
+ target,
175
+ targetKey
176
+ });
177
+ entity.foreignKeys.push(fk);
178
+ }
179
+ EntityMetadata.addForeignKey = addForeignKey;
180
+ function addEventListener(entity, event, fn) {
181
+ if (typeof fn !== 'function')
182
+ throw new Error('Property must be a function');
183
+ entity.eventListeners = entity.eventListeners || {};
184
+ entity.eventListeners[event] = entity.eventListeners[event] || [];
185
+ entity.eventListeners[event].push(fn);
186
+ }
187
+ EntityMetadata.addEventListener = addEventListener;
188
+ function defineColumnElement(entity, name, options = {}) {
189
+ delete entity._elementNames;
190
+ let prop = EntityMetadata.getElement(entity, name);
191
+ if ((0, orm_helper_1.isColumnElement)(prop))
192
+ options = { ...prop, ...options };
193
+ if (!options.type) {
194
+ switch (options.dataType) {
195
+ case builder_1.DataType.BOOL:
196
+ options.type = Boolean;
197
+ break;
198
+ case builder_1.DataType.VARCHAR:
199
+ case builder_1.DataType.CHAR:
200
+ case builder_1.DataType.TEXT:
201
+ options.type = String;
202
+ break;
203
+ case builder_1.DataType.NUMBER:
204
+ case builder_1.DataType.DOUBLE:
205
+ case builder_1.DataType.FLOAT:
206
+ case builder_1.DataType.INTEGER:
207
+ case builder_1.DataType.SMALLINT:
208
+ options.type = Number;
209
+ break;
210
+ case builder_1.DataType.TIMESTAMP:
211
+ case builder_1.DataType.TIMESTAMPTZ:
212
+ options.type = Date;
213
+ break;
214
+ case builder_1.DataType.BINARY:
215
+ options.type = Buffer;
216
+ break;
217
+ default:
218
+ options.type = String;
219
+ }
220
+ }
221
+ if (!options.dataType) {
222
+ switch (options.type) {
223
+ case Boolean:
224
+ options.dataType = builder_1.DataType.BOOL;
225
+ break;
226
+ case Number:
227
+ options.dataType = builder_1.DataType.NUMBER;
228
+ break;
229
+ case Date:
230
+ options.dataType = builder_1.DataType.TIMESTAMP;
231
+ break;
232
+ case Array:
233
+ options.dataType = builder_1.DataType.VARCHAR;
234
+ options.isArray = true;
235
+ break;
236
+ case Buffer:
237
+ options.dataType = builder_1.DataType.BINARY;
238
+ break;
239
+ default:
240
+ options.dataType = builder_1.DataType.VARCHAR;
241
+ }
242
+ }
243
+ prop = column_element_metadata_1.ColumnElementMetadata.create(entity, name, options);
244
+ entity.elements[name.toLowerCase()] = prop;
245
+ return prop;
246
+ }
247
+ EntityMetadata.defineColumnElement = defineColumnElement;
248
+ function defineEmbeddedElement(entity, name, type, options) {
249
+ delete entity._elementNames;
250
+ let prop = EntityMetadata.getElement(entity, name);
251
+ if ((0, orm_helper_1.isEmbeddedElement)(prop))
252
+ options = { ...prop, ...options };
253
+ prop = embedded_element_metadata_1.EmbeddedElementMetadata.create(entity, name, type, options);
254
+ entity.elements[name.toLowerCase()] = prop;
255
+ return prop;
256
+ }
257
+ EntityMetadata.defineEmbeddedElement = defineEmbeddedElement;
258
+ function defineAssociationElement(entity, propertyKey, association) {
259
+ delete entity._elementNames;
260
+ const prop = association_element_metadata_1.AssociationElementMetadata.create(entity, propertyKey, association);
261
+ let l = association;
262
+ let i = 1;
263
+ while (l) {
264
+ l.name = entity.name + '.' + propertyKey + '#' + (i++);
265
+ l = l.next;
266
+ }
267
+ entity.elements[propertyKey.toLowerCase()] = prop;
268
+ return prop;
269
+ }
270
+ EntityMetadata.defineAssociationElement = defineAssociationElement;
271
+ function setPrimaryKeys(entity, column, options) {
272
+ addIndex(entity, {
273
+ ...options,
274
+ columns: Array.isArray(column) ? column : [column],
275
+ unique: true,
276
+ primary: true
277
+ });
278
+ }
279
+ EntityMetadata.setPrimaryKeys = setPrimaryKeys;
280
+ function mixin(derived, base, elements) {
281
+ const elementKeys = elements && elements.map(x => x.toLowerCase());
282
+ const hasElement = (k) => !(elementKeys && !elementKeys.includes(k.toLowerCase()));
283
+ // applyMixins(derived, baseCtor, hasElement);
284
+ delete derived._elementNames;
285
+ if (!derived.tableName) {
286
+ derived.tableName = base.tableName;
287
+ derived.schema = base.schema;
288
+ derived.comment = base.comment;
289
+ }
290
+ // Copy indexes
291
+ if (base.indexes && base.indexes.length) {
292
+ const hasPrimaryIndex = !!getPrimaryIndex(derived);
293
+ for (const idx of base.indexes) {
294
+ if (!idx.columns.find(x => !hasElement(x))) {
295
+ if (hasPrimaryIndex)
296
+ addIndex(derived, { ...idx, primary: undefined });
297
+ else
298
+ addIndex(derived, idx);
299
+ }
300
+ }
301
+ }
302
+ // Copy foreign indexes
303
+ if (base.foreignKeys && base.foreignKeys.length) {
304
+ derived.foreignKeys = derived.foreignKeys || [];
305
+ for (const fk of base.foreignKeys) {
306
+ if (!fk.sourceKey || hasElement(fk.sourceKey)) {
307
+ const newFk = new association_1.Association(fk.name, { ...fk, source: derived.ctor });
308
+ derived.foreignKeys.push(newFk);
309
+ }
310
+ }
311
+ }
312
+ // Copy event listeners
313
+ if (base.eventListeners) {
314
+ for (const [event, arr] of Object.entries(base.eventListeners)) {
315
+ arr.forEach(fn => EntityMetadata.addEventListener(derived, event, fn));
316
+ }
317
+ }
318
+ // Copy elements
319
+ for (const [n, p] of Object.entries(base.elements)) {
320
+ if (!hasElement(n))
321
+ continue;
322
+ const o = Object.assign({}, p);
323
+ o.entity = derived;
324
+ Object.setPrototypeOf(o, Object.getPrototypeOf(p));
325
+ derived.elements[n] = o;
326
+ }
327
+ }
328
+ EntityMetadata.mixin = mixin;
329
+ })(EntityMetadata = exports.EntityMetadata || (exports.EntityMetadata = {}));
@@ -0,0 +1,18 @@
1
+ export interface IndexMetadata {
2
+ /**
3
+ * Columns of the index
4
+ */
5
+ columns: string[];
6
+ /**
7
+ * Name of the index
8
+ */
9
+ name?: string;
10
+ /**
11
+ * Specifies if index is unique
12
+ */
13
+ unique?: boolean;
14
+ /**
15
+ * Specifies if index is primary
16
+ */
17
+ primary?: boolean;
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,2 +1,2 @@
1
- export declare const ENTITY_DEFINITION_KEY: unique symbol;
1
+ export declare const ENTITY_METADATA_KEY: unique symbol;
2
2
  export declare const REPOSITORY_KEY: unique symbol;
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.REPOSITORY_KEY = exports.ENTITY_DEFINITION_KEY = void 0;
4
- exports.ENTITY_DEFINITION_KEY = Symbol.for('sqb.entity-definition');
5
- exports.REPOSITORY_KEY = Symbol.for('sqb.entity.repository');
3
+ exports.REPOSITORY_KEY = exports.ENTITY_METADATA_KEY = void 0;
4
+ exports.ENTITY_METADATA_KEY = Symbol.for('SQB_ENTITY_METADATA');
5
+ exports.REPOSITORY_KEY = Symbol.for('SQB_REPOSITORY');