Skip to content

Commit

Permalink
Evolve example providers to be a little bit type safer.
Browse files Browse the repository at this point in the history
  • Loading branch information
samchon committed Oct 13, 2023
1 parent afccc51 commit d85779d
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 73 deletions.
10 changes: 5 additions & 5 deletions src/api/structures/common/IRecordMerge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { tags } from "typia";
*
* `IRecordMerge` is a structure for merging records.
*
* The `merge` means that merging multiple {@link IRecordMerge.merged}
* The `merge` means that merging multiple {@link IRecordMerge.absorbed}
* records into {@link IRecordMerge.keep} instead of deleting
* {@link IRecordMerge.merged} records.
* {@link IRecordMerge.absorbed} records.
*
* If there're some dependent tables of the target `table` having
* unique constraint on foriegn key column, such dependent tables
Expand All @@ -24,13 +24,13 @@ export interface IRecordMerge {
/**
* Target record to keep after merging.
*
* After merge process, {@link merged} records would be merged into
* After merge process, {@link absorbed} records would be merged into
* this {@link keep} record.
*/
keep: string & tags.Format<"uuid">;

/**
* To be merged to {@link keep} after merging.
* To be absorbed to {@link keep} after merging.
*/
merged: Array<string & tags.Format<"uuid">>;
absorbed: Array<string & tags.Format<"uuid">>;
}
9 changes: 3 additions & 6 deletions src/providers/common/AttachmentFileProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,12 @@ export namespace AttachmentFileProvider {
Prisma.validator<Prisma.attachment_filesFindManyArgs>()({});
}

