utils_ezworks_prepare-file-delete.js
import { saveJSON } from "../../adapters/ezworks/com-api/ds";
import { encodeHex } from "../crypto/encode-hex";
import { generateUUIDv4 } from "../crypto/generate-uuidv4";
/**
* @typedef prepareFileDeleteOptions
* @property {nexacro.Dataset} dataset 삭제한 항목이 존재하는 데이터 셋
* @property {string} target 대상 테이블
* @property {string[]} keyCols Deprecated. PK 키 값
* @property {function} fileKeyFn 파일 키 함수
* @property {nexacro.Form} [form] 트랜잭션 등에 사용되는 기준이 되는 form. 생략 시
* dataset의
* 상위 form을 사용함
*/
/**
* 삭제할 데이터셋의 대상 파일 UUID를 찾습니다.
*
* @function prepareFileDelete
* @param {prepareFileDeleteOptions} options
* @returns {Promise<function>}
* 성공 시 파일 삭제 실행 함수 반환
* @throws {Error}
* @memberof $f
* @example
* this.fn_cansave = function (obj, e) {
* this.delFuncPromise = $f.prepareFileDelete({
* dataset: this.ds_main,
* target: "CSB_ANNO_MATER",
* fileKeyFn: (c) => [c("YY"), c("SEQ"), "1"],
* });
* return $mpt.confirmSave(this.ds_main, this.validatorMain);
* };
*
* this.fn_save = async function () {
* try {
* await (
* await this.delFuncPromise
* )();
* await this.fn_saveMain();
* } catch (e) {
* this.pop.alert("저장 중 오류가 발생하였습니다.");
* return;
* }
*
* this.fn_search();
* return $mpt.alertSaved();
* };
*
*/
export async function prepareFileDelete(options) {
const { dataset, target, keyCols, fileKeyFn, form } = options;
if (!dataset || !target) {
throw new Error(
"searchDelFileUuid: invalid arguments - dataset and target are required",
);
}
if (!keyCols && !fileKeyFn) {
throw new Error(
"searchDelFileUuid: either keyCols or fileKeyFn must be provided",
);
}
const workForm = form || dataset.parent;
const delRowCnt = dataset.getDeletedRowCount();
// 삭제할 대상이 없는 경우 마침
if (delRowCnt === 0) {
return () => {};
}
// 요청용 데이터셋 생성 및 초기화
const argsDsName = "_ds_searchDelFileUuid";
const argsDs = createTempDataset(workForm, argsDsName);
argsDs.addColumn("FILE_TARGT_IDEN", "string");
for (let i = 0; i < delRowCnt; i++) {
if (fileKeyFn) {
const fileTargtIdenList = parseTargetFunction(
fileKeyFn,
dataset,
i,
);
fileTargtIdenList.forEach((fileTargtIden) => {
const rowIdx = argsDs.addRow();
argsDs.setColumn(rowIdx, "FILE_TARGT_IDEN", fileTargtIden);
});
} else {
const fileTargtIden = keyCols
.map((col) => dataset.getDeletedColumn(i, col))
.join("[^]");
const rowIdx = argsDs.addRow();
argsDs.setColumn(rowIdx, "FILE_TARGT_IDEN", fileTargtIden);
}
}
// 응답용 데이터셋 생성 및 초기화
const respDsName = "_ds_schDelOutDs";
const respDs = createTempDataset(workForm, respDsName);
try {
await workForm.tx.search({
action: "basic",
svcId: "searchDelFileUuid" + argsDsName,
sqlId: "@f_fileUtil.fileSearch",
outDs: respDsName,
opInDs: argsDsName,
param: {
FILE_TARGT: target,
},
});
const obj = saveJSON(respDs);
const jsonStr = JSON.stringify(obj);
return async function (uuidList) {
if (uuidList.length === 0) {
return null;
}
return this.tx.load(
{
action: "basic",
svcId: `filedel_${encodeHex(generateUUIDv4())}`,
param: {
UUID_LIST: uuidList,
},
},
"/ezFile/basic/del",
);
}.bind(workForm, jsonStr);
} catch (e) {
throw e;
} finally {
// 데이터셋 삭제
workForm.removeChild(argsDsName);
argsDs.destroy();
workForm.removeChild(respDsName);
respDs.destroy();
}
}
/**
* 고유한 데이터셋을 생성하고 폼에 추가합니다.
*
* @param {nexacro.Form} form 데이터셋을 추가할 폼
* @param {string} dsName 생성할 데이터셋의 이름
* @returns {nexacro.Dataset} 생성된 데이터셋
* @returns {string[]} filetargtiden 배열
* @throws {Error} 동일한 이름의 데이터셋이 이미 존재하는 경우
* @access private
*/
function createTempDataset(form, dsName) {
if (form[dsName]) {
throw new Error("searchDelFileUuid: duplicate call is not allowed");
}
const ds = new Dataset(dsName, form);
form.addChild(dsName, ds);
return ds;
}
function parseTargetFunction(fn, ds, rowIdx) {
if (typeof fn !== "function") {
return [];
}
const getDelColumnFn = (col) => ds.getDeletedColumn(rowIdx, col);
let fnResult = fn(getDelColumnFn);
if (Array.isArray(fnResult)) {
if (fnResult.length === 0) {
fnResult = [[]];
}
// 1차원 배열인 경우 2차원 단일행 배열로 변환
else if (!Array.isArray(fnResult[0])) {
fnResult = [fnResult];
}
}
if (Array.isArray(fnResult)) {
return fnResult.map((arr) => arr.join("[^]"));
}
return [];
}