chore: load view collection when source not found (#1930)

This commit is contained in:
ChengLei Shao 2023-05-25 21:46:58 +08:00 committed by GitHub
parent e61568ac57
commit 27a74906ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -79,6 +79,31 @@ export class Collection<
model: ModelStatic<Model>; model: ModelStatic<Model>;
repository: Repository<TModelAttributes, TCreationAttributes>; repository: Repository<TModelAttributes, TCreationAttributes>;
constructor(options: CollectionOptions, context: CollectionContext) {
super();
this.context = context;
this.options = options;
this.checkOptions(options);
this.bindFieldEventListener();
this.modelInit();
this.db.modelCollection.set(this.model, this);
// set tableName to collection map
// the form of key is `${schema}.${tableName}` if schema exists
// otherwise is `${tableName}`
this.db.tableNameCollectionMap.set(this.getTableNameWithSchemaAsString(), this);
if (!options.inherits) {
this.setFields(options.fields);
}
this.setRepository(options.repository);
this.setSortable(options.sortable);
}
get filterTargetKey() { get filterTargetKey() {
const targetKey = lodash.get(this.options, 'filterTargetKey', this.model.primaryKeyAttribute); const targetKey = lodash.get(this.options, 'filterTargetKey', this.model.primaryKeyAttribute);
if (!targetKey && this.model.rawAttributes['id']) { if (!targetKey && this.model.rawAttributes['id']) {
@ -116,65 +141,12 @@ export class Collection<
} }
} }
constructor(options: CollectionOptions, context: CollectionContext) {
super();
this.context = context;
this.options = options;
this.checkOptions(options);
this.bindFieldEventListener();
this.modelInit();
this.db.modelCollection.set(this.model, this);
// set tableName to collection map
// the form of key is `${schema}.${tableName}` if schema exists
// otherwise is `${tableName}`
this.db.tableNameCollectionMap.set(this.getTableNameWithSchemaAsString(), this);
if (!options.inherits) {
this.setFields(options.fields);
}
this.setRepository(options.repository);
this.setSortable(options.sortable);
}
private checkOptions(options: CollectionOptions) {
checkIdentifier(options.name);
this.checkTableName();
}
private checkTableName() {
const tableName = this.tableName();
for (const [k, collection] of this.db.collections) {
if (
collection.name != this.options.name &&
tableName === collection.tableName() &&
collection.collectionSchema() === this.collectionSchema()
) {
throw new Error(`collection ${collection.name} and ${this.name} have same tableName "${tableName}"`);
}
}
}
tableName() { tableName() {
const { name, tableName } = this.options; const { name, tableName } = this.options;
const tName = tableName || name; const tName = tableName || name;
return this.options.underscored ? snakeCase(tName) : tName; return this.options.underscored ? snakeCase(tName) : tName;
} }
protected sequelizeModelOptions() {
const { name } = this.options;
return {
..._.omit(this.options, ['name', 'fields', 'model', 'targetKey']),
modelName: name,
sequelize: this.context.database.sequelize,
tableName: this.tableName(),
};
}
/** /**
* TODO * TODO
*/ */
@ -232,17 +204,6 @@ export class Collection<
this.repository = new repo(this); this.repository = new repo(this);
} }
private bindFieldEventListener() {
this.on('field.afterAdd', (field: Field) => {
field.bind();
});
this.on('field.afterRemove', (field: Field) => {
field.unbind();
this.db.emit('field.afterRemove', field);
});
}
forEachField(callback: (field: Field) => void) { forEachField(callback: (field: Field) => void) {
return [...this.fields.values()].forEach(callback); return [...this.fields.values()].forEach(callback);
} }
@ -299,12 +260,20 @@ export class Collection<
const [sourceCollectionName, sourceFieldName] = options.source.split('.'); const [sourceCollectionName, sourceFieldName] = options.source.split('.');
const sourceCollection = this.db.collections.get(sourceCollectionName); const sourceCollection = this.db.collections.get(sourceCollectionName);
if (!sourceCollection) { if (!sourceCollection) {
throw new Error( this.db.logger.warn(
`source collection "${sourceCollectionName}" not found for field "${name}" at collection "${this.name}"`, `source collection "${sourceCollectionName}" not found for field "${name}" at collection "${this.name}"`,
); );
} }
const sourceField = sourceCollection.fields.get(sourceFieldName); const sourceField = sourceCollection.fields.get(sourceFieldName);
options = { ...sourceField.options, ...options };
if (!sourceField) {
this.db.logger.warn(
`source field "${sourceFieldName}" not found for field "${name}" at collection "${this.name}"`,
);
} else {
options = { ...sourceField.options, ...options };
}
} }
this.emit('field.beforeAdd', name, options, { collection: this }); this.emit('field.beforeAdd', name, options, { collection: this });
@ -678,4 +647,43 @@ export class Collection<
public isView() { public isView() {
return false; return false;
} }
protected sequelizeModelOptions() {
const { name } = this.options;
return {
..._.omit(this.options, ['name', 'fields', 'model', 'targetKey']),
modelName: name,
sequelize: this.context.database.sequelize,
tableName: this.tableName(),
};
}
private checkOptions(options: CollectionOptions) {
checkIdentifier(options.name);
this.checkTableName();
}
private checkTableName() {
const tableName = this.tableName();
for (const [k, collection] of this.db.collections) {
if (
collection.name != this.options.name &&
tableName === collection.tableName() &&
collection.collectionSchema() === this.collectionSchema()
) {
throw new Error(`collection ${collection.name} and ${this.name} have same tableName "${tableName}"`);
}
}
}
private bindFieldEventListener() {
this.on('field.afterAdd', (field: Field) => {
field.bind();
});
this.on('field.afterRemove', (field: Field) => {
field.unbind();
this.db.emit('field.afterRemove', field);
});
}
} }