-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
43f8b95
commit e5b71b6
Showing
6 changed files
with
152 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"typescript.tsdk": "node_modules/typescript/lib" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,92 @@ | ||
/** | ||
* A registry of metadata for classes decorated with the @Entity decorator. | ||
* The metadata is stored as a Map where the key is the class constructor and | ||
* The metadata is stored as a Map where the key is the class constructor and | ||
* the value is an object with the following properties: | ||
* - columns: an object where the keys are property keys and the values are objects with column options | ||
* - primaryKey: the property key of the primary key column | ||
* @type {Map<Function, any>} | ||
*/ | ||
export const metadataRegistry = new Map<Function, any>(); | ||
export const metadataRegistry = new Map<Function, any>() | ||
|
||
export function Column(options?: { | ||
unique?: boolean, | ||
primary?: boolean, | ||
nullable?: boolean, | ||
name?: string, | ||
export function Column(options?: { | ||
unique?: boolean | ||
primary?: boolean | ||
nullable?: boolean | ||
name?: string | ||
relation?: any | ||
}): PropertyDecorator { | ||
return function(target: any, propertyKey: string | symbol): void { | ||
const constructor = target.constructor; | ||
return function (target: any, propertyKey: string | symbol): void { | ||
const constructor = target.constructor | ||
if (!metadataRegistry.has(constructor)) { | ||
metadataRegistry.set(constructor, { columns: {}, primaryKey: undefined }); | ||
metadataRegistry.set(constructor, { | ||
columns: {}, | ||
primaryKey: undefined, | ||
}) | ||
} | ||
|
||
const classMetadata = metadataRegistry.get(constructor); | ||
const classMetadata = metadataRegistry.get(constructor) | ||
|
||
const columnName = options?.name || propertyKey.toString(); | ||
const relationName = options?.relation || propertyKey.toString(); | ||
const columnName = options?.name || propertyKey.toString() | ||
const relationName = options?.relation || propertyKey.toString() | ||
|
||
// Initialize the column metadata if it doesn't exist | ||
if (!classMetadata.columns[propertyKey]) { | ||
classMetadata.columns[propertyKey] = {}; | ||
classMetadata.columns[propertyKey] = {} | ||
} | ||
|
||
// Update the column metadata with new options | ||
classMetadata.columns[propertyKey] = { | ||
...classMetadata.columns[propertyKey], | ||
...options, | ||
name: columnName, | ||
relation: relationName | ||
}; | ||
relation: relationName, | ||
} | ||
|
||
if (options?.primary) { | ||
if (classMetadata.primaryKey) { | ||
throw new Error(`Multiple primary keys are not allowed: ${constructor.name} already has a primary key on property '${String(classMetadata.primaryKey)}'.`); | ||
throw new Error( | ||
`Multiple primary keys are not allowed: ${constructor.name} already has a primary key on property '${String(classMetadata.primaryKey)}'.` | ||
) | ||
} | ||
classMetadata.primaryKey = propertyKey; | ||
classMetadata.primaryKey = propertyKey | ||
} | ||
}; | ||
} | ||
} | ||
|
||
export function isColumn(targetClass: Function, propertyName: string): boolean { | ||
const metadata = metadataRegistry.get(targetClass); | ||
return metadata && metadata.columns[propertyName]; | ||
const metadata = metadataRegistry.get(targetClass) | ||
return metadata && metadata.columns[propertyName] | ||
} | ||
|
||
export function isPropertyUnique(targetClass: Function, propertyName: string): boolean { | ||
const metadata = metadataRegistry.get(targetClass); | ||
export function isPropertyUnique( | ||
targetClass: Function, | ||
propertyName: string | ||
): boolean { | ||
const metadata = metadataRegistry.get(targetClass) | ||
return metadata && metadata[propertyName] && metadata[propertyName].unique | ||
} | ||
|
||
export function isColumnNullable(targetClass: Function, propertyName: string): boolean { | ||
const metadata = metadataRegistry.get(targetClass); | ||
if (metadata && metadata.columns[propertyName] && metadata.columns[propertyName].hasOwnProperty('nullable')) { | ||
return metadata.columns[propertyName].nullable; | ||
export function isColumnNullable( | ||
targetClass: Function, | ||
propertyName: string | ||
): boolean { | ||
const metadata = metadataRegistry.get(targetClass) | ||
if ( | ||
metadata && | ||
metadata.columns[propertyName] && | ||
metadata.columns[propertyName].hasOwnProperty('nullable') | ||
) { | ||
return metadata.columns[propertyName].nullable | ||
} | ||
return false; | ||
return false | ||
} | ||
|
||
export function getPrimaryKey(targetClass: Function): string | symbol | undefined { | ||
const metadata = metadataRegistry.get(targetClass); | ||
export function getPrimaryKey( | ||
targetClass: Function | ||
): string | symbol | undefined { | ||
const metadata = metadataRegistry.get(targetClass) | ||
if (metadata) { | ||
return metadata.primaryKey; | ||
return metadata.primaryKey | ||
} | ||
return undefined; | ||
} | ||
return undefined | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { describe, expect, it } from '@jest/globals' | ||
import { | ||
metadataRegistry, | ||
Column, | ||
isColumn, | ||
isPropertyUnique, | ||
isColumnNullable, | ||
getPrimaryKey, | ||
} from '../../src/models/decorators' // Adjust the path as necessary | ||
|
||
class TestEntity { | ||
@Column({ primary: true }) | ||
id: number | ||
|
||
@Column({ unique: true, nullable: false }) | ||
uniqueColumn: string | ||
|
||
@Column({ nullable: true }) | ||
nullableColumn: string | ||
|
||
@Column() | ||
regularColumn: string | ||
} | ||
|
||
describe('metadataRegistry', () => { | ||
it('should register primary key column', () => { | ||
expect(getPrimaryKey(TestEntity)).toBe('id') | ||
}) | ||
|
||
it('should register columns with correct metadata', () => { | ||
const metadata = metadataRegistry.get(TestEntity) | ||
expect(metadata).toBeDefined() | ||
expect(metadata.columns).toHaveProperty('id') | ||
expect(metadata.columns.id).toHaveProperty('primary', true) | ||
expect(metadata.columns.id).toHaveProperty('name', 'id') | ||
expect(metadata.columns).toHaveProperty('uniqueColumn') | ||
expect(metadata.columns.uniqueColumn).toHaveProperty('unique', true) | ||
expect(metadata.columns.uniqueColumn).toHaveProperty('nullable', false) | ||
expect(metadata.columns).toHaveProperty('nullableColumn') | ||
expect(metadata.columns.nullableColumn).toHaveProperty('nullable', true) | ||
expect(metadata.columns).toHaveProperty('regularColumn') | ||
}) | ||
|
||
it('should detect if a property is a column', () => { | ||
expect(isColumn(TestEntity, 'id')).toBe(true) | ||
expect(isColumn(TestEntity, 'uniqueColumn')).toBe(true) | ||
expect(isColumn(TestEntity, 'nullableColumn')).toBe(true) | ||
expect(isColumn(TestEntity, 'regularColumn')).toBe(true) | ||
expect(isColumn(TestEntity, 'nonExistentColumn')).toBe(false) | ||
}) | ||
|
||
it('should detect if a column is unique', () => { | ||
expect(isPropertyUnique(TestEntity, 'uniqueColumn')).toBe(true) | ||
expect(isPropertyUnique(TestEntity, 'nullableColumn')).toBe(false) | ||
expect(isPropertyUnique(TestEntity, 'regularColumn')).toBe(false) | ||
}) | ||
|
||
it('should detect if a column is nullable', () => { | ||
expect(isColumnNullable(TestEntity, 'nullableColumn')).toBe(true) | ||
expect(isColumnNullable(TestEntity, 'uniqueColumn')).toBe(false) | ||
expect(isColumnNullable(TestEntity, 'regularColumn')).toBe(false) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { describe, expect, it } from '@jest/globals' | ||
import { BaseTable } from '../../src/models/index' // Adjust the path as necessary | ||
|
||
describe('BaseTable class', () => { | ||
it('should create an instance with a name and schema', () => { | ||
const name = 'testTable' | ||
const schema = 'testSchema' | ||
const baseTable = new BaseTable({ _name: name, _schema: schema }) | ||
|
||
expect(baseTable).toBeInstanceOf(BaseTable) | ||
expect(baseTable._name).toBe(name) | ||
expect(baseTable._schema).toBe(schema) | ||
}) | ||
|
||
it('should create an instance with only a name', () => { | ||
const name = 'testTable' | ||
const baseTable = new BaseTable({ _name: name }) | ||
|
||
expect(baseTable).toBeInstanceOf(BaseTable) | ||
expect(baseTable._name).toBe(name) | ||
expect(baseTable._schema).toBeUndefined() | ||
}) | ||
|
||
it('should handle missing schema parameter', () => { | ||
const name = 'testTable' | ||
const baseTable = new BaseTable({ _name: name }) | ||
|
||
expect(baseTable._name).toBe(name) | ||
expect(baseTable._schema).toBeUndefined() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters