UNPKG

9.13 kBPlain TextView Raw
1import Mongoose = require('mongoose');
2import * as Sequelize from "sequelize";
3//import aa = require('mongoose');
4import * as Enumerable from 'linq';
5import * as Types from './datatype';
6import { Strict } from './enums/entity-strict';
7import { Decorators } from '../core/constants/decorators';
8import { MetadataConstants } from '../core/constants';
9
10import { DecoratorType } from '../core/enums/decorator-type';
11import { MetaUtils } from "../core/metadata/utils";
12import { MetaData } from '../core/metadata/metadata';
13import { IEntityParams } from './decorators/interfaces/entity-params';
14import { sequelizeService } from './sequelizeService';
15
16export class DynamicSchema {
17 parsedSchema: any;
18 schemaName: string;
19 private target: Object;
20 private _tablespecs: any;
21 private _schema: any;
22 private _relations: any = {};
23 private _defaultPrimaryKey = null;
24 private _removeColumnProperties = ['name','otherProperties'];
25
26 constructor(target: Object, name: string, tableSpecs: any) {
27 this.target = target;
28 this.schemaName = name;
29 this.parsedSchema = this.parse(target);
30 this._tablespecs = tableSpecs;
31 this._schema = sequelizeService.addScheam(this.schemaName, this.parsedSchema, this._tablespecs);
32 if(this._defaultPrimaryKey){
33 this._schema.beforeCreate((user, _ ) => {
34 let id = this['_defaultPrimaryKey'](user);
35 user[this._schema.primaryKeyField] =id;
36 return user;
37 });
38 }
39 }
40
41 public getSchema() {
42 return this._schema;
43 }
44
45 public getRelations() {
46 return this._relations;
47 }
48
49 public getTarget() {
50 return this.target;
51 }
52
53 private parse(target: Object) {
54 if (!target || !(target instanceof Object)) {
55 throw TypeError;
56 }
57 var schema = {};
58 var primaryKeyProp;
59 //var metaDataMap = this.getAllMetadataForSchema(target);
60 var metaDataMap = MetaUtils.getMetaData(this.target, Decorators.COLUMN);
61 for (var field in metaDataMap) {
62 var fieldMetadata: MetaData = <MetaData>metaDataMap[field];
63 let newParam = {}
64 Object.keys(fieldMetadata.params).forEach(x => {
65 if(this._removeColumnProperties.indexOf(x)<0){
66 newParam[x] = fieldMetadata.params[x]
67 }
68 else if(x == 'otherProperties'){
69 Object.keys(fieldMetadata.params[x]).forEach(subProp=>{
70 newParam[subProp] = fieldMetadata.params[x][subProp];
71 });
72 }
73 })
74 if(fieldMetadata.params.primaryKey && typeof fieldMetadata.params.defaultValue=="function"){
75 this._defaultPrimaryKey = fieldMetadata.params.defaultValue;
76 delete newParam['defaultValue'];
77 }
78 schema[fieldMetadata.params.name] = newParam;
79 }
80
81 var metaDataMap1 = MetaUtils.getMetaData(this.target, Decorators.ONETOMANY);
82 var oneTomanyrels = [];
83 for (var field in metaDataMap1) {
84 var fieldMetadata: MetaData = <MetaData>metaDataMap1[field];
85
86 var params = fieldMetadata.params;
87 params.propertyKey = fieldMetadata.propertyKey;
88 if (!params.foreignKey)
89 throw 'Please add foreign key for association ' + this.schemaName + ' -> ' + params.propertyKey;
90 oneTomanyrels.push(params);
91 }
92 this._relations[Decorators.ONETOMANY] = oneTomanyrels;
93
94 var metaDataMap2 = MetaUtils.getMetaData(this.target, Decorators.MANYTOONE);
95 var manytoonerels = [];
96 for (var field in metaDataMap2) {
97 var fieldMetadata: MetaData = <MetaData>metaDataMap2[field];
98
99 var params = fieldMetadata.params;
100 params.propertyKey = fieldMetadata.propertyKey;
101 if (!params.foreignKey)
102 throw 'Please add foreign key for association ' + this.schemaName + ' -> ' + params.propertyKey;
103 else if (!schema[params.foreignKey])
104 throw 'Please choose a valid foreign key from the defined properties for ' + this.schemaName + ' -> ' + params.propertyKey;
105 manytoonerels.push(params);
106 }
107 this._relations[Decorators.MANYTOONE] = manytoonerels;
108
109 var metaDataMap3 = MetaUtils.getMetaData(this.target, Decorators.ONETOONE);
110 var onetoonerels = [];
111 for (var field in metaDataMap3) {
112 var fieldMetadata: MetaData = <MetaData>metaDataMap3[field];
113
114 var params = fieldMetadata.params;
115 params.propertyKey = fieldMetadata.propertyKey;
116 if (!params.foreignKey)
117 throw 'Please add foreign key for association ' + this.schemaName + ' -> ' + params.propertyKey;
118 onetoonerels.push(params);
119 }
120 this._relations[Decorators.ONETOONE] = onetoonerels;
121
122 return schema;
123 }
124
125 private getSearchSchemaTypeForParam(fieldMetadata: MetaData): any {
126 var schemaType = this.getSchemaTypeForType(fieldMetadata.getType());
127 if (fieldMetadata.params && fieldMetadata.params.rel) {
128 return fieldMetadata.propertyType.isArray ? [schemaType] : schemaType;
129 }
130 else {
131 return fieldMetadata.propertyType.isArray ? [schemaType] : { type: schemaType, es_indexed: true };
132 }
133 //var schemaType = this.getSchemaTypeForType(paramType);
134 //if (paramType.rel) {
135 // //var metaData = Utils.getPrimaryKeyMetadata(paramType.itemType);
136 // //var relSchema;
137 // //if ((<any>fieldMetadata.params).embedded) {
138 // // schema[field] = paramType.isArray ? [Types.Mixed] : Mongoose.Schema.Types.Mixed;
139 // //} else {
140 // // relSchema = { ref: paramType.rel, type: Mongoose.Schema.Types.ObjectId };
141 // // schema[field] = paramType.isArray ? [relSchema] : relSchema;
142 // //}
143
144 // // need to handle embedding vs foreign key refs
145 // return paramType.isArray ? [schemaType] : schemaType;
146 //}
147 //return paramType.isArray ? [schemaType] : {type : schemaType, es_indexed : true};
148 }
149
150 private getSchemaTypeForParam(fieldMetadata: MetaData) {
151 var schemaType = this.getSchemaTypeForType(fieldMetadata.getType());
152 return fieldMetadata.propertyType.isArray ? [schemaType] : schemaType;
153 //var schemaType = this.getSchemaTypeForType(paramType.itemType);
154 //if (paramType.rel) {
155 // //var metaData = Utils.getPrimaryKeyMetadata(paramType.itemType);
156 // //var relSchema;
157 // //if ((<any>fieldMetadata.params).embedded) {
158 // // schema[field] = paramType.isArray ? [Types.Mixed] : Mongoose.Schema.Types.Mixed;
159 // //} else {
160 // // relSchema = { ref: paramType.rel, type: Mongoose.Schema.Types.ObjectId };
161 // // schema[field] = paramType.isArray ? [relSchema] : relSchema;
162 // //}
163
164 // // need to handle embedding vs foreign key refs
165 // return paramType.isArray ? [schemaType] : schemaType;
166 //}
167 //return paramType.isArray ? [schemaType] : schemaType;
168 }
169
170 private getSchemaTypeForType(type?): any {
171 switch (type) {
172 case Mongoose.Types.ObjectId: return Mongoose.Schema.Types.ObjectId;
173 case String: return Sequelize.STRING(128);
174 case Number: return Number;
175 case Buffer: return Buffer;
176 case Date: return Date;
177 case Boolean: return Boolean;
178 case Array: return Array;
179 //case undefined: return Mongoose.Schema.Types.Mixed;
180 // any or no types
181 case Object:
182 default: return Mongoose.Schema.Types.Mixed;
183 }
184 }
185
186 private getMongooseOptions(target: Object) {
187 var meta = MetaUtils.getMetaData(<any>target, Decorators.ENTITY);
188 var entityMeta = meta[0];
189 var options = <any>{};
190 var params = <IEntityParams>(entityMeta.params || <any>{});
191 options.strict = true;
192 return options;
193 }
194
195 private isSchemaDecorator(decorator: string) {
196 return decorator === Decorators.FIELD || decorator === Decorators.ONETOMANY || decorator === Decorators.MANYTOONE || decorator === Decorators.MANYTOMANY || decorator === Decorators.ONETOONE;
197 }
198
199 private getAllMetadataForSchema(target: Object): { [key: string]: MetaData } {
200 var metaDataMap: Array<MetaData> = MetaUtils.getMetaData(<any>target);
201 var metaDataMapFiltered: { [key: string]: MetaData } = <any>{};
202 for (var i in metaDataMap) {
203 var meta: MetaData = metaDataMap[i] as MetaData;
204
205 if (!this.isSchemaDecorator(meta.decorator))
206 continue;
207
208 if (metaDataMapFiltered[meta.propertyKey])
209 throw "A property cannot have more than one schema decorator";
210
211 metaDataMapFiltered[meta.propertyKey] = meta;
212 }
213 return metaDataMapFiltered;
214 }
215}
\No newline at end of file