@sqb/connect 4.0.9 → 4.0.13
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/dist/client/Adapter.d.ts +57 -0
- package/dist/client/Adapter.js +2 -0
- package/dist/client/Cursor.d.ts +116 -0
- package/dist/client/Cursor.js +250 -0
- package/dist/client/CursorStream.d.ts +29 -0
- package/dist/client/CursorStream.js +98 -0
- package/dist/client/FieldInfoMap.d.ts +10 -0
- package/dist/client/FieldInfoMap.js +33 -0
- package/dist/client/SqbClient.d.ts +70 -0
- package/dist/client/SqbClient.js +165 -0
- package/dist/client/SqbConnection.d.ts +74 -0
- package/dist/client/SqbConnection.js +272 -0
- package/dist/client/extensions.d.ts +4 -0
- package/dist/client/extensions.js +14 -0
- package/dist/client/helpers.d.ts +9 -0
- package/dist/client/helpers.js +133 -0
- package/dist/client/types.d.ts +189 -0
- package/dist/client/types.js +5 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +37 -0
- package/dist/orm/base-entity.class.d.ts +16 -0
- package/dist/orm/base-entity.class.js +56 -0
- package/dist/orm/commands/command.helper.d.ts +14 -0
- package/dist/orm/commands/command.helper.js +140 -0
- package/dist/orm/commands/count.command.d.ts +11 -0
- package/dist/orm/commands/count.command.js +30 -0
- package/dist/orm/commands/create.command.d.ts +20 -0
- package/dist/orm/commands/create.command.js +83 -0
- package/dist/orm/commands/destroy.command.d.ts +11 -0
- package/dist/orm/commands/destroy.command.js +30 -0
- package/dist/orm/commands/find.command.d.ts +44 -0
- package/dist/orm/commands/find.command.js +308 -0
- package/dist/orm/commands/row-converter.d.ts +55 -0
- package/dist/orm/commands/row-converter.js +187 -0
- package/dist/orm/commands/update.command.d.ts +22 -0
- package/dist/orm/commands/update.command.js +82 -0
- package/dist/orm/decorators/column.decorator.d.ts +4 -0
- package/dist/orm/decorators/column.decorator.js +14 -0
- package/dist/orm/decorators/embedded.decorator.d.ts +2 -0
- package/dist/orm/decorators/embedded.decorator.js +17 -0
- package/dist/orm/decorators/entity.decorator.d.ts +6 -0
- package/dist/orm/decorators/entity.decorator.js +23 -0
- package/dist/orm/decorators/events.decorator.d.ts +6 -0
- package/dist/orm/decorators/events.decorator.js +76 -0
- package/dist/orm/decorators/foreignkey.decorator.d.ts +2 -0
- package/dist/orm/decorators/foreignkey.decorator.js +13 -0
- package/dist/orm/decorators/index.decorator.d.ts +3 -0
- package/dist/orm/decorators/index.decorator.js +22 -0
- package/dist/orm/decorators/link.decorator.d.ts +23 -0
- package/dist/orm/decorators/link.decorator.js +88 -0
- package/dist/orm/decorators/primarykey.decorator.d.ts +3 -0
- package/dist/orm/decorators/primarykey.decorator.js +23 -0
- package/dist/orm/decorators/transform.decorator.d.ts +3 -0
- package/dist/orm/decorators/transform.decorator.js +24 -0
- package/dist/orm/model/abstract-entityelement.d.ts +8 -0
- package/dist/orm/model/abstract-entityelement.js +10 -0
- package/dist/orm/model/association-node.d.ts +9 -0
- package/dist/orm/model/association-node.js +25 -0
- package/dist/orm/model/association.d.ts +28 -0
- package/dist/orm/model/association.js +129 -0
- package/dist/orm/model/entity-association-element.d.ts +9 -0
- package/dist/orm/model/entity-association-element.js +13 -0
- package/dist/orm/model/entity-column-element.d.ts +68 -0
- package/dist/orm/model/entity-column-element.js +27 -0
- package/dist/orm/model/entity-model.d.ts +59 -0
- package/dist/orm/model/entity-model.js +295 -0
- package/dist/orm/model/entity-object-element.d.ts +12 -0
- package/dist/orm/model/entity-object-element.js +24 -0
- package/dist/orm/model/index-meta.d.ts +9 -0
- package/dist/orm/model/index-meta.js +16 -0
- package/dist/orm/model/link-chain.d.ts +15 -0
- package/dist/orm/model/link-chain.js +50 -0
- package/dist/orm/orm.const.d.ts +2 -0
- package/dist/orm/orm.const.js +5 -0
- package/dist/orm/orm.type.d.ts +112 -0
- package/dist/orm/orm.type.js +2 -0
- package/dist/orm/repository.class.d.ts +125 -0
- package/dist/orm/repository.class.js +217 -0
- package/dist/orm/util/entity-mapping.d.ts +12 -0
- package/dist/orm/util/entity-mapping.js +154 -0
- package/dist/orm/util/extract-keyvalues.d.ts +2 -0
- package/dist/orm/util/extract-keyvalues.js +60 -0
- package/dist/orm/util/orm.helper.d.ts +14 -0
- package/dist/orm/util/orm.helper.js +39 -0
- package/dist/orm/util/serialize-element.d.ts +2 -0
- package/dist/orm/util/serialize-element.js +43 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/package.json +3 -3
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Association = void 0;
|
|
4
|
+
const putil_varhelpers_1 = require("putil-varhelpers");
|
|
5
|
+
const orm_helper_1 = require("../util/orm.helper");
|
|
6
|
+
class Association {
|
|
7
|
+
constructor(name, args) {
|
|
8
|
+
this.name = name;
|
|
9
|
+
this.source = args.source;
|
|
10
|
+
this.target = args.target;
|
|
11
|
+
this.sourceKey = args.sourceKey;
|
|
12
|
+
this.targetKey = args.targetKey;
|
|
13
|
+
this.kind = args.kind;
|
|
14
|
+
}
|
|
15
|
+
async resolveSource() {
|
|
16
|
+
this._source = await (0, orm_helper_1.resolveEntityMeta)(this.source);
|
|
17
|
+
if (!this._source)
|
|
18
|
+
throw new Error(`Can't resolve source entity of association "${this.name}"`);
|
|
19
|
+
return this._source;
|
|
20
|
+
}
|
|
21
|
+
async resolveTarget() {
|
|
22
|
+
this._target = await (0, orm_helper_1.resolveEntityMeta)(this.target);
|
|
23
|
+
if (!this._target)
|
|
24
|
+
throw new Error(`Can't resolve target entity of association "${this.name}"`);
|
|
25
|
+
return this._target;
|
|
26
|
+
}
|
|
27
|
+
async resolveSourceKey() {
|
|
28
|
+
await this._resolveKeys();
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
return this._sourceKey;
|
|
31
|
+
}
|
|
32
|
+
async resolveSourceProperty() {
|
|
33
|
+
await this._resolveKeys();
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
return this._sourceProperty;
|
|
36
|
+
}
|
|
37
|
+
async resolveTargetKey() {
|
|
38
|
+
await this._resolveKeys();
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
return this._targetKey;
|
|
41
|
+
}
|
|
42
|
+
async resolveTargetProperty() {
|
|
43
|
+
await this._resolveKeys();
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
return this._targetProperty;
|
|
46
|
+
}
|
|
47
|
+
get sourceBelongsToTarget() {
|
|
48
|
+
return this.kind === 'from' || this.kind === 'from-many';
|
|
49
|
+
}
|
|
50
|
+
returnsMany() {
|
|
51
|
+
return this.kind === 'to-many' || this.kind === 'from-many';
|
|
52
|
+
}
|
|
53
|
+
async _resolveKeys() {
|
|
54
|
+
if (this._resolved)
|
|
55
|
+
return;
|
|
56
|
+
const source = await this.resolveSource();
|
|
57
|
+
const target = await this.resolveTarget();
|
|
58
|
+
let sourceKey = this.sourceKey;
|
|
59
|
+
let targetKey = this.targetKey;
|
|
60
|
+
if (!(sourceKey && targetKey)) {
|
|
61
|
+
// Try to determine key fields from foreign key from source to target
|
|
62
|
+
let foreign = await source.getForeignKeyFor(target);
|
|
63
|
+
if (foreign && foreign !== this) {
|
|
64
|
+
await foreign._resolveKeys();
|
|
65
|
+
this._sourceKey = foreign._sourceKey;
|
|
66
|
+
this._sourceProperty = foreign._sourceProperty;
|
|
67
|
+
this._targetKey = foreign._targetKey;
|
|
68
|
+
this._targetProperty = foreign._targetProperty;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Try to determine key fields from foreign key from target to source
|
|
73
|
+
foreign = await target.getForeignKeyFor(source);
|
|
74
|
+
if (foreign && foreign !== this) {
|
|
75
|
+
await foreign._resolveKeys();
|
|
76
|
+
this._sourceKey = foreign._targetKey;
|
|
77
|
+
this._sourceProperty = foreign._targetProperty;
|
|
78
|
+
this._targetKey = foreign._sourceKey;
|
|
79
|
+
this._targetProperty = foreign._sourceProperty;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let master;
|
|
84
|
+
let detail;
|
|
85
|
+
let masterKey;
|
|
86
|
+
let detailKey;
|
|
87
|
+
if (this.sourceBelongsToTarget) {
|
|
88
|
+
master = target;
|
|
89
|
+
detail = source;
|
|
90
|
+
masterKey = targetKey || '';
|
|
91
|
+
detailKey = sourceKey || '';
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
master = source;
|
|
95
|
+
detail = target;
|
|
96
|
+
detailKey = targetKey || '';
|
|
97
|
+
masterKey = sourceKey || '';
|
|
98
|
+
}
|
|
99
|
+
if (!detailKey) {
|
|
100
|
+
const primaryIndex = detail.primaryIndex;
|
|
101
|
+
detailKey = primaryIndex && primaryIndex.columns.length === 1 ?
|
|
102
|
+
primaryIndex.columns[0] : 'id';
|
|
103
|
+
}
|
|
104
|
+
if (!masterKey) {
|
|
105
|
+
// snake-case
|
|
106
|
+
masterKey = detail.name[0].toLowerCase() + detail.name.substring(1) + '_' + detailKey;
|
|
107
|
+
if (!master.getColumnElement(masterKey))
|
|
108
|
+
masterKey = (0, putil_varhelpers_1.camelCase)(masterKey);
|
|
109
|
+
}
|
|
110
|
+
if (this.sourceBelongsToTarget) {
|
|
111
|
+
targetKey = masterKey;
|
|
112
|
+
sourceKey = detailKey;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
targetKey = detailKey;
|
|
116
|
+
sourceKey = masterKey;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
this._targetProperty = target.getColumnElement(targetKey);
|
|
120
|
+
if (!this._targetProperty)
|
|
121
|
+
throw new Error(`Can't determine target key of ${this.name}`);
|
|
122
|
+
this._sourceProperty = source.getColumnElement(sourceKey);
|
|
123
|
+
if (!this._sourceProperty)
|
|
124
|
+
throw new Error(`Can't determine source key of ${this.name}`);
|
|
125
|
+
this._targetKey = targetKey;
|
|
126
|
+
this._sourceKey = sourceKey;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.Association = Association;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EntityModel } from './entity-model';
|
|
2
|
+
import { ElementKind } from '../orm.type';
|
|
3
|
+
import { AbstractEntityelement } from './abstract-entityelement';
|
|
4
|
+
import type { AssociationNode } from './association-node';
|
|
5
|
+
export declare class EntityAssociationElement extends AbstractEntityelement {
|
|
6
|
+
readonly association: AssociationNode;
|
|
7
|
+
readonly kind: ElementKind;
|
|
8
|
+
constructor(entity: EntityModel, name: string, association: AssociationNode);
|
|
9
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityAssociationElement = void 0;
|
|
4
|
+
const abstract_entityelement_1 = require("./abstract-entityelement");
|
|
5
|
+
class EntityAssociationElement extends abstract_entityelement_1.AbstractEntityelement {
|
|
6
|
+
constructor(entity, name, association) {
|
|
7
|
+
super(entity, name);
|
|
8
|
+
this.association = association;
|
|
9
|
+
this.kind = 'association';
|
|
10
|
+
this.association.name = this.entity.name + '.' + name;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.EntityAssociationElement = EntityAssociationElement;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
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;
|
|
8
|
+
fieldName: string;
|
|
9
|
+
dataType?: DataType;
|
|
10
|
+
type?: Function;
|
|
11
|
+
/**
|
|
12
|
+
* Field comment
|
|
13
|
+
*/
|
|
14
|
+
comment?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Column's default value
|
|
17
|
+
*/
|
|
18
|
+
default?: FieldValue | DefaultValueGetter;
|
|
19
|
+
/**
|
|
20
|
+
* Indicates if column data is an array
|
|
21
|
+
*/
|
|
22
|
+
isArray?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Indicates enum values
|
|
25
|
+
*/
|
|
26
|
+
enum?: EnumValue;
|
|
27
|
+
/**
|
|
28
|
+
* Character or byte length of column
|
|
29
|
+
*/
|
|
30
|
+
length?: number;
|
|
31
|
+
/**
|
|
32
|
+
* The precision for a decimal field
|
|
33
|
+
*/
|
|
34
|
+
precision?: number;
|
|
35
|
+
/**
|
|
36
|
+
* The scale for a decimal field
|
|
37
|
+
*/
|
|
38
|
+
scale?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Fields's collation.
|
|
41
|
+
*/
|
|
42
|
+
collation?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Indicates auto generation strategy
|
|
45
|
+
*/
|
|
46
|
+
autoGenerated?: ColumnAutoGenerationStrategy;
|
|
47
|
+
/**
|
|
48
|
+
* Indicates if column value can be null
|
|
49
|
+
*/
|
|
50
|
+
notNull?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Indicates whether or not to hide this column by default when making queries.
|
|
53
|
+
*/
|
|
54
|
+
hidden?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Indicates if column value is used in update queries
|
|
57
|
+
*/
|
|
58
|
+
noUpdate?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Indicates if column value is used in insert queries
|
|
61
|
+
*/
|
|
62
|
+
noInsert?: boolean;
|
|
63
|
+
parse?: ColumnTransformFunction;
|
|
64
|
+
serialize?: ColumnTransformFunction;
|
|
65
|
+
constructor(entity: EntityModel, name: string, options?: DataPropertyOptions);
|
|
66
|
+
assign(options: DataPropertyOptions): void;
|
|
67
|
+
checkEnumValue(v: FieldValue): void;
|
|
68
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityColumnElement = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
require("reflect-metadata");
|
|
6
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
|
+
const abstract_entityelement_1 = require("./abstract-entityelement");
|
|
8
|
+
class EntityColumnElement extends abstract_entityelement_1.AbstractEntityelement {
|
|
9
|
+
constructor(entity, name, options = {}) {
|
|
10
|
+
super(entity, name);
|
|
11
|
+
this.kind = 'column';
|
|
12
|
+
this.fieldName = name;
|
|
13
|
+
if (options)
|
|
14
|
+
this.assign(options);
|
|
15
|
+
}
|
|
16
|
+
assign(options) {
|
|
17
|
+
Object.assign(this, lodash_1.default.omit(options, ['entity', 'name', 'kind']));
|
|
18
|
+
}
|
|
19
|
+
checkEnumValue(v) {
|
|
20
|
+
if (v === undefined || !this.enum || (v == null && !this.notNull))
|
|
21
|
+
return;
|
|
22
|
+
const enumKeys = Array.isArray(this.enum) ? this.enum : Object.keys(this.enum);
|
|
23
|
+
if (!enumKeys.includes(v))
|
|
24
|
+
throw new Error(`${this.entity.name}.${this.name} value must be one of (${enumKeys})`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.EntityColumnElement = EntityColumnElement;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Type, Maybe } from 'ts-gems';
|
|
2
|
+
import { IndexOptions, TypeThunk, DataPropertyOptions } from '../orm.type';
|
|
3
|
+
import { IndexMeta } from './index-meta';
|
|
4
|
+
import { Association } from './association';
|
|
5
|
+
import { EntityColumnElement } from './entity-column-element';
|
|
6
|
+
import { EntityObjectElement } from './entity-object-element';
|
|
7
|
+
import { EntityAssociationElement } from './entity-association-element';
|
|
8
|
+
import { AssociationNode } from './association-node';
|
|
9
|
+
export declare type EntityElement = EntityColumnElement | EntityObjectElement | EntityAssociationElement;
|
|
10
|
+
export declare class EntityModel {
|
|
11
|
+
readonly ctor: Type;
|
|
12
|
+
private _elementKeys?;
|
|
13
|
+
readonly name: string;
|
|
14
|
+
tableName?: string;
|
|
15
|
+
schema?: string;
|
|
16
|
+
comment?: string;
|
|
17
|
+
primaryIndex?: IndexMeta;
|
|
18
|
+
elements: Map<string, EntityElement>;
|
|
19
|
+
indexes: IndexMeta[];
|
|
20
|
+
foreignKeys: Association[];
|
|
21
|
+
eventListeners: {
|
|
22
|
+
event: string;
|
|
23
|
+
fn: Function;
|
|
24
|
+
}[];
|
|
25
|
+
constructor(ctor: Type);
|
|
26
|
+
get elementKeys(): string[];
|
|
27
|
+
getElement(name: string): Maybe<EntityElement>;
|
|
28
|
+
getColumnElement(name: string): Maybe<EntityColumnElement>;
|
|
29
|
+
getColumnElementByFieldName(fieldName: string): Maybe<EntityColumnElement>;
|
|
30
|
+
getObjectElement(name: string): Maybe<EntityObjectElement>;
|
|
31
|
+
getAssociationElement(name: string): Maybe<EntityAssociationElement>;
|
|
32
|
+
defineColumnElement(propertyKey: string, options?: DataPropertyOptions): EntityColumnElement;
|
|
33
|
+
defineAssociationElement(propertyKey: string, association: AssociationNode): EntityAssociationElement;
|
|
34
|
+
defineObjectElement(propertyKey: string, type?: TypeThunk): EntityObjectElement;
|
|
35
|
+
setPrimaryIndex(column: string | string[], options?: IndexOptions): void;
|
|
36
|
+
addIndex(column: string | string[], options?: IndexOptions): void;
|
|
37
|
+
addForeignKey(propertyKey: string, target: TypeThunk, targetKey?: string): void;
|
|
38
|
+
before(event: 'insert' | 'update' | 'destroy', fn: Type): void;
|
|
39
|
+
after(event: 'insert' | 'update' | 'destroy', fn: Type): void;
|
|
40
|
+
getPrimaryIndexColumns(): EntityColumnElement[];
|
|
41
|
+
getElementNames(fn: (el: EntityElement) => boolean): string[];
|
|
42
|
+
getColumnNames(): string[];
|
|
43
|
+
getObjectElementNames(): string[];
|
|
44
|
+
getAssociationElementNames(): string[];
|
|
45
|
+
getNonAssociationElementNames(): string[];
|
|
46
|
+
getInsertColumnNames(): string[];
|
|
47
|
+
getUpdateColumnNames(): string[];
|
|
48
|
+
getForeignKeyFor(t: EntityModel): Promise<Maybe<Association>>;
|
|
49
|
+
static get(ctor: Function): Maybe<EntityModel>;
|
|
50
|
+
static hasOwn(ctor: Function): boolean;
|
|
51
|
+
static attachTo(ctor: Function): EntityModel;
|
|
52
|
+
static getElementNames<T extends Function, K extends keyof T>(ctor: T): K[] | undefined;
|
|
53
|
+
static getColumnNames<T extends Function, K extends keyof T>(ctor: T): K[] | undefined;
|
|
54
|
+
static getAssociationElementNames<T extends Function, K extends keyof T>(ctor: T): K[] | undefined;
|
|
55
|
+
static getNonAssociationElementNames<T extends Function, K extends keyof T>(ctor: T): K[] | undefined;
|
|
56
|
+
static getObjectElementNames<T extends Function, K extends keyof T>(ctor: T): K[] | undefined;
|
|
57
|
+
static getInsertColumnNames<T extends Function, K extends keyof T>(ctor: T): K[] | undefined;
|
|
58
|
+
static getUpdateColumnNames<T extends Function, K extends keyof T>(ctor: T): K[] | undefined;
|
|
59
|
+
}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityModel = void 0;
|
|
4
|
+
const builder_1 = require("@sqb/builder");
|
|
5
|
+
const orm_const_1 = require("../orm.const");
|
|
6
|
+
const index_meta_1 = require("./index-meta");
|
|
7
|
+
const association_1 = require("./association");
|
|
8
|
+
const entity_column_element_1 = require("./entity-column-element");
|
|
9
|
+
const entity_object_element_1 = require("./entity-object-element");
|
|
10
|
+
const entity_association_element_1 = require("./entity-association-element");
|
|
11
|
+
const serialize_element_1 = require("../util/serialize-element");
|
|
12
|
+
const orm_helper_1 = require("../util/orm.helper");
|
|
13
|
+
class EntityModel {
|
|
14
|
+
constructor(ctor) {
|
|
15
|
+
this.ctor = ctor;
|
|
16
|
+
this.elements = new Map();
|
|
17
|
+
this.indexes = [];
|
|
18
|
+
this.foreignKeys = [];
|
|
19
|
+
this.eventListeners = [];
|
|
20
|
+
this.name = ctor.name;
|
|
21
|
+
}
|
|
22
|
+
get elementKeys() {
|
|
23
|
+
if (!(this._elementKeys && this.hasOwnProperty('_elementKeys')))
|
|
24
|
+
this._elementKeys = Array.from(this.elements.keys());
|
|
25
|
+
return this._elementKeys;
|
|
26
|
+
}
|
|
27
|
+
getElement(name) {
|
|
28
|
+
if (!name)
|
|
29
|
+
return;
|
|
30
|
+
return this.elements.get(name.toLowerCase());
|
|
31
|
+
}
|
|
32
|
+
getColumnElement(name) {
|
|
33
|
+
if (!name)
|
|
34
|
+
return;
|
|
35
|
+
const prop = this.elements.get(name.toLowerCase());
|
|
36
|
+
return (0, orm_helper_1.isColumnElement)(prop) ? prop : undefined;
|
|
37
|
+
}
|
|
38
|
+
getColumnElementByFieldName(fieldName) {
|
|
39
|
+
if (!fieldName)
|
|
40
|
+
return;
|
|
41
|
+
fieldName = fieldName.toLowerCase();
|
|
42
|
+
for (const prop of this.elements.values()) {
|
|
43
|
+
if ((0, orm_helper_1.isColumnElement)(prop) && prop.fieldName.toLowerCase() === fieldName)
|
|
44
|
+
return prop;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
getObjectElement(name) {
|
|
48
|
+
if (!name)
|
|
49
|
+
return;
|
|
50
|
+
const col = this.elements.get(name.toLowerCase());
|
|
51
|
+
return (0, orm_helper_1.isObjectElement)(col) ? col : undefined;
|
|
52
|
+
}
|
|
53
|
+
getAssociationElement(name) {
|
|
54
|
+
if (!name)
|
|
55
|
+
return;
|
|
56
|
+
const col = this.elements.get(name.toLowerCase());
|
|
57
|
+
return (0, orm_helper_1.isAssociationElement)(col) ? col : undefined;
|
|
58
|
+
}
|
|
59
|
+
defineColumnElement(propertyKey, options) {
|
|
60
|
+
let prop = this.getElement(propertyKey);
|
|
61
|
+
if (!prop || !(0, orm_helper_1.isColumnElement)(prop)) {
|
|
62
|
+
prop = new entity_column_element_1.EntityColumnElement(this, propertyKey, options);
|
|
63
|
+
if (!prop.type) {
|
|
64
|
+
const typ = Reflect.getMetadata("design:type", this.ctor.prototype, propertyKey);
|
|
65
|
+
if (typ === Array) {
|
|
66
|
+
prop.type = String;
|
|
67
|
+
prop.isArray = true;
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
prop.type = typ;
|
|
71
|
+
}
|
|
72
|
+
if (!prop.dataType) {
|
|
73
|
+
if (prop.type === Boolean)
|
|
74
|
+
prop.dataType = builder_1.DataType.BOOL;
|
|
75
|
+
else if (prop.type === String)
|
|
76
|
+
prop.dataType = builder_1.DataType.VARCHAR;
|
|
77
|
+
else if (prop.type === Number)
|
|
78
|
+
prop.dataType = builder_1.DataType.NUMBER;
|
|
79
|
+
else if (prop.type === Date)
|
|
80
|
+
prop.dataType = builder_1.DataType.TIMESTAMP;
|
|
81
|
+
else if (prop.type === Array) {
|
|
82
|
+
prop.dataType = builder_1.DataType.VARCHAR;
|
|
83
|
+
prop.isArray = true;
|
|
84
|
+
}
|
|
85
|
+
else if (prop.type === Buffer)
|
|
86
|
+
prop.dataType = builder_1.DataType.BINARY;
|
|
87
|
+
}
|
|
88
|
+
if (options?.isArray)
|
|
89
|
+
prop.isArray = true;
|
|
90
|
+
if (!this.elements.has(propertyKey.toLowerCase()))
|
|
91
|
+
this.elementKeys.push(propertyKey);
|
|
92
|
+
this.elements.set(propertyKey.toLowerCase(), prop);
|
|
93
|
+
}
|
|
94
|
+
else if (options)
|
|
95
|
+
prop.assign(options);
|
|
96
|
+
return prop;
|
|
97
|
+
}
|
|
98
|
+
defineAssociationElement(propertyKey, association) {
|
|
99
|
+
const prop = new entity_association_element_1.EntityAssociationElement(this, propertyKey, association);
|
|
100
|
+
let l = association;
|
|
101
|
+
let i = 1;
|
|
102
|
+
while (l) {
|
|
103
|
+
l.name = this.name + '.' + propertyKey + '#' + (i++);
|
|
104
|
+
l = l.next;
|
|
105
|
+
}
|
|
106
|
+
if (!this.elements.has(propertyKey.toLowerCase()))
|
|
107
|
+
this.elementKeys.push(propertyKey);
|
|
108
|
+
this.elements.set(propertyKey.toLowerCase(), prop);
|
|
109
|
+
return prop;
|
|
110
|
+
}
|
|
111
|
+
defineObjectElement(propertyKey, type) {
|
|
112
|
+
type = type || Reflect.getMetadata("design:type", this.ctor.prototype, propertyKey);
|
|
113
|
+
if (typeof type !== 'function')
|
|
114
|
+
throw new Error('"type" must be defined');
|
|
115
|
+
let prop = this.getElement(propertyKey);
|
|
116
|
+
if (!prop || !(0, orm_helper_1.isObjectElement)(prop)) {
|
|
117
|
+
prop = new entity_object_element_1.EntityObjectElement(this, propertyKey, type);
|
|
118
|
+
if (!this.elements.has(propertyKey.toLowerCase()))
|
|
119
|
+
this.elementKeys.push(propertyKey);
|
|
120
|
+
this.elements.set(propertyKey.toLowerCase(), prop);
|
|
121
|
+
}
|
|
122
|
+
return prop;
|
|
123
|
+
}
|
|
124
|
+
setPrimaryIndex(column, options) {
|
|
125
|
+
this.primaryIndex = new index_meta_1.IndexMeta(this, column, options);
|
|
126
|
+
this.primaryIndex.unique = true;
|
|
127
|
+
}
|
|
128
|
+
addIndex(column, options) {
|
|
129
|
+
this.indexes.push(new index_meta_1.IndexMeta(this, column, options));
|
|
130
|
+
}
|
|
131
|
+
addForeignKey(propertyKey, target, targetKey) {
|
|
132
|
+
const fk = new association_1.Association(this.name + '.' + propertyKey, {
|
|
133
|
+
source: this.ctor,
|
|
134
|
+
sourceKey: propertyKey,
|
|
135
|
+
target,
|
|
136
|
+
targetKey
|
|
137
|
+
});
|
|
138
|
+
this.foreignKeys.push(fk);
|
|
139
|
+
}
|
|
140
|
+
before(event, fn) {
|
|
141
|
+
this.eventListeners.push({ event: 'before-' + event, fn });
|
|
142
|
+
}
|
|
143
|
+
after(event, fn) {
|
|
144
|
+
this.eventListeners.push({ event: 'after-' + event, fn });
|
|
145
|
+
}
|
|
146
|
+
getPrimaryIndexColumns() {
|
|
147
|
+
const out = [];
|
|
148
|
+
if (this.primaryIndex) {
|
|
149
|
+
for (const k of this.primaryIndex.columns) {
|
|
150
|
+
const col = this.getColumnElement(k);
|
|
151
|
+
if (!col)
|
|
152
|
+
throw new Error(`Data column "${k}" in primary index of ${this.name} does not exists`);
|
|
153
|
+
out.push(col);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
getElementNames(fn) {
|
|
159
|
+
const out = [];
|
|
160
|
+
for (const k of this.elementKeys) {
|
|
161
|
+
const el = this.getElement(k);
|
|
162
|
+
if (el && (!fn || fn(el)))
|
|
163
|
+
out.push(k);
|
|
164
|
+
}
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
getColumnNames() {
|
|
168
|
+
return this.getElementNames(orm_helper_1.isColumnElement);
|
|
169
|
+
}
|
|
170
|
+
getObjectElementNames() {
|
|
171
|
+
return this.getElementNames(orm_helper_1.isObjectElement);
|
|
172
|
+
}
|
|
173
|
+
getAssociationElementNames() {
|
|
174
|
+
return this.getElementNames(orm_helper_1.isAssociationElement);
|
|
175
|
+
}
|
|
176
|
+
getNonAssociationElementNames() {
|
|
177
|
+
return this.getElementNames(x => !(0, orm_helper_1.isAssociationElement)(x));
|
|
178
|
+
}
|
|
179
|
+
getInsertColumnNames() {
|
|
180
|
+
const out = [];
|
|
181
|
+
for (const k of this.elementKeys) {
|
|
182
|
+
const col = this.getElement(k);
|
|
183
|
+
if ((0, orm_helper_1.isColumnElement)(col) && !col.noInsert)
|
|
184
|
+
out.push(k);
|
|
185
|
+
}
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
getUpdateColumnNames() {
|
|
189
|
+
const out = [];
|
|
190
|
+
for (const k of this.elementKeys) {
|
|
191
|
+
const col = this.getElement(k);
|
|
192
|
+
if ((0, orm_helper_1.isColumnElement)(col) && !col.noUpdate)
|
|
193
|
+
out.push(k);
|
|
194
|
+
}
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
async getForeignKeyFor(t) {
|
|
198
|
+
for (const f of this.foreignKeys) {
|
|
199
|
+
if (await f.resolveTarget() === t)
|
|
200
|
+
return f;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
static get(ctor) {
|
|
204
|
+
return ctor[orm_const_1.ENTITY_DEFINITION_KEY];
|
|
205
|
+
}
|
|
206
|
+
static hasOwn(ctor) {
|
|
207
|
+
return ctor.hasOwnProperty(orm_const_1.ENTITY_DEFINITION_KEY);
|
|
208
|
+
}
|
|
209
|
+
static attachTo(ctor) {
|
|
210
|
+
const own = this.hasOwn(ctor) ? this.get(ctor) : undefined;
|
|
211
|
+
if (own)
|
|
212
|
+
return own;
|
|
213
|
+
const current = this.get(ctor);
|
|
214
|
+
const entity = new EntityModel(ctor);
|
|
215
|
+
Object.defineProperty(ctor, orm_const_1.ENTITY_DEFINITION_KEY, {
|
|
216
|
+
value: entity,
|
|
217
|
+
enumerable: false
|
|
218
|
+
});
|
|
219
|
+
// Merge base entity columns into this one
|
|
220
|
+
if (current) {
|
|
221
|
+
entity.tableName = current.tableName;
|
|
222
|
+
for (const k of current.elementKeys) {
|
|
223
|
+
const col = current.elements.get(k.toLowerCase());
|
|
224
|
+
if (col) {
|
|
225
|
+
entity.elementKeys.push(k);
|
|
226
|
+
entity.elements.set(k.toLowerCase(), col);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
for (const fk of current.foreignKeys) {
|
|
230
|
+
const newFk = new association_1.Association(fk.name, { ...fk, source: ctor });
|
|
231
|
+
entity.foreignKeys.push(newFk);
|
|
232
|
+
}
|
|
233
|
+
for (const idx of current.indexes) {
|
|
234
|
+
const newIdx = new index_meta_1.IndexMeta(entity, idx.columns, idx);
|
|
235
|
+
entity.indexes.push(newIdx);
|
|
236
|
+
}
|
|
237
|
+
entity.eventListeners.push(...current.eventListeners);
|
|
238
|
+
if (current.primaryIndex)
|
|
239
|
+
entity.setPrimaryIndex([...current.primaryIndex.columns]);
|
|
240
|
+
}
|
|
241
|
+
ctor.prototype.toJSON = function () {
|
|
242
|
+
const obj = {};
|
|
243
|
+
const elementKeys = entity.elementKeys;
|
|
244
|
+
const l = elementKeys.length;
|
|
245
|
+
let key;
|
|
246
|
+
let v;
|
|
247
|
+
for (let i = 0; i < l; i++) {
|
|
248
|
+
key = elementKeys[i];
|
|
249
|
+
v = this[key];
|
|
250
|
+
if (v === undefined)
|
|
251
|
+
continue;
|
|
252
|
+
const col = entity.getElement(key);
|
|
253
|
+
if (col)
|
|
254
|
+
obj[key] = (0, serialize_element_1.serializeColumn)(col, v);
|
|
255
|
+
}
|
|
256
|
+
return obj;
|
|
257
|
+
};
|
|
258
|
+
return entity;
|
|
259
|
+
}
|
|
260
|
+
static getElementNames(ctor) {
|
|
261
|
+
const meta = this.get(ctor);
|
|
262
|
+
return meta && [...meta.elementKeys];
|
|
263
|
+
}
|
|
264
|
+
static getColumnNames(ctor) {
|
|
265
|
+
const meta = this.get(ctor);
|
|
266
|
+
if (meta)
|
|
267
|
+
return meta.getColumnNames();
|
|
268
|
+
}
|
|
269
|
+
static getAssociationElementNames(ctor) {
|
|
270
|
+
const meta = this.get(ctor);
|
|
271
|
+
if (meta)
|
|
272
|
+
return meta.getAssociationElementNames();
|
|
273
|
+
}
|
|
274
|
+
static getNonAssociationElementNames(ctor) {
|
|
275
|
+
const meta = this.get(ctor);
|
|
276
|
+
if (meta)
|
|
277
|
+
return meta.getNonAssociationElementNames();
|
|
278
|
+
}
|
|
279
|
+
static getObjectElementNames(ctor) {
|
|
280
|
+
const meta = this.get(ctor);
|
|
281
|
+
if (meta)
|
|
282
|
+
return meta.getObjectElementNames();
|
|
283
|
+
}
|
|
284
|
+
static getInsertColumnNames(ctor) {
|
|
285
|
+
const meta = this.get(ctor);
|
|
286
|
+
if (meta)
|
|
287
|
+
return meta.getInsertColumnNames();
|
|
288
|
+
}
|
|
289
|
+
static getUpdateColumnNames(ctor) {
|
|
290
|
+
const meta = this.get(ctor);
|
|
291
|
+
if (meta)
|
|
292
|
+
return meta.getUpdateColumnNames();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
exports.EntityModel = EntityModel;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ElementKind, TypeThunk, DataPropertyOptions } from '../orm.type';
|
|
2
|
+
import { AbstractEntityelement } from './abstract-entityelement';
|
|
3
|
+
import { EntityModel } from './entity-model';
|
|
4
|
+
export declare class EntityObjectElement extends AbstractEntityelement {
|
|
5
|
+
kind: ElementKind;
|
|
6
|
+
type: TypeThunk;
|
|
7
|
+
fieldNamePrefix?: string;
|
|
8
|
+
fieldNameSuffix?: string;
|
|
9
|
+
constructor(entity: EntityModel, name: string, type: TypeThunk);
|
|
10
|
+
resolveType(): Promise<EntityModel>;
|
|
11
|
+
assign(options: DataPropertyOptions): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityObjectElement = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
6
|
+
const abstract_entityelement_1 = require("./abstract-entityelement");
|
|
7
|
+
const orm_helper_1 = require("../util/orm.helper");
|
|
8
|
+
class EntityObjectElement extends abstract_entityelement_1.AbstractEntityelement {
|
|
9
|
+
constructor(entity, name, type) {
|
|
10
|
+
super(entity, name);
|
|
11
|
+
this.kind = 'object';
|
|
12
|
+
this.type = type;
|
|
13
|
+
}
|
|
14
|
+
async resolveType() {
|
|
15
|
+
const typ = await (0, orm_helper_1.resolveEntityMeta)(this.type);
|
|
16
|
+
if (typ)
|
|
17
|
+
return typ;
|
|
18
|
+
throw new Error(`Can't resolve type of ${this.entity.name}.${this.name}`);
|
|
19
|
+
}
|
|
20
|
+
assign(options) {
|
|
21
|
+
Object.assign(this, lodash_1.default.omit(options, ['entity', 'name', 'kind']));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.EntityObjectElement = EntityObjectElement;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EntityModel } from './entity-model';
|
|
2
|
+
import { IndexOptions } from '../orm.type';
|
|
3
|
+
export declare class IndexMeta {
|
|
4
|
+
entity: EntityModel;
|
|
5
|
+
columns: string[];
|
|
6
|
+
name?: string;
|
|
7
|
+
unique?: boolean;
|
|
8
|
+
constructor(entity: EntityModel, column: string | string[], options?: IndexOptions);
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IndexMeta = void 0;
|
|
4
|
+
class IndexMeta {
|
|
5
|
+
constructor(entity, column, options) {
|
|
6
|
+
this.entity = entity;
|
|
7
|
+
this.columns = Array.isArray(column) ? column : [column];
|
|
8
|
+
if (options) {
|
|
9
|
+
if (options.name)
|
|
10
|
+
this.name = options.name;
|
|
11
|
+
if (options.unique)
|
|
12
|
+
this.unique = options.unique;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.IndexMeta = IndexMeta;
|