Merged PR 626: Revert 'deleteでコメントを追加できるようにする'

## 概要
[Task3289: deleteでコメントを追加できるようにする](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3289)

delete処理にSQLコメントを挿入する形にリファクタ
レビューポイント
repository/* に存在するdelete文は全て置き換えたはずだが、漏れはなさそうか

Reverts !622
This commit is contained in:
maruyama.t 2023-12-12 09:45:30 +00:00
parent 6c6970c70a
commit 934ee7f44d
7 changed files with 78 additions and 302 deletions

View File

@ -1,128 +0,0 @@
import {
ObjectLiteral,
Repository,
EntityTarget,
UpdateResult,
DeleteResult,
UpdateQueryBuilder,
Brackets,
FindOptionsWhere,
} from 'typeorm';
import { Context } from '../log';
/**
* VS Code上で型解析エラーが発生するためtypeorm内の型定義と同一の型定義をここに記述する
*/
type QueryDeepPartialEntity<T> = _QueryDeepPartialEntity<
ObjectLiteral extends T ? unknown : T
>;
type _QueryDeepPartialEntity<T> = {
[P in keyof T]?:
| (T[P] extends Array<infer U>
? Array<_QueryDeepPartialEntity<U>>
: T[P] extends ReadonlyArray<infer U>
? ReadonlyArray<_QueryDeepPartialEntity<U>>
: _QueryDeepPartialEntity<T[P]>)
| (() => string);
};
const insertEntity = async <T extends ObjectLiteral>(
entity: EntityTarget<T>,
repository: Repository<T>,
value: QueryDeepPartialEntity<T>,
isCommentOut: boolean,
// context: Context,
): Promise<T> => {
let query = repository.createQueryBuilder().insert().into(entity);
if (isCommentOut) {
query = query.comment(
`context.getTrackingId()_${new Date().toUTCString()}`,
);
}
const result = await query.values(value).execute();
// 結果をもとにセレクトする
const inserted = await repository.findOne({
where: { id: result.identifiers[0].id },
});
if (!inserted) {
throw new Error('Failed to insert entity');
}
return inserted;
};
const insertEntities = async <T extends ObjectLiteral>(
entity: EntityTarget<T>,
repository: Repository<T>,
values: QueryDeepPartialEntity<T>[],
isCommentOut: boolean,
// context: Context,
): Promise<T[]> => {
let query = repository.createQueryBuilder().insert().into(entity);
if (isCommentOut) {
query = query.comment(
`context.getTrackingId()_${new Date().toUTCString()}`,
);
}
const result = await query.values(values).execute();
// 挿入するレコードが0で、結果も0であれば、からの配列を返す
if (values.length === 0 && result.identifiers.length === 0) {
return [];
}
// 挿入するレコード数と挿入されたレコード数が一致しない場合はエラー
if (result.identifiers.length !== values.length) {
throw new Error('Failed to insert entities');
}
const where: FindOptionsWhere<T>[] = result.identifiers.map((i) => {
return { id: i.id };
});
// 結果をもとにセレクトする
const inserted = await repository.find({
where,
});
if (!inserted) {
throw new Error('Failed to insert entity');
}
return inserted;
};
const updateEntity = async <T extends ObjectLiteral>(
repository: Repository<T>,
criteria:
| string
| ((qb: UpdateQueryBuilder<T>) => string)
| Brackets
| ObjectLiteral
| ObjectLiteral[],
values: QueryDeepPartialEntity<T>,
isCommentOut: boolean,
// context: Context,
): Promise<UpdateResult> => {
let query = repository.createQueryBuilder().update();
if (isCommentOut) {
query = query.comment(
`context.getTrackingId()_${new Date().toUTCString()}`,
);
}
return await query.set(values).where(criteria).execute();
};
const deleteEntity = async <T extends ObjectLiteral>(
repository: Repository<T>,
criteria: string | Brackets | ObjectLiteral | ObjectLiteral[],
isCommentOut: boolean,
// context: Context,
): Promise<DeleteResult> => {
let query = repository.createQueryBuilder().delete();
if (isCommentOut) {
query = query.comment(
`context.getTrackingId()_${new Date().toUTCString()}`,
);
}
return await query.where(criteria).execute();
};
export { insertEntity, insertEntities, updateEntity, deleteEntity };

View File

