@cyber-rom/nestjs-scylladb
Version:
Based on https://www.npmjs.com/package/@ouato/nestjs-express-cassandra With support columns name mapping
149 lines (128 loc) • 4.93 kB
text/typescript
import 'reflect-metadata';
import {Logger} from '@nestjs/common';
import {mergeDeep} from './deep-merge.utils';
import {
OPTIONS_KEY,
ATTRIBUTE_KEY,
ENTITY_NAME_KEY,
ENTITY_METADATA,
COLUMNS_MAPPER_KEY,
PROPERTIES_MAPPER_KEY,
} from '../orm.constant';
export function setEntity(target: any, entity: Function): void {
Reflect.defineMetadata(ENTITY_METADATA, entity, target);
}
export function getEntity(target: any): Function {
return Reflect.getMetadata(ENTITY_METADATA, target);
}
export function setEntityName(target: any, modelName: string): void {
Reflect.defineMetadata(ENTITY_NAME_KEY, modelName, target);
}
export function getEntityName(target: any): string {
return Reflect.getMetadata(ENTITY_NAME_KEY, target);
}
export function getAttributes(target: any): any | undefined {
const attributes = Reflect.getMetadata(ATTRIBUTE_KEY, target);
if (attributes) {
return Object.keys(attributes).reduce((copy, key) => {
copy[key] = {...attributes[key]};
return copy;
}, {});
}
}
export function setAttributes(target: any, attributes: any) {
Reflect.defineMetadata(ATTRIBUTE_KEY, {...attributes}, target);
}
export function getColumnsMapper(target: any) {
return Reflect.getMetadata(COLUMNS_MAPPER_KEY, target) || {};
}
export function getPropertiesMapper(target: any) {
return Reflect.getMetadata(PROPERTIES_MAPPER_KEY, target) || {};
}
export function getColumnName(target: any, propertyName: string, def?: string) {
const mapper = getColumnsMapper(target);
if (propertyName in mapper) {
return mapper[propertyName];
}
return def || propertyName;
}
export function getPropertyName(target: any, columnName: string, def?: string) {
const mapper = getPropertiesMapper(target);
if (columnName in mapper) {
return mapper[columnName];
}
return def || columnName;
}
export function setColumnMapping(target: any, propertyName: string, columnName: string) {
if (!propertyName || !columnName || propertyName === columnName) {
return;
}
const mapper = getColumnsMapper(target);
if (propertyName in mapper && mapper[propertyName]) {
Logger.warn(`Columns mapper already constrain propertyName "${propertyName}"`, undefined, 'ScyllaModule');
}
Reflect.defineMetadata(
COLUMNS_MAPPER_KEY,
{
...mapper,
[propertyName]: columnName,
},
target,
);
}
export function setPropertyMapping(target: any, propertyName: string, columnName: string) {
if (!propertyName || !columnName || propertyName === columnName) {
return;
}
const mapper = getPropertiesMapper(target);
if (columnName in mapper && mapper[propertyName]) {
Logger.warn(`Columns mapper already constrain columnName "${columnName}"`, undefined, 'ScyllaModule');
}
Reflect.defineMetadata(
PROPERTIES_MAPPER_KEY,
{
...mapper,
[columnName]: propertyName,
},
target,
);
}
export function setTransformMapping(target: any, propertyName: string, columnName: string) {
setPropertyMapping(target, propertyName, columnName);
setColumnMapping(target, propertyName, columnName);
}
export function hasAttribute(target: any, propertyName: string): boolean {
const attributes = getAttributes(target),
columnName = getColumnName(target, propertyName);
return attributes && columnName in attributes && attributes[columnName];
}
export function addAttribute(target: any, propertyName: string, {name, ...options}: any): void {
const attributes = getAttributes(target) || {};
if (name) {
setTransformMapping(target, propertyName, name);
}
setAttributes(target, {...attributes, [name || propertyName]: {...(options || {})}});
}
export function addAttributeOptions(target: any, propertyName: string, {name, ...options}: any): void {
const attributes = getAttributes(target) || {};
const columnName = getColumnName(target, propertyName, name);
if (columnName in attributes) {
attributes[columnName] = mergeDeep(attributes[columnName], options);
} else {
attributes[columnName] = options;
}
setAttributes(target, attributes);
}
export function getOptions(target: any): any | undefined {
return {...(Reflect.getMetadata(OPTIONS_KEY, target) || {})};
}
export function setOptions(target: any, options: any): void {
Reflect.defineMetadata(OPTIONS_KEY, {...options}, target);
}
export function addOptions(target: any, options: any): void {
setOptions(target, mergeDeep(getOptions(target) || {}, options));
}
export const addHookFunction = (target: object, metadataKey: string) => {
const funcLikeArray: any[] = Reflect.getMetadata(metadataKey, target) || [];
return (...args: any[]) => funcLikeArray.map((funcLike) => funcLike(...args));
};