feat: implement unique identifier when searching to database

This commit is contained in:
Supan Adit Pratama 2024-11-02 09:41:20 +07:00
parent 606221dab3
commit b0088e4f63
13 changed files with 93 additions and 31 deletions

View File

@ -5,11 +5,12 @@ export class PrismaDeleteProcess
extends PrismaProcess extends PrismaProcess
implements DeleteProcess implements DeleteProcess
{ {
public identity; public identityData;
public identityKey: string = 'id';
async process() { async process() {
this.result = await this.getDelegate().delete({ this.result = await this.getDelegate().delete({
where: { id: this.identity }, where: { [this.identityKey]: this.identityData },
}); });
} }
} }

View File

@ -2,11 +2,12 @@ import { ReadProcess } from '@aditama-labs/nest-autocrud/skeleton';
import { PrismaProcess } from './prisma.process'; import { PrismaProcess } from './prisma.process';
export class PrismaReadProcess extends PrismaProcess implements ReadProcess { export class PrismaReadProcess extends PrismaProcess implements ReadProcess {
public identity; public identityData;
public identityKey: string = 'id';
async process() { async process() {
this.result = await this.getDelegate().findUnique({ this.result = await this.getDelegate().findUnique({
where: { id: this.identity }, where: { [this.identityKey]: this.identityData },
}); });
} }
} }

View File

@ -5,13 +5,14 @@ export class PrismaUpdateProcess
extends PrismaProcess extends PrismaProcess
implements UpdateProcess implements UpdateProcess
{ {
public identity; public identityData;
public identityKey: string = 'id';
public payload; public payload;
async process() { async process() {
this.result = await this.getDelegate().update({ this.result = await this.getDelegate().update({
data: this.payload, data: this.payload,
where: { id: this.identity }, where: { [this.identityKey]: this.identityData },
}); });
} }
} }

View File

