Stop switching to a different datasource per workspace (#3425)
* Stop switching to a different datasource per workspace * Add console * Remove call to metadata
This commit is contained in:
@ -37,27 +37,35 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy {
|
||||
public async connectToDataSource(
|
||||
dataSource: DataSourceEntity,
|
||||
): Promise<DataSource | undefined> {
|
||||
// Wait for a bit before trying again if another initialization is in progress
|
||||
while (this.isDatasourceInitializing.get(dataSource.id)) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
const isMultiDatasourceEnabled = false;
|
||||
|
||||
console.log('Data sources number', this.dataSources.size);
|
||||
|
||||
if (isMultiDatasourceEnabled) {
|
||||
// Wait for a bit before trying again if another initialization is in progress
|
||||
while (this.isDatasourceInitializing.get(dataSource.id)) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
}
|
||||
|
||||
if (this.dataSources.has(dataSource.id)) {
|
||||
return this.dataSources.get(dataSource.id);
|
||||
}
|
||||
|
||||
this.isDatasourceInitializing.set(dataSource.id, true);
|
||||
|
||||
try {
|
||||
const dataSourceInstance =
|
||||
await this.createAndInitializeDataSource(dataSource);
|
||||
|
||||
this.dataSources.set(dataSource.id, dataSourceInstance);
|
||||
|
||||
return dataSourceInstance;
|
||||
} finally {
|
||||
this.isDatasourceInitializing.delete(dataSource.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.dataSources.has(dataSource.id)) {
|
||||
return this.dataSources.get(dataSource.id);
|
||||
}
|
||||
|
||||
this.isDatasourceInitializing.set(dataSource.id, true);
|
||||
|
||||
try {
|
||||
const dataSourceInstance =
|
||||
await this.createAndInitializeDataSource(dataSource);
|
||||
|
||||
this.dataSources.set(dataSource.id, dataSourceInstance);
|
||||
|
||||
return dataSourceInstance;
|
||||
} finally {
|
||||
this.isDatasourceInitializing.delete(dataSource.id);
|
||||
}
|
||||
return this.mainDataSource;
|
||||
}
|
||||
|
||||
private async createAndInitializeDataSource(
|
||||
|
||||
@ -298,6 +298,7 @@ export class WorkspaceMigrationRunnerService {
|
||||
columnNames: [migrationColumn.columnName],
|
||||
referencedColumnNames: [migrationColumn.referencedTableColumnName],
|
||||
referencedTableName: migrationColumn.referencedTableName,
|
||||
referencedSchema: schemaName,
|
||||
onDelete: 'CASCADE',
|
||||
}),
|
||||
);
|
||||
|
||||
@ -27,6 +27,7 @@ export class CreateManyQueryFactory {
|
||||
const fieldsString = await this.fieldsStringFactory.create(
|
||||
options.info,
|
||||
options.fieldMetadataCollection,
|
||||
options.objectMetadataCollection,
|
||||
);
|
||||
const computedArgs = this.argsAliasFactory.create(
|
||||
args,
|
||||
|
||||
@ -18,6 +18,7 @@ export class DeleteManyQueryFactory {
|
||||
const fieldsString = await this.fieldsStringFactory.create(
|
||||
options.info,
|
||||
options.fieldMetadataCollection,
|
||||
options.objectMetadataCollection,
|
||||
);
|
||||
|
||||
return `
|
||||
|
||||
@ -18,6 +18,7 @@ export class DeleteOneQueryFactory {
|
||||
const fieldsString = await this.fieldsStringFactory.create(
|
||||
options.info,
|
||||
options.fieldMetadataCollection,
|
||||
options.objectMetadataCollection,
|
||||
);
|
||||
|
||||
return `
|
||||
|
||||
@ -5,6 +5,7 @@ import graphqlFields from 'graphql-fields';
|
||||
import isEmpty from 'lodash.isempty';
|
||||
|
||||
import { FieldMetadataInterface } from 'src/metadata/field-metadata/interfaces/field-metadata.interface';
|
||||
import { ObjectMetadataInterface } from 'src/metadata/field-metadata/interfaces/object-metadata.interface';
|
||||
|
||||
import { isRelationFieldMetadataType } from 'src/workspace/utils/is-relation-field-metadata-type.util';
|
||||
|
||||
@ -23,6 +24,7 @@ export class FieldsStringFactory {
|
||||
create(
|
||||
info: GraphQLResolveInfo,
|
||||
fieldMetadataCollection: FieldMetadataInterface[],
|
||||
objectMetadataCollection: ObjectMetadataInterface[],
|
||||
): Promise<string> {
|
||||
const selectedFields: Record<string, any> = graphqlFields(info);
|
||||
|
||||
@ -30,6 +32,7 @@ export class FieldsStringFactory {
|
||||
info,
|
||||
selectedFields,
|
||||
fieldMetadataCollection,
|
||||
objectMetadataCollection,
|
||||
);
|
||||
}
|
||||
|
||||
@ -37,6 +40,7 @@ export class FieldsStringFactory {
|
||||
info: GraphQLResolveInfo,
|
||||
selectedFields: Record<string, any>,
|
||||
fieldMetadataCollection: FieldMetadataInterface[],
|
||||
objectMetadataCollection: ObjectMetadataInterface[],
|
||||
accumulator = '',
|
||||
): Promise<string> {
|
||||
const fieldMetadataMap = new Map(
|
||||
@ -58,6 +62,7 @@ export class FieldsStringFactory {
|
||||
fieldKey,
|
||||
fieldValue,
|
||||
fieldMetadata,
|
||||
objectMetadataCollection,
|
||||
info,
|
||||
);
|
||||
|
||||
@ -84,6 +89,7 @@ export class FieldsStringFactory {
|
||||
info,
|
||||
fieldValue,
|
||||
fieldMetadataCollection,
|
||||
objectMetadataCollection,
|
||||
accumulator,
|
||||
);
|
||||
accumulator += `}\n`;
|
||||
|
||||
@ -29,6 +29,7 @@ export class FindManyQueryFactory {
|
||||
const fieldsString = await this.fieldsStringFactory.create(
|
||||
options.info,
|
||||
options.fieldMetadataCollection,
|
||||
options.objectMetadataCollection,
|
||||
);
|
||||
const argsString = this.argsStringFactory.create(
|
||||
args,
|
||||
|
||||
@ -23,6 +23,7 @@ export class FindOneQueryFactory {
|
||||
const fieldsString = await this.fieldsStringFactory.create(
|
||||
options.info,
|
||||
options.fieldMetadataCollection,
|
||||
options.objectMetadataCollection,
|
||||
);
|
||||
const argsString = this.argsStringFactory.create(
|
||||
args,
|
||||
|
||||
@ -3,6 +3,7 @@ import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { GraphQLResolveInfo } from 'graphql';
|
||||
|
||||
import { FieldMetadataInterface } from 'src/metadata/field-metadata/interfaces/field-metadata.interface';
|
||||
import { ObjectMetadataInterface } from 'src/metadata/field-metadata/interfaces/object-metadata.interface';
|
||||
|
||||
import { isRelationFieldMetadataType } from 'src/workspace/utils/is-relation-field-metadata-type.util';
|
||||
import { RelationMetadataType } from 'src/metadata/relation-metadata/relation-metadata.entity';
|
||||
@ -31,19 +32,27 @@ export class RelationFieldAliasFactory {
|
||||
fieldKey: string,
|
||||
fieldValue: any,
|
||||
fieldMetadata: FieldMetadataInterface,
|
||||
objectMetadataCollection: ObjectMetadataInterface[],
|
||||
info: GraphQLResolveInfo,
|
||||
): Promise<string> {
|
||||
if (!isRelationFieldMetadataType(fieldMetadata.type)) {
|
||||
throw new Error(`Field ${fieldMetadata.name} is not a relation field`);
|
||||
}
|
||||
|
||||
return this.createRelationAlias(fieldKey, fieldValue, fieldMetadata, info);
|
||||
return this.createRelationAlias(
|
||||
fieldKey,
|
||||
fieldValue,
|
||||
fieldMetadata,
|
||||
objectMetadataCollection,
|
||||
info,
|
||||
);
|
||||
}
|
||||
|
||||
private async createRelationAlias(
|
||||
fieldKey: string,
|
||||
fieldValue: any,
|
||||
fieldMetadata: FieldMetadataInterface,
|
||||
objectMetadataCollection: ObjectMetadataInterface[],
|
||||
info: GraphQLResolveInfo,
|
||||
): Promise<string> {
|
||||
const relationMetadata =
|
||||
@ -67,18 +76,13 @@ export class RelationFieldAliasFactory {
|
||||
);
|
||||
// Retrieve the referenced object metadata based on the relation direction
|
||||
// Mandatory to handle n+n relations
|
||||
const referencedObjectMetadata =
|
||||
await this.objectMetadataService.findOneWithinWorkspace(
|
||||
fieldMetadata.workspaceId,
|
||||
{
|
||||
where: {
|
||||
id:
|
||||
relationDirection == RelationDirection.TO
|
||||
? relationMetadata.fromObjectMetadataId
|
||||
: relationMetadata.toObjectMetadataId,
|
||||
},
|
||||
},
|
||||
);
|
||||
const referencedObjectMetadata = objectMetadataCollection.find(
|
||||
(objectMetadata) =>
|
||||
objectMetadata.id ===
|
||||
(relationDirection == RelationDirection.TO
|
||||
? relationMetadata.fromObjectMetadataId
|
||||
: relationMetadata.toObjectMetadataId),
|
||||
);
|
||||
|
||||
if (!referencedObjectMetadata) {
|
||||
throw new Error(
|
||||
@ -101,6 +105,7 @@ export class RelationFieldAliasFactory {
|
||||
info,
|
||||
fieldValue,
|
||||
referencedObjectMetadata.fields ?? [],
|
||||
objectMetadataCollection,
|
||||
);
|
||||
|
||||
return `
|
||||
@ -129,6 +134,7 @@ export class RelationFieldAliasFactory {
|
||||
info,
|
||||
fieldValue,
|
||||
referencedObjectMetadata.fields ?? [],
|
||||
objectMetadataCollection,
|
||||
);
|
||||
|
||||
// Otherwise it means it's a relation destination is of kind ONE
|
||||
|
||||
@ -28,6 +28,7 @@ export class UpdateManyQueryFactory {
|
||||
const fieldsString = await this.fieldsStringFactory.create(
|
||||
options.info,
|
||||
options.fieldMetadataCollection,
|
||||
options.objectMetadataCollection,
|
||||
);
|
||||
|
||||
const computedArgs = this.argsAliasFactory.create(
|
||||
|
||||
@ -25,6 +25,7 @@ export class UpdateOneQueryFactory {
|
||||
const fieldsString = await this.fieldsStringFactory.create(
|
||||
options.info,
|
||||
options.fieldMetadataCollection,
|
||||
options.objectMetadataCollection,
|
||||
);
|
||||
const computedArgs = this.argsAliasFactory.create(
|
||||
args,
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { GraphQLResolveInfo } from 'graphql';
|
||||
|
||||
import { FieldMetadataInterface } from 'src/metadata/field-metadata/interfaces/field-metadata.interface';
|
||||
import { ObjectMetadataInterface } from 'src/metadata/field-metadata/interfaces/object-metadata.interface';
|
||||
|
||||
export interface WorkspaceQueryBuilderOptions {
|
||||
targetTableName: string;
|
||||
info: GraphQLResolveInfo;
|
||||
fieldMetadataCollection: FieldMetadataInterface[];
|
||||
objectMetadataCollection: ObjectMetadataInterface[];
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { GraphQLResolveInfo } from 'graphql';
|
||||
|
||||
import { FieldMetadataInterface } from 'src/metadata/field-metadata/interfaces/field-metadata.interface';
|
||||
import { ObjectMetadataInterface } from 'src/metadata/field-metadata/interfaces/object-metadata.interface';
|
||||
|
||||
export interface WorkspaceQueryRunnerOptions {
|
||||
targetTableName: string;
|
||||
workspaceId: string;
|
||||
info: GraphQLResolveInfo;
|
||||
fieldMetadataCollection: FieldMetadataInterface[];
|
||||
objectMetadataCollection: ObjectMetadataInterface[];
|
||||
}
|
||||
|
||||
@ -64,11 +64,17 @@ export class WorkspaceQueryRunnerService {
|
||||
): Promise<IConnection<Record> | undefined> {
|
||||
try {
|
||||
const { workspaceId, targetTableName } = options;
|
||||
const start = performance.now();
|
||||
|
||||
const query = await this.workspaceQueryBuilderFactory.findMany(
|
||||
args,
|
||||
options,
|
||||
);
|
||||
|
||||
const result = await this.execute(query, workspaceId);
|
||||
const end = performance.now();
|
||||
|
||||
console.log(`query time: ${end - start} ms`);
|
||||
|
||||
return this.parseResult<IConnection<Record>>(result, targetTableName, '');
|
||||
} catch (exception) {
|
||||
|
||||
@ -30,6 +30,7 @@ export class CreateManyResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ export class CreateOneResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ export class DeleteManyResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ export class DeleteOneResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ export class ExecuteQuickActionOnOneResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ export class FindManyResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ export class FindOneResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ export class UpdateManyResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ export class UpdateOneResolverFactory
|
||||
workspaceId: internalContext.workspaceId,
|
||||
info,
|
||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -81,6 +81,7 @@ export class WorkspaceResolverFactory {
|
||||
workspaceId,
|
||||
targetTableName: objectMetadata.targetTableName,
|
||||
fieldMetadataCollection: objectMetadata.fields,
|
||||
objectMetadataCollection: objectMetadataCollection,
|
||||
});
|
||||
}
|
||||
|
||||
@ -103,6 +104,7 @@ export class WorkspaceResolverFactory {
|
||||
workspaceId,
|
||||
targetTableName: objectMetadata.targetTableName,
|
||||
fieldMetadataCollection: objectMetadata.fields,
|
||||
objectMetadataCollection: objectMetadataCollection,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { FieldMetadataInterface } from 'src/metadata/field-metadata/interfaces/field-metadata.interface';
|
||||
import { ObjectMetadataInterface } from 'src/metadata/field-metadata/interfaces/object-metadata.interface';
|
||||
|
||||
export interface WorkspaceSchemaBuilderContext {
|
||||
workspaceId: string;
|
||||
targetTableName: string;
|
||||
fieldMetadataCollection: FieldMetadataInterface[];
|
||||
objectMetadataCollection: ObjectMetadataInterface[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user