Added entities & transfomer for binary uuids

This commit is contained in:
Thom Werring 2024-03-24 14:28:17 +01:00
parent 7409f041c3
commit 500f4a88c9
5 changed files with 217 additions and 0 deletions

View File

@ -0,0 +1,37 @@
import { BaseEntity, Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
import { uuidTransformer } from '@/utils/uuidTransformer';
import { ShipmentEntity } from '@/entities/shipment.entity';
@Entity({
name: 'containers',
})
export class ContainerEntity extends BaseEntity {
@PrimaryColumn({
type: 'binary',
length: 16,
generated: false,
transformer: uuidTransformer,
default: () => '(UUID_TO_BIN(UUID()))',
})
id!: string;
@Column({
type: 'char',
length: 13,
})
containerNumber!: string;
@Column({
type: 'binary',
length: 16,
generated: false,
transformer: uuidTransformer,
})
shipmentId!: string;
@ManyToOne(
() => ShipmentEntity,
(shipment: ShipmentEntity) => shipment.containers,
)
shipment?: ShipmentEntity;
}

View File

@ -0,0 +1,50 @@
import {
BaseEntity,
Column,
Entity,
JoinColumn,
OneToOne,
PrimaryColumn,
} from 'typeorm';
import { uuidTransformer } from '@/utils/uuidTransformer';
import { ShipmentEntity } from '@/entities/shipment.entity';
@Entity({
name: 'live_tracking',
})
export class LiveTrackingEntity extends BaseEntity {
@PrimaryColumn({
type: 'binary',
length: 16,
generated: false,
transformer: uuidTransformer,
})
shipmentId!: string;
@Column({
type: 'datetime',
default: () => 'CURRENT_TIMESTAMP',
})
createdAt!: Date;
@Column({
type: 'decimal',
precision: 11,
scale: 7,
})
latitude!: number;
@Column({
type: 'decimal',
precision: 11,
scale: 7,
})
longitude!: number;
@OneToOne(
() => ShipmentEntity,
(shipment: ShipmentEntity) => shipment.liveTracking,
)
@JoinColumn()
shipment?: ShipmentEntity;
}

View File

@ -0,0 +1,77 @@
import {
BaseEntity,
Column,
Entity,
OneToMany,
OneToOne,
PrimaryColumn,
} from 'typeorm';
import { uuidTransformer } from '@/utils/uuidTransformer';
import { ContainerEntity } from '@/entities/container.entity';
import { LiveTrackingEntity } from '@/entities/liveTracking.entity';
@Entity({
name: 'shipments',
})
export class ShipmentEntity extends BaseEntity {
@PrimaryColumn({
type: 'binary',
length: 16,
generated: false,
transformer: uuidTransformer,
default: () => '(UUID_TO_BIN(UUID()))',
})
id!: string;
@Column({
type: 'datetime',
default: () => 'CURRENT_TIMESTAMP',
})
createdAt!: Date;
@Column({
type: 'varchar',
length: 255,
})
carrierName!: string;
@Column({
type: 'char',
length: 5,
})
originPort!: string;
@Column({
type: 'char',
length: 5,
})
destinationPort!: string;
@Column({
type: 'datetime',
})
departureDate!: Date;
@Column({
type: 'datetime',
})
arrivalDateOriginal!: Date;
@Column({
type: 'datetime',
})
arrivalDateEstimate!: Date;
@OneToMany(
() => ContainerEntity,
(container: ContainerEntity) => container.shipment,
)
containers?: ContainerEntity[];
@OneToOne(
() => LiveTrackingEntity,
(liveTracking: LiveTrackingEntity) => liveTracking.shipment,
{ eager: true },
)
liveTracking?: LiveTrackingEntity;
}

View File

@ -0,0 +1,27 @@
import { uuidTransformer } from '@/utils/uuidTransformer';
import { NIL } from 'uuid';
describe('uuidTransformer util', () => {
const transformer = uuidTransformer;
beforeEach(() => {});
it('Should have a to member', () => {
expect(transformer.to).toBeDefined();
});
it('Should have a from member', () => {
expect(transformer.from).toBeDefined();
});
it('From method should return a nil uuid if null is passed', () => {
expect(transformer.from(null)).toBe(NIL);
});
it('From method should return a nil uuid if empty 16 length buffer is passed', () => {
expect(transformer.from(Buffer.alloc(16))).toBe(NIL);
});
it('To method should return a buffer matching the uuid', () => {
expect(transformer.to(NIL)).toEqual(Buffer.alloc(16));
});
});

View File

@ -0,0 +1,26 @@
import { NIL, parse } from 'uuid';
// custom implementation of stringify, as provided uuid's are not valid according to RFC4122
const stringify = (buffer: Buffer | null): string => {
if (buffer === null) {
return NIL;
}
if (buffer.length != 16) {
throw new Error('Invalid buffer length for uuid: ' + buffer.length);
}
if (buffer.equals(Buffer.alloc(16))) {
return NIL; // If buffer is all zeros, return zero'd uuid
}
const hex = buffer.toString('hex');
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
};
export const uuidTransformer = {
to(uuid: string): Buffer {
return Buffer.from(parse(uuid));
},
from(bin: Buffer | null): string {
return stringify(bin);
},
};