export function collect(
input: IAttachmentFile.IStore,
): Prisma.attachment_filesCreateInput {
return {
export const collect = (input: IAttachmentFile.IStore) =>
Prisma.validator<Prisma.attachment_filesCreateInput>()({
id: v4(),
name: input.name,
extension: input.extension,
url: input.url,
created_at: new Date(),
};
}
});
}
39 changes: 20 additions & 19 deletions src/providers/common/BbsArticleCommentSnapshotProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export namespace BbsArticleCommentSnapshotProvider {
id: input.id,
format: input.format as any,
body: input.body,
files: input.files
files: input.to_files
.sort((a, b) => a.sequence - b.sequence)
.map((p) => AttachmentFileProvider.json.transform(p.file)),
created_at: input.created_at.toISOString(),
Expand All @@ -26,7 +26,7 @@ export namespace BbsArticleCommentSnapshotProvider {
Prisma.validator<Prisma.bbs_article_comment_snapshotsFindManyArgs>()(
{
include: {
files: {
to_files: {
include: {
file: AttachmentFileProvider.json.select(),
},
Expand All @@ -52,21 +52,22 @@ export namespace BbsArticleCommentSnapshotProvider {
return json.transform(snapshot);
};

export const collect = (
input: IBbsArticleComment.IStore,
): Omit<Prisma.bbs_article_comment_snapshotsCreateInput, "comment"> => ({
id: v4(),
format: input.format,
body: input.body,
created_at: new Date(),
files: {
create: input.files.map((file, i) => ({
id: v4(),
file: {
create: AttachmentFileProvider.collect(file),
},
sequence: i,
})),
},
});
export const collect = (input: IBbsArticleComment.IStore) =>
Prisma.validator<
Omit<Prisma.bbs_article_comment_snapshotsCreateInput, "comment">
>()({
id: v4(),
format: input.format,
body: input.body,
created_at: new Date(),
to_files: {
create: input.files.map((file, i) => ({
id: v4(),
file: {
create: AttachmentFileProvider.collect(file),
},
sequence: i,
})),
},
});
}
22 changes: 13 additions & 9 deletions src/providers/common/BbsArticleProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export namespace BbsArticleProvider {
format: input.mv_last!.snapshot.format as IBbsArticle.Format,
created_at: input.created_at.toISOString(),
updated_at: input.mv_last!.snapshot.created_at.toISOString(),
files: input.mv_last!.snapshot.files.map((p) =>
files: input.mv_last!.snapshot.to_files.map((p) =>
AttachmentFileProvider.json.transform(p.file),
),
});
Expand All @@ -47,7 +47,7 @@ export namespace BbsArticleProvider {
include: {
snapshot: {
include: {
files: {
to_files: {
include: {
file: AttachmentFileProvider.json.select(),
},
Expand Down Expand Up @@ -99,14 +99,18 @@ export namespace BbsArticleProvider {
: null;

export const collect =
<Input extends IBbsArticle.IStore>(
snapshotFactory: (
input: Input,
) => Omit<Prisma.bbs_article_snapshotsCreateInput, "article">,
<
Input extends IBbsArticle.IStore,
Snapshot extends Omit<
Prisma.bbs_article_snapshotsCreateInput,
"article"
>,
>(
snapshotFactory: (input: Input) => Snapshot,
) =>
(input: Input): Prisma.bbs_articlesCreateInput => {
(input: Input) => {
const snapshot = snapshotFactory(input);
return {
return Prisma.validator<Prisma.bbs_articlesCreateInput>()({
id: v4(),
snapshots: {
create: [snapshot],
Expand All @@ -118,6 +122,6 @@ export namespace BbsArticleProvider {
snapshot: { connect: { id: snapshot.id } },
},
},
};
});
};
}
41 changes: 21 additions & 20 deletions src/providers/common/BbsArticleSnapshotProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ export namespace BbsArticleSnapshotProvider {
title: input.title,
format: input.format as any,
body: input.body,
files: input.files
files: input.to_files
.sort((a, b) => a.sequence - b.sequence)
.map((p) => AttachmentFileProvider.json.transform(p.file)),
created_at: input.created_at.toISOString(),
});
export const select = () =>
Prisma.validator<Prisma.bbs_article_snapshotsFindManyArgs>()({
include: {
files: {
to_files: {
include: {
file: AttachmentFileProvider.json.select(),
},
Expand Down Expand Up @@ -56,22 +56,23 @@ export namespace BbsArticleSnapshotProvider {
return json.transform(snapshot);
};

export const collect = (
input: IBbsArticle.IStore,
): Omit<Prisma.bbs_article_snapshotsCreateInput, "article"> => ({
id: v4(),
title: input.title,
format: input.format,
body: input.body,
created_at: new Date(),
files: {
create: input.files.map((file, i) => ({
id: v4(),
file: {
create: AttachmentFileProvider.collect(file),
},
sequence: i,
})),
},
});
export const collect = (input: IBbsArticle.IStore) =>
Prisma.validator<
Omit<Prisma.bbs_article_snapshotsCreateInput, "article">
>()({
id: v4(),
title: input.title,
format: input.format,
body: input.body,
created_at: new Date(),
to_files: {
create: input.files.map((file, i) => ({
id: v4(),
file: {
create: AttachmentFileProvider.collect(file),
},
sequence: i,
})),
},
});
}
6 changes: 4 additions & 2 deletions src/providers/common/EntityMergeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ export namespace EntityMergeProvider {
? await finder(input)
: await (SGlobal.prisma[table] as any).count({
where: {
[primary.name]: { in: [input.keep, ...input.merged] },
[primary.name]: {
in: [input.keep, ...input.absorbed],
},
},
});
if (count !== input.merged.length + 1)
if (count !== input.absorbed.length + 1)
throw new nest.NotFoundException(
"Unable to find matched record(s).",
);
Expand Down
4 changes: 2 additions & 2 deletions src/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ model bbs_article_snapshots {
article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)
/// List of wrappers of attachment files.
files bbs_article_snapshot_files[]
to_files bbs_article_snapshot_files[]
mv_last mv_bbs_article_last_snapshots?
Expand Down Expand Up @@ -336,7 +336,7 @@ model bbs_article_comment_snapshots {
comment bbs_article_comments @relation(fields: [bbs_article_comment_id], references: [id], onDelete: Cascade)
/// List of wrappers of attachment files.
files bbs_article_comment_snapshot_files[]
to_files bbs_article_comment_snapshot_files[]
@@index([bbs_article_comment_id, created_at])
}
Expand Down
22 changes: 12 additions & 10 deletions src/utils/EntityUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ export namespace EntityUtil {
/**
* Target record to keep after merging.
*
* After merge process, {@link merged} records would be merged into
* After merge process, {@link absorbed} records would be merged into
* this {@link keep} record.
*/
keep: Key;

/**
* To be merged to {@link keep} after merging.
* To be absorbed to the {@link keep} record after merging.
*/
merged: Key[];
absorbed: Key[];
}

/**
* Merge multiple records into one.
*
* Merge multiple {@link IMergeProps.merged} records into
* Merge multiple {@link IMergeProps.absorbed} records into
* {@link IMergeProps.keep} record, instead of deleting them.
*
* If there're some dependent tables of the target `table` having
Expand Down Expand Up @@ -112,7 +112,7 @@ export namespace EntityUtil {
else
await (client[table] as any).updateMany({
where: {
[foreign.name]: { in: props.merged },
[foreign.name]: { in: props.absorbed },
},
data: {
[foreign.name]: props.keep,
Expand All @@ -123,7 +123,7 @@ export namespace EntityUtil {
// REMOVE TO BE MERGED RECORD
await (client[table] as any).deleteMany({
where: {
[key.name]: { in: props.merged },
[key.name]: { in: props.absorbed },
},
});
};
Expand Down Expand Up @@ -156,7 +156,9 @@ export namespace EntityUtil {
primary.dbName
} AS VARCHAR(36))) AS UUID) AS ${primary.dbName}
FROM ${current.model.dbName}
WHERE ${current.foreign.dbName} IN ($1, ${parent.merged
WHERE ${
current.foreign.dbName
} IN ($1, ${parent.absorbed
.map((_, index) => `$${index + 2}`)
.join(", ")})
GROUP BY ${group.join(", ")}
Expand All @@ -166,7 +168,7 @@ export namespace EntityUtil {
)`;
await client.$executeRawUnsafe(sql, [
parent.keep,
...parent.merged,
...parent.absorbed,
]);
}

Expand All @@ -179,7 +181,7 @@ export namespace EntityUtil {
].findMany({
where: {
[current.foreign.name]: {
in: [parent.keep, ...parent.merged],
in: [parent.keep, ...parent.absorbed],
},
},
orderBy: [
Expand All @@ -203,7 +205,7 @@ export namespace EntityUtil {

await merge(client)(current.model.name as Prisma.ModelName)({
keep: master[primary.name],
merged: slaves.map((slave) => slave[primary.name]),
absorbed: slaves.map((slave) => slave[primary.name]),
});
}
};
Expand Down

0 comments on commit d85779d

Please sign in to comment.