Refactor tenant ORM integration (#1650)
* Refactor tenant ORM integration * fix tests
This commit is contained in:
@ -0,0 +1,7 @@
|
||||
export const baseColumns = {
|
||||
id: {
|
||||
primary: true,
|
||||
type: 'uuid',
|
||||
generated: 'uuid',
|
||||
},
|
||||
} as const;
|
||||
@ -0,0 +1,12 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { ObjectMetadataModule } from 'src/tenant/metadata/object-metadata/object-metadata.module';
|
||||
|
||||
import { EntitySchemaGeneratorService } from './entity-schema-generator.service';
|
||||
|
||||
@Module({
|
||||
imports: [ObjectMetadataModule],
|
||||
providers: [EntitySchemaGeneratorService],
|
||||
exports: [EntitySchemaGeneratorService],
|
||||
})
|
||||
export class EntitySchemaGeneratorModule {}
|
||||
@ -0,0 +1,29 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { ObjectMetadataService } from 'src/tenant/metadata/object-metadata/object-metadata.service';
|
||||
|
||||
import { EntitySchemaGeneratorService } from './entity-schema-generator.service';
|
||||
|
||||
describe('EntitySchemaGeneratorService', () => {
|
||||
let service: EntitySchemaGeneratorService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
EntitySchemaGeneratorService,
|
||||
{
|
||||
provide: ObjectMetadataService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<EntitySchemaGeneratorService>(
|
||||
EntitySchemaGeneratorService,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,43 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EntitySchema } from 'typeorm';
|
||||
|
||||
import { ObjectMetadataService } from 'src/tenant/metadata/object-metadata/object-metadata.service';
|
||||
|
||||
import { baseColumns } from './base.entity';
|
||||
import {
|
||||
convertFieldTypeToPostgresType,
|
||||
sanitizeColumnName,
|
||||
} from './entity-schema-generator.util';
|
||||
|
||||
@Injectable()
|
||||
export class EntitySchemaGeneratorService {
|
||||
constructor(private readonly objectMetadataService: ObjectMetadataService) {}
|
||||
|
||||
async getTypeORMEntitiesByDataSourceId(dataSourceId: string) {
|
||||
const objectMetadata =
|
||||
await this.objectMetadataService.getObjectMetadataFromDataSourceId(
|
||||
dataSourceId,
|
||||
);
|
||||
|
||||
const entities = objectMetadata.map((object) => {
|
||||
return new EntitySchema({
|
||||
name: object.name,
|
||||
columns: {
|
||||
...baseColumns,
|
||||
...object.fields.reduce((columns, field) => {
|
||||
return {
|
||||
...columns,
|
||||
[sanitizeColumnName(field.name)]: {
|
||||
type: convertFieldTypeToPostgresType(field.type),
|
||||
nullable: true,
|
||||
},
|
||||
};
|
||||
}, {}),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Converts a UUID to a base 36 string.
|
||||
* This is used to generate the schema name since hyphens from workspace uuid are not allowed in postgres schema names.
|
||||
*
|
||||
* @param uuid
|
||||
* @returns
|
||||
*/
|
||||
export const uuidToBase36 = (uuid: string): string => {
|
||||
const hexString = uuid.replace(/-/g, '');
|
||||
const base10Number = BigInt('0x' + hexString);
|
||||
const base36String = base10Number.toString(36);
|
||||
return base36String;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sanitizes a column name by replacing all non-alphanumeric characters with an underscore.
|
||||
* Note: Probablay not the best way to do this, leaving it here as a placeholder for now.
|
||||
*
|
||||
* @param columnName
|
||||
* @returns string
|
||||
*/
|
||||
export const sanitizeColumnName = (columnName: string): string =>
|
||||
columnName.replace(/[^a-zA-Z0-9]/g, '_');
|
||||
|
||||
/**
|
||||
* Converts a field type to a postgres type. Field types are defined in the UI.
|
||||
*
|
||||
* @param fieldType
|
||||
* @returns string
|
||||
*/
|
||||
export const convertFieldTypeToPostgresType = (fieldType: string): string => {
|
||||
switch (fieldType) {
|
||||
case 'text':
|
||||
return 'text';
|
||||
case 'url':
|
||||
return 'text';
|
||||
case 'number':
|
||||
return 'numeric';
|
||||
case 'boolean':
|
||||
return 'boolean';
|
||||
case 'date':
|
||||
return 'timestamp';
|
||||
default:
|
||||
return 'text';
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user