@ -57,12 +57,11 @@ import { AudioOptionItem } from '../audio_option_items/entity/audio_option_item.
import { UserGroup } from '../user_groups/entity/user_group.entity';
import { UserGroupMember } from '../user_groups/entity/user_group_member.entity';
import { TemplateFile } from '../template_files/entity/template_file.entity';
import { deleteEntity } from '../../common/repository';
@Injectable()
export class AccountsRepositoryService {
constructor(private dataSource: DataSource) {}
// クエリログにコメントを出力するかどうか
private readonly isCommentOut = process.env.STAGE !== 'local';
/**
*
* @param companyName
@ -197,15 +196,13 @@ export class AccountsRepositoryService {
const usersRepo = entityManager.getRepository(User);
const sortCriteriaRepo = entityManager.getRepository(SortCriteria);
// ソート条件を削除
await deleteEntity(
sortCriteriaRepo,
{ user_id: userId },
this.isCommentOut,
);
await sortCriteriaRepo.delete({
user_id: userId,
});
// プライマリ管理者を削除
await deleteEntity(usersRepo, { id: userId }, this.isCommentOut);
await usersRepo.delete({ id: userId });
// アカウントを削除
await deleteEntity(accountsRepo, { id: accountId }, this.isCommentOut);
await accountsRepo.delete({ id: accountId });
});
}
@ -744,11 +741,7 @@ export class AccountsRepositoryService {
},
);
// 発行時に発行されたライセンスを削除する
await deleteEntity(
licenseRepo,
{ order_id: targetOrder.id },
this.isCommentOut,
);
await licenseRepo.delete({ order_id: targetOrder.id });
});
}
@ -1024,14 +1017,13 @@ export class AccountsRepositoryService {
// アカウントを削除
const accountRepo = entityManager.getRepository(Account);
await deleteEntity(accountRepo, { id: accountId }, this.isCommentOut);
await accountRepo.delete({ id: accountId });
// ライセンス系(card_license_issue以外)のテーブルのレコードを削除する
const orderRepo = entityManager.getRepository(LicenseOrder);
await deleteEntity(
orderRepo,
{ from_account_id: accountId },
this.isCommentOut,
);
await orderRepo.delete({
from_account_id: accountId,
});
const licenseRepo = entityManager.getRepository(License);
const targetLicenses = await licenseRepo.find({
where: {
@ -1039,24 +1031,18 @@ export class AccountsRepositoryService {
},
});
const cardLicenseRepo = entityManager.getRepository(CardLicense);
await deleteEntity(
cardLicenseRepo,
{ license_id: In(targetLicenses.map((license) => license.id)) },
this.isCommentOut,
);
await deleteEntity(
licenseRepo,
{ account_id: accountId },
this.isCommentOut,
);
await cardLicenseRepo.delete({
license_id: In(targetLicenses.map((license) => license.id)),
});
await licenseRepo.delete({
account_id: accountId,
});
const LicenseAllocationHistoryRepo = entityManager.getRepository(
LicenseAllocationHistory,
);
await deleteEntity(
LicenseAllocationHistoryRepo,
{ account_id: accountId },
this.isCommentOut,
);
await LicenseAllocationHistoryRepo.delete({
account_id: accountId,
});
// ワークタイプ系のテーブルのレコードを削除する
const worktypeRepo = entityManager.getRepository(Worktype);
@ -1065,16 +1051,10 @@ export class AccountsRepositoryService {
});
const optionItemRepo = entityManager.getRepository(OptionItem);
await deleteEntity(
optionItemRepo,
{ worktype_id: In(taggerWorktypes.map((worktype) => worktype.id)) },
this.isCommentOut,
);
await deleteEntity(
worktypeRepo,
{ account_id: accountId },
this.isCommentOut,
);
await optionItemRepo.delete({
worktype_id: In(taggerWorktypes.map((worktype) => worktype.id)),
});
await worktypeRepo.delete({ account_id: accountId });
// タスク系のテーブルのレコードを削除する
const taskRepo = entityManager.getRepository(Task);
@ -1085,16 +1065,12 @@ export class AccountsRepositoryService {
});
const checkoutPermissionRepo =
entityManager.getRepository(CheckoutPermission);
await deleteEntity(
checkoutPermissionRepo,
{ task_id: In(targetTasks.map((task) => task.id)) },
this.isCommentOut,
);
await deleteEntity(
taskRepo,
{ account_id: accountId },
this.isCommentOut,
);
await checkoutPermissionRepo.delete({
task_id: In(targetTasks.map((task) => task.id)),
});
await taskRepo.delete({
account_id: accountId,
});
// オーディオファイル系のテーブルのレコードを削除する
const audioFileRepo = entityManager.getRepository(AudioFile);
@ -1104,18 +1080,12 @@ export class AccountsRepositoryService {
},
});
const audioOptionItemsRepo = entityManager.getRepository(AudioOptionItem);
await deleteEntity(
audioOptionItemsRepo,
{
audio_file_id: In(targetaudioFiles.map((audioFile) => audioFile.id)),
},
this.isCommentOut,
);
await deleteEntity(
audioFileRepo,
{ account_id: accountId },
this.isCommentOut,
);
await audioOptionItemsRepo.delete({
audio_file_id: In(targetaudioFiles.map((audioFile) => audioFile.id)),
});
await audioFileRepo.delete({
account_id: accountId,
});
// ユーザーグループ系のテーブルのレコードを削除する
const userGroupRepo = entityManager.getRepository(UserGroup);
@ -1125,42 +1095,28 @@ export class AccountsRepositoryService {
},
});
const userGroupMemberRepo = entityManager.getRepository(UserGroupMember);
await deleteEntity(
userGroupMemberRepo,
{
user_group_id: In(targetUserGroup.map((userGroup) => userGroup.id)),
},
this.isCommentOut,
);
await deleteEntity(
userGroupRepo,
{ account_id: accountId },
this.isCommentOut,
);
await userGroupMemberRepo.delete({
user_group_id: In(targetUserGroup.map((userGroup) => userGroup.id)),
});
await userGroupRepo.delete({
account_id: accountId,
});
// テンプレートファイルテーブルのレコードを削除する
const templateFileRepo = entityManager.getRepository(TemplateFile);
await deleteEntity(
templateFileRepo,
{ account_id: accountId },
this.isCommentOut,
);
await templateFileRepo.delete({ account_id: accountId });
// ユーザテーブルのレコードを削除する
const userRepo = entityManager.getRepository(User);
await deleteEntity(
userRepo,
{ account_id: accountId },
this.isCommentOut,
);
await userRepo.delete({
account_id: accountId,
});
// ソート条件のテーブルのレコードを削除する
const sortCriteriaRepo = entityManager.getRepository(SortCriteria);
await deleteEntity(
sortCriteriaRepo,
{ user_id: In(users.map((user) => user.id)) },
this.isCommentOut,
);
await sortCriteriaRepo.delete({
user_id: In(users.map((user) => user.id)),
});
return users;
});
}

View File

@ -41,12 +41,9 @@ import { TaskStatus, isTaskStatus } from '../../common/types/taskStatus';
import { SortCriteria } from '../sort_criteria/entity/sort_criteria.entity';
import { Workflow } from '../workflows/entity/workflow.entity';
import { Worktype } from '../worktypes/entity/worktype.entity';
import { deleteEntity } from '../../common/repository';
@Injectable()
export class TasksRepositoryService {
//クエリログにコメントを出力するかどうか
private readonly isCommentOut = process.env.STAGE !== 'local';
constructor(private dataSource: DataSource) {}
/**
@ -258,13 +255,9 @@ export class TasksRepositoryService {
);
//対象のタスクに紐づくチェックアウト権限レコードを削除
await deleteEntity(
checkoutRepo,
{
task_id: task.id,
},
this.isCommentOut,
);
await checkoutRepo.delete({
task_id: task.id,
});
//対象のタスクチェックアウト権限を自身のユーザーIDで作成
await checkoutRepo.save({
@ -381,13 +374,9 @@ export class TasksRepositoryService {
// 対象タスクの文字起こし候補を削除
/* Inprogress,PendingID
()*/
await deleteEntity(
checkoutPermissionRepo,
{
task_id: task.id,
},
this.isCommentOut,
);
await checkoutPermissionRepo.delete({
task_id: task.id,
});
});
}
@ -919,13 +908,9 @@ export class TasksRepositoryService {
// 当該タスクに紐づく既存checkoutPermissionをdelete
const checkoutPermissionRepo =
entityManager.getRepository(CheckoutPermission);
await deleteEntity(
checkoutPermissionRepo,
{
task_id: taskRecord.id,
},
this.isCommentOut,
);
await checkoutPermissionRepo.delete({
task_id: taskRecord.id,
});
// 当該タスクに紐づく新規checkoutPermissionをinsert
const checkoutPermissions: CheckoutPermission[] = assignees.map(
@ -1232,13 +1217,9 @@ export class TasksRepositoryService {
entityManager.getRepository(CheckoutPermission);
// 当該タスクに紐づく既存checkoutPermissionをdelete
await deleteEntity(
checkoutPermissionRepo,
{
task_id: task.id,
},
this.isCommentOut,
);
await checkoutPermissionRepo.delete({
task_id: task.id,
});
// ルーティング候補ユーザーのチェックアウト権限を作成
const typistPermissions = typistUsers.map((typistUser) => {

View File

@ -5,12 +5,9 @@ import { UserGroupMember } from './entity/user_group_member.entity';
import { User } from '../users/entity/user.entity';
import { TypistGroupNotExistError, TypistIdInvalidError } from './errors/types';
import { USER_ROLES } from '../../constants';
import { deleteEntity } from '../../common/repository';
@Injectable()
export class UserGroupsRepositoryService {
//クエリログにコメントを出力するかどうか
private readonly isCommentOut = process.env.STAGE !== 'local';
constructor(private dataSource: DataSource) {}
async getUserGroups(account_id: number): Promise<UserGroup[]> {
@ -187,13 +184,9 @@ export class UserGroupsRepositoryService {
await userGroupRepo.save(typistGroup);
// user_group_membersテーブルから対象のタイピストグループのユーザーを削除する
await deleteEntity(
userGroupMemberRepo,
{
user_group_id: typistGroupId,
},
this.isCommentOut,
);
await userGroupMemberRepo.delete({
user_group_id: typistGroupId,
});
const typistGroupMembers = userRecords.map((typist) => {
return {

View File

@ -36,12 +36,9 @@ import { Account } from '../accounts/entity/account.entity';
import { Workflow } from '../workflows/entity/workflow.entity';
import { Worktype } from '../worktypes/entity/worktype.entity';
import { Context } from '../../common/log';
import { deleteEntity } from '../../common/repository';
@Injectable()
export class UsersRepositoryService {
//クエリログにコメントを出力するかどうか
private readonly isCommentOut = process.env.STAGE !== 'local';
constructor(private dataSource: DataSource) {}
/**
@ -436,13 +433,11 @@ export class UsersRepositoryService {
const usersRepo = entityManager.getRepository(User);
const sortCriteriaRepo = entityManager.getRepository(SortCriteria);
// ソート条件を削除
await deleteEntity(
sortCriteriaRepo,
{ user_id: userId },
this.isCommentOut,
);
await sortCriteriaRepo.delete({
user_id: userId,
});
// プライマリ管理者を削除
await deleteEntity(usersRepo, { id: userId }, this.isCommentOut);
await usersRepo.delete({ id: userId });
});
}

View File

@ -15,12 +15,9 @@ import {
AuthorIdAndWorktypeIdPairAlreadyExistsError,
WorkflowNotFoundError,
} from './errors/types';
import { deleteEntity } from '../../common/repository';
@Injectable()
export class WorkflowsRepositoryService {
//クエリログにコメントを出力するかどうか
private readonly isCommentOut = process.env.STAGE !== 'local';
constructor(private dataSource: DataSource) {}
/**
@ -277,12 +274,8 @@ export class WorkflowsRepositoryService {
const workflowTypistsRepo = entityManager.getRepository(DbWorkflowTypist);
// 既存データの削除
await deleteEntity(
workflowTypistsRepo,
{ workflow_id: workflowId },
this.isCommentOut,
);
await deleteEntity(workflowRepo, { id: workflowId }, this.isCommentOut);
await workflowTypistsRepo.delete({ workflow_id: workflowId });
await workflowRepo.delete(workflowId);
{
// ワークフローの重複確認
@ -343,12 +336,9 @@ export class WorkflowsRepositoryService {
`workflow not found. id: ${workflowId}`,
);
}
await deleteEntity(
workflowTypistsRepo,
{ workflow_id: workflowId },
this.isCommentOut,
);
await deleteEntity(workflowRepo, { id: workflowId }, this.isCommentOut);
await workflowTypistsRepo.delete({ workflow_id: workflowId });
await workflowRepo.delete(workflowId);
});
}

View File

@ -17,12 +17,9 @@ import { PostWorktypeOptionItem } from '../../features/accounts/types/types';
import { AccountNotFoundError } from '../accounts/errors/types';
import { Account } from '../accounts/entity/account.entity';
import { Workflow } from '../workflows/entity/workflow.entity';
import { deleteEntity } from '../../common/repository';
@Injectable()
export class WorktypesRepositoryService {
//クエリログにコメントを出力するかどうか
private readonly isCommentOut = process.env.STAGE !== 'local';
constructor(private dataSource: DataSource) {}
/**
@ -206,14 +203,10 @@ export class WorktypesRepositoryService {
// ワークタイプに紐づくオプションアイテムを削除
const optionItemRepo = entityManager.getRepository(OptionItem);
await deleteEntity(
optionItemRepo,
{ worktype_id: id },
this.isCommentOut,
);
await optionItemRepo.delete({ worktype_id: id });
// ワークタイプを削除
await deleteEntity(worktypeRepo, { id: id }, this.isCommentOut);
await worktypeRepo.delete({ id: id });
});
}
@ -288,11 +281,7 @@ export class WorktypesRepositoryService {
});
// ワークタイプに紐づくオプションアイテムを削除してから再登録
await deleteEntity(
optionItemRepo,
{ worktype_id: worktypeId },
this.isCommentOut,
);
await optionItemRepo.delete({ worktype_id: worktypeId });
await optionItemRepo.save(optionItems);
});
}