@ -3,14 +3,23 @@ import { DefaultExecutor } from './default.executor';
// @TODO: ReadExecutor and DeleteExecutor can be merged into one executor // @TODO: ReadExecutor and DeleteExecutor can be merged into one executor
export class DeleteExecutor extends DefaultExecutor { export class DeleteExecutor extends DefaultExecutor {
constructor(process: DeleteProcess, id) { constructor(
process: DeleteProcess,
identityData,
identityKey: string = 'id',
) {
super(process); super(process);
// Set the id of the data // Set the id of the data
process.identity = id; process.identityData = identityData;
process.identityKey = identityKey;
} }
static async bootstrap(process: DeleteProcess, id) { static async bootstrap(
const executor = new DeleteExecutor(process, id); process: DeleteProcess,
identityData,
identityKey: string = 'id',
) {
const executor = new DeleteExecutor(process, identityData, identityKey);
await executor.execute(); await executor.execute();
return executor.getOutput(); return executor.getOutput();
} }

View File

@ -2,14 +2,19 @@ import { ReadProcess } from '../processes';
import { DefaultExecutor } from './default.executor'; import { DefaultExecutor } from './default.executor';
export class ReadExecutor extends DefaultExecutor { export class ReadExecutor extends DefaultExecutor {
constructor(process: ReadProcess, id) { constructor(process: ReadProcess, identityData, identityKey: string = 'id') {
super(process); super(process);
// Set the id of the data // Set the id of the data
process.identity = id; process.identityData = identityData;
process.identityKey = identityKey;
} }
static async bootstrap(process: ReadProcess, id) { static async bootstrap(
const executor = new ReadExecutor(process, id); process: ReadProcess,
identityData,
identityKey: string = 'id',
) {
const executor = new ReadExecutor(process, identityData, identityKey);
await executor.execute(); await executor.execute();
return executor.getOutput(); return executor.getOutput();
} }

View File

@ -3,15 +3,31 @@ import { DefaultExecutor } from './default.executor';
// @TODO: This executor should be able to extend from ReadExecutor and CreateExecutor // @TODO: This executor should be able to extend from ReadExecutor and CreateExecutor
export class UpdateExecutor extends DefaultExecutor { export class UpdateExecutor extends DefaultExecutor {
constructor(process: UpdateProcess, id, data) { constructor(
process: UpdateProcess,
identityData,
data,
identityKey: string = 'id',
) {
super(process); super(process);
// Set the id and data to process // Set the id and data to process
process.identity = id; process.identityData = identityData;
process.payload = data; process.payload = data;
process.identityKey = identityKey;
} }
static async bootstrap(process: UpdateProcess, id, data) { static async bootstrap(
const executor = new UpdateExecutor(process, id, data); process: UpdateProcess,
identityData,
data,
identityKey: string = 'id',
) {
const executor = new UpdateExecutor(
process,
identityData,
data,
identityKey,
);
await executor.execute(); await executor.execute();
return executor.getOutput(); return executor.getOutput();
} }

View File

@ -2,5 +2,6 @@ import { DefaultProcess } from './default.process';
// @TODO: DeleteProcess and ReadProcess are the same, should be refactored next // @TODO: DeleteProcess and ReadProcess are the same, should be refactored next
export class DeleteProcess extends DefaultProcess { export class DeleteProcess extends DefaultProcess {
public identity; public identityData;
public identityKey: string = 'id';
} }

View File

@ -1,5 +1,6 @@
import { DefaultProcess } from './default.process'; import { DefaultProcess } from './default.process';
export class ReadProcess extends DefaultProcess { export class ReadProcess extends DefaultProcess {
public identity; public identityData;
public identityKey: string = 'id';
} }

View File

@ -2,7 +2,8 @@ import { DefaultProcess } from './default.process';
export class UpdateProcess extends DefaultProcess { export class UpdateProcess extends DefaultProcess {
// @TODO: The property of id can be take from ReadProcess which is extended // @TODO: The property of id can be take from ReadProcess which is extended
public identity; public identityData;
public identityKey: string = 'id';
// @TODO: The property of data can be take from CreateProcess which is extended // @TODO: The property of data can be take from CreateProcess which is extended
public payload; public payload;
} }

View File

@ -95,8 +95,12 @@ export const CustomCRUDController = (options?: ControllerOption) => {
} }
@Delete(`:${uniqueIdentifier}`) @Delete(`:${uniqueIdentifier}`)
async delete(@Param(uniqueIdentifier) id) { async delete(@Param(uniqueIdentifier) identityData) {
return await super.delete(id); return await DeleteExecutor.bootstrap(
this.deleteProcess,
identityData,
uniqueIdentifier,
);
} }
@Get('list') @Get('list')
@ -111,13 +115,22 @@ export const CustomCRUDController = (options?: ControllerOption) => {
} }
@Get(`:${uniqueIdentifier}`) @Get(`:${uniqueIdentifier}`)
async read(@Param(uniqueIdentifier) id) { async read(@Param(uniqueIdentifier) identityData) {
return await super.read(id); return await ReadExecutor.bootstrap(
this.readProcess,
identityData,
uniqueIdentifier,
);
} }
@Patch(`:${uniqueIdentifier}`) @Patch(`:${uniqueIdentifier}`)
async update(@Param(uniqueIdentifier) id, @Body() body) { async update(@Param(uniqueIdentifier) identityData, @Body() body) {
return await super.update(id, body); return await UpdateExecutor.bootstrap(
this.updateProcess,
identityData,
body,
uniqueIdentifier,
);
} }
} }

View File

@ -0,0 +1,12 @@
/*
Warnings:
- A unique constraint covering the columns `[username]` on the table `account` will be added. If there are existing duplicate values, this will fail.
- Added the required column `username` to the `account` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "account" ADD COLUMN "username" TEXT NOT NULL;
-- CreateIndex
CREATE UNIQUE INDEX "account_username_key" ON "account"("username");

View File

@ -17,6 +17,7 @@ datasource db {
model User { model User {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
username String @unique
name String name String
Todo Todo[] Todo Todo[]

View File

@ -4,7 +4,7 @@ export class CustomReadProcess extends PrismaReadProcess {
customResult; customResult;
async before(): Promise<any> { async before(): Promise<any> {
console.log('The ID requested in path parameter', this.identity); console.log('The ID requested in path parameter', this.identityData);
} }
async after(): Promise<any> { async after(): Promise<any> {
this.customResult = { this.customResult = {