고도화: 전 모듈 dbio 25→40 · batch 17→22 세분화 (+432본, 전부 고유)
- 11개 모듈 각 dbio +15(→40), batch +5(→22) 새 고유 ECPG 프로그램 + 카피북 헤더 (window/HAVING/JOIN/FILTER/NOT EXISTS/upsert/correlated/INSERT..SELECT 등 구조 다양) - 전 코퍼스 .pgc 1004/1004 정규화-고유 (dup 그룹 0) - 통합 검증: 12서버 runok, 333 서비스, 242 배치 바이너리, 매입체인 XA 커밋, prepared_xacts=0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
05ad8a3064
commit
fc16ea64c8
422 changed files with 8717 additions and 0 deletions
35
app/src/mm/batch/mm_bin_dedup_batch.pgc
Normal file
35
app/src/mm/batch/mm_bin_dedup_batch.pgc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* mm_bin_dedup_batch.pgc - mm 비활성 BIN 정리 배치 (DELETE range + XA).
|
||||
*
|
||||
* 지정 카드브랜드의 비활성(status<>'ACTIVE') BIN 행을 한 문장으로 삭제하고
|
||||
* 삭제행수를 sqlca.sqlerrd[2] 로 확인한다. ONE global XA transaction.
|
||||
* host 변수는 전용 카피북 mm_bin_dedup_cpy.h 를 EXEC SQL INCLUDE.
|
||||
* Usage: mm_bin_dedup_batch [CARD_BRAND]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *brand = (argc > 1) ? argv[1] : "LOCAL";
|
||||
|
||||
EXEC SQL INCLUDE mm_bin_dedup_cpy;
|
||||
|
||||
strncpy(d_brand, brand, sizeof(d_brand)-1); d_brand[sizeof(d_brand)-1] = 0;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DELETE FROM mm_bin WHERE card_brand = :d_brand AND status <> 'ACTIVE';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "DELETE FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
d_deleted = (long) sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> mm_bin_dedup_batch COMMIT: brand=%s 삭제=%ld건\n", brand, d_deleted);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
5
app/src/mm/batch/mm_bin_dedup_cpy.h
Normal file
5
app/src/mm/batch/mm_bin_dedup_cpy.h
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
/* mm_bin_dedup_cpy.h - mm_bin_dedup_batch 전용 카피북 (host 변수 선언). */
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char d_brand[16];
|
||||
long d_deleted;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
50
app/src/mm/batch/mm_fee_bump_batch.pgc
Normal file
50
app/src/mm/batch/mm_fee_bump_batch.pgc
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* mm_fee_bump_batch.pgc - mm 수수료율 일괄 인상 배치 (커서 + UPDATE + XA).
|
||||
*
|
||||
* 지정 card_type 의 수수료율 행을 커서로 훑어 rate_bps 를 delta 만큼 인상하고,
|
||||
* 변경 이력을 mm_fee_rate_hist 에 남긴다. 전 구간 ONE global XA transaction.
|
||||
* host 변수는 전용 카피북 mm_fee_bump_cpy.h 를 EXEC SQL INCLUDE.
|
||||
* Usage: mm_fee_bump_batch [CARD_TYPE] [DELTA_BPS]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *card = (argc > 1) ? argv[1] : "CREDIT";
|
||||
long delta = (argc > 2) ? atol(argv[2]) : 1;
|
||||
long bumped = 0;
|
||||
|
||||
EXEC SQL INCLUDE mm_fee_bump_cpy;
|
||||
|
||||
strncpy(b_card, card, sizeof(b_card)-1); b_card[sizeof(b_card)-1] = 0;
|
||||
b_delta = delta;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DECLARE mfb CURSOR FOR
|
||||
SELECT merchant_id FROM mm_fee_rate WHERE card_type = :b_card ORDER BY merchant_id;
|
||||
EXEC SQL OPEN mfb;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH mfb INTO :b_merch;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE mfb; tpabort(0); return 1; }
|
||||
EXEC SQL UPDATE mm_fee_rate SET rate_bps = rate_bps + :b_delta, updated_at = now()
|
||||
WHERE merchant_id = :b_merch AND card_type = :b_card;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "UPDATE FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE mfb; tpabort(0); return 1; }
|
||||
bumped++;
|
||||
}
|
||||
EXEC SQL CLOSE mfb;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> mm_fee_bump_batch COMMIT: card=%s delta=%ld 인상=%ld건\n", card, delta, bumped);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
6
app/src/mm/batch/mm_fee_bump_cpy.h
Normal file
6
app/src/mm/batch/mm_fee_bump_cpy.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* mm_fee_bump_cpy.h - mm_fee_bump_batch 전용 카피북 (host 변수 선언). */
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char b_card[16];
|
||||
long b_delta;
|
||||
char b_merch[64];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
39
app/src/mm/batch/mm_hist_archive_batch.pgc
Normal file
39
app/src/mm/batch/mm_hist_archive_batch.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* mm_hist_archive_batch.pgc - mm 현행 수수료율 이력 적재 배치 (INSERT..SELECT + XA).
|
||||
*
|
||||
* 현재 mm_fee_rate 스냅샷 전체를 mm_fee_rate_hist 에 한 문장으로 적재한다.
|
||||
* hist_id 는 시퀀스 기준값 + row_number() 로 부여. ONE global XA transaction.
|
||||
* host 변수는 전용 카피북 mm_hist_archive_cpy.h 를 EXEC SQL INCLUDE.
|
||||
* Usage: mm_hist_archive_batch
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
(void) argc; (void) argv;
|
||||
|
||||
EXEC SQL INCLUDE mm_hist_archive_cpy;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL SELECT coalesce(max(hist_id),0) INTO :a_base FROM mm_fee_rate_hist;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "BASE FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
EXEC SQL INSERT INTO mm_fee_rate_hist (hist_id, merchant_id, card_type, rate_bps, eff_date)
|
||||
SELECT :a_base + row_number() OVER (ORDER BY merchant_id, card_type),
|
||||
merchant_id, card_type, rate_bps, eff_date
|
||||
FROM mm_fee_rate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "INSERT FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
a_rows = (long) sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> mm_hist_archive_batch COMMIT: 이력적재=%ld건\n", a_rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
5
app/src/mm/batch/mm_hist_archive_cpy.h
Normal file
5
app/src/mm/batch/mm_hist_archive_cpy.h
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
/* mm_hist_archive_cpy.h - mm_hist_archive_batch 전용 카피북 (host 변수 선언). */
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long a_base;
|
||||
long a_rows;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
40
app/src/mm/batch/mm_limit_scale_batch.pgc
Normal file
40
app/src/mm/batch/mm_limit_scale_batch.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* mm_limit_scale_batch.pgc - mm 등급별 한도 일괄 조정 배치 (UPDATE + IN 서브셀렉트 + XA).
|
||||
*
|
||||
* 지정 등급 가맹점(IN 서브셀렉트)의 mm_limit.daily_limit 을 pct 퍼센트로 스케일한다.
|
||||
* 한 UPDATE 문으로 처리하고 변경행수를 sqlca.sqlerrd[2] 로 확인. ONE global XA.
|
||||
* host 변수는 전용 카피북 mm_limit_scale_cpy.h 를 EXEC SQL INCLUDE.
|
||||
* Usage: mm_limit_scale_batch [GRADE] [PCT]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *grade = (argc > 1) ? argv[1] : "S";
|
||||
long pct = (argc > 2) ? atol(argv[2]) : 120;
|
||||
|
||||
EXEC SQL INCLUDE mm_limit_scale_cpy;
|
||||
|
||||
strncpy(s_grade, grade, sizeof(s_grade)-1); s_grade[sizeof(s_grade)-1] = 0;
|
||||
s_pct = pct;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL UPDATE mm_limit
|
||||
SET daily_limit = daily_limit * :s_pct / 100, updated_at = now()
|
||||
WHERE merchant_id IN (SELECT merchant_id FROM mm_merchant_ext
|
||||
WHERE grade = :s_grade AND status = 'ACTIVE');
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "UPDATE FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
s_scaled = (long) sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> mm_limit_scale_batch COMMIT: grade=%s pct=%ld 조정=%ld건\n", grade, pct, s_scaled);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
6
app/src/mm/batch/mm_limit_scale_cpy.h
Normal file
6
app/src/mm/batch/mm_limit_scale_cpy.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* mm_limit_scale_cpy.h - mm_limit_scale_batch 전용 카피북 (host 변수 선언). */
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char s_grade[8];
|
||||
long s_pct;
|
||||
long s_scaled;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
47
app/src/mm/batch/mm_risk_rollup_batch.pgc
Normal file
47
app/src/mm/batch/mm_risk_rollup_batch.pgc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* mm_risk_rollup_batch.pgc - mm MCC 위험도 재산정 배치 (커서 + 가맹점수 기반 UPDATE + XA).
|
||||
*
|
||||
* mm_mcc 를 커서로 훑어 각 MCC 를 쓰는 가맹점 수를 세고, 그 규모에 따라 risk_level 을
|
||||
* 재산정(UPDATE)한다. 규모가 클수록 높은 위험도. 전 구간 ONE global XA transaction.
|
||||
* host 변수는 전용 카피북 mm_risk_rollup_cpy.h 를 EXEC SQL INCLUDE.
|
||||
* Usage: mm_risk_rollup_batch
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
long rolled = 0;
|
||||
(void) argc; (void) argv;
|
||||
|
||||
EXEC SQL INCLUDE mm_risk_rollup_cpy;
|
||||
|
||||
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
|
||||
|
||||
EXEC SQL DECLARE mrr CURSOR FOR SELECT mcc FROM mm_mcc ORDER BY mcc;
|
||||
EXEC SQL OPEN mrr;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH mrr INTO :k_mcc;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE mrr; tpabort(0); return 1; }
|
||||
EXEC SQL SELECT count(*) INTO :k_merch FROM mm_merchant_ext WHERE mcc = :k_mcc;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE mrr; tpabort(0); return 1; }
|
||||
k_level = (k_merch >= 100) ? 3 : (k_merch >= 10) ? 2 : 1;
|
||||
EXEC SQL UPDATE mm_mcc SET risk_level = :k_level WHERE mcc = :k_mcc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "UPDATE FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE mrr; tpabort(0); return 1; }
|
||||
rolled++;
|
||||
}
|
||||
EXEC SQL CLOSE mrr;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> mm_risk_rollup_batch COMMIT: 재산정=%ld건\n", rolled);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
6
app/src/mm/batch/mm_risk_rollup_cpy.h
Normal file
6
app/src/mm/batch/mm_risk_rollup_cpy.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/* mm_risk_rollup_cpy.h - mm_risk_rollup_batch 전용 카피북 (host 변수 선언). */
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char k_mcc[8];
|
||||
long k_merch;
|
||||
long k_level;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
9
app/src/mm/dbio/mm_bin_distinct_dbio.h
Normal file
9
app/src/mm/dbio/mm_bin_distinct_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_bin_distinct_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_bin_distinct_dbio, part of libmmdbio.a).
|
||||
* 카드브랜드별 고유 발급사 수 (count DISTINCT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_BIN_DISTINCT_DBIO_H
|
||||
#define MM_BIN_DISTINCT_DBIO_H
|
||||
long mmdb_bin_distinct_issuer(const char *brand);
|
||||
#endif /* MM_BIN_DISTINCT_DBIO_H */
|
||||
22
app/src/mm/dbio/mm_bin_distinct_dbio.pgc
Normal file
22
app/src/mm/dbio/mm_bin_distinct_dbio.pgc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* mm_bin_distinct_dbio.pgc - mm 모듈 DB 접근 함수 (mm_bin_distinct_dbio), archived into libmmdbio.a.
|
||||
* 카드브랜드별 고유 발급사 수 (count DISTINCT).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_bin_distinct_dbio.h"
|
||||
|
||||
/* card_brand 의 BIN 에서 고유 issuer_cd 수. */
|
||||
long mmdb_bin_distinct_issuer(const char *brand)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_brand[16];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_brand, brand, sizeof(h_brand)-1); h_brand[sizeof(h_brand)-1] = 0;
|
||||
EXEC SQL SELECT count(DISTINCT issuer_cd) INTO :h_v FROM mm_bin
|
||||
WHERE card_brand = :h_brand AND status = 'ACTIVE';
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_fee_in_dbio.h
Normal file
9
app/src/mm/dbio/mm_fee_in_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_fee_in_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_fee_in_dbio, part of libmmdbio.a).
|
||||
* 특정 등급 가맹점의 평균 수수료율 (IN 서브셀렉트).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_FEE_IN_DBIO_H
|
||||
#define MM_FEE_IN_DBIO_H
|
||||
long mmdb_fee_in_avg(const char *grade);
|
||||
#endif /* MM_FEE_IN_DBIO_H */
|
||||
23
app/src/mm/dbio/mm_fee_in_dbio.pgc
Normal file
23
app/src/mm/dbio/mm_fee_in_dbio.pgc
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* mm_fee_in_dbio.pgc - mm 모듈 DB 접근 함수 (mm_fee_in_dbio), archived into libmmdbio.a.
|
||||
* 특정 등급 가맹점의 평균 수수료율 (IN 서브셀렉트).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_fee_in_dbio.h"
|
||||
|
||||
/* grade 에 해당하는 가맹점(IN) 의 CREDIT 수수료율 평균(bps). */
|
||||
long mmdb_fee_in_avg(const char *grade)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_grade[8];
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_grade, grade, sizeof(h_grade)-1); h_grade[sizeof(h_grade)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(avg(rate_bps),0)::bigint INTO :h_v FROM mm_fee_rate
|
||||
WHERE card_type = 'CREDIT'
|
||||
AND merchant_id IN (SELECT merchant_id FROM mm_merchant_ext WHERE grade = :h_grade);
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_fee_rank_dbio.h
Normal file
9
app/src/mm/dbio/mm_fee_rank_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_fee_rank_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_fee_rank_dbio, part of libmmdbio.a).
|
||||
* 카드유형 내 수수료율 순위 n번째 가맹점 (window RANK).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_FEE_RANK_DBIO_H
|
||||
#define MM_FEE_RANK_DBIO_H
|
||||
int mmdb_fee_rank(const char *card_type, long rank, char *merch_out);
|
||||
#endif /* MM_FEE_RANK_DBIO_H */
|
||||
26
app/src/mm/dbio/mm_fee_rank_dbio.pgc
Normal file
26
app/src/mm/dbio/mm_fee_rank_dbio.pgc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* mm_fee_rank_dbio.pgc - mm 모듈 DB 접근 함수 (mm_fee_rank_dbio), archived into libmmdbio.a.
|
||||
* 카드유형 내 수수료율 순위 n번째 가맹점 (window RANK).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_fee_rank_dbio.h"
|
||||
|
||||
/* card_type 파티션에서 rate_bps 내림차순 rank 번째 가맹점. */
|
||||
int mmdb_fee_rank(const char *card_type, long rank, char *merch_out)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_ct[16], h_merch[64];
|
||||
long h_rank = rank;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_ct, card_type, sizeof(h_ct)-1); h_ct[sizeof(h_ct)-1] = 0;
|
||||
EXEC SQL SELECT merchant_id INTO :h_merch FROM (
|
||||
SELECT merchant_id, rank() OVER (PARTITION BY card_type ORDER BY rate_bps DESC) AS rk
|
||||
FROM mm_fee_rate WHERE card_type = :h_ct) t
|
||||
WHERE t.rk = :h_rank LIMIT 1;
|
||||
if (sqlca.sqlcode == 100) { merch_out[0] = 0; return 0; }
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
strcpy(merch_out, h_merch);
|
||||
return 0;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_fx_upsert_dbio.h
Normal file
9
app/src/mm/dbio/mm_fx_upsert_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_fx_upsert_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_fx_upsert_dbio, part of libmmdbio.a).
|
||||
* 환율 마스터 upsert (ON CONFLICT).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_FX_UPSERT_DBIO_H
|
||||
#define MM_FX_UPSERT_DBIO_H
|
||||
int mmdb_fx_upsert(const char *ccy, long rate_bps, const char *base_date);
|
||||
#endif /* MM_FX_UPSERT_DBIO_H */
|
||||
25
app/src/mm/dbio/mm_fx_upsert_dbio.pgc
Normal file
25
app/src/mm/dbio/mm_fx_upsert_dbio.pgc
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* mm_fx_upsert_dbio.pgc - mm 모듈 DB 접근 함수 (mm_fx_upsert_dbio), archived into libmmdbio.a.
|
||||
* 환율 마스터 upsert (ON CONFLICT).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_fx_upsert_dbio.h"
|
||||
|
||||
/* mm_fx_rate 에 통화별 환율을 upsert. */
|
||||
int mmdb_fx_upsert(const char *ccy, long rate_bps, const char *base_date)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_ccy[8], h_date[16];
|
||||
long h_rate = rate_bps;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_ccy, ccy, sizeof(h_ccy)-1); h_ccy[sizeof(h_ccy)-1] = 0;
|
||||
strncpy(h_date, base_date, sizeof(h_date)-1); h_date[sizeof(h_date)-1] = 0;
|
||||
EXEC SQL INSERT INTO mm_fx_rate (ccy, rate_bps, base_date)
|
||||
VALUES (:h_ccy, :h_rate, :h_date)
|
||||
ON CONFLICT (ccy) DO UPDATE
|
||||
SET rate_bps = EXCLUDED.rate_bps, base_date = EXCLUDED.base_date, updated_at = now();
|
||||
if (sqlca.sqlcode < 0) { userlog("mmdb_fx_upsert FAIL [%d]", sqlca.sqlcode); return -1; }
|
||||
return 0;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_grade_having_dbio.h
Normal file
9
app/src/mm/dbio/mm_grade_having_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_grade_having_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_grade_having_dbio, part of libmmdbio.a).
|
||||
* 가맹점 수 임계 초과 등급 수 (GROUP BY ... HAVING).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_GRADE_HAVING_DBIO_H
|
||||
#define MM_GRADE_HAVING_DBIO_H
|
||||
long mmdb_grade_having(long min_cnt);
|
||||
#endif /* MM_GRADE_HAVING_DBIO_H */
|
||||
32
app/src/mm/dbio/mm_grade_having_dbio.pgc
Normal file
32
app/src/mm/dbio/mm_grade_having_dbio.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* mm_grade_having_dbio.pgc - mm 모듈 DB 접근 함수 (mm_grade_having_dbio), archived into libmmdbio.a.
|
||||
* 가맹점 수 임계 초과 등급 수 (GROUP BY ... HAVING 커서).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_grade_having_dbio.h"
|
||||
|
||||
/* 등급별 활성 가맹점 수가 min_cnt 이상인 등급 개수. */
|
||||
long mmdb_grade_having(long min_cnt)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_min = min_cnt, h_cnt;
|
||||
char h_grade[8];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
long grades = 0;
|
||||
EXEC SQL DECLARE mgh CURSOR FOR
|
||||
SELECT grade, count(*) FROM mm_merchant_ext
|
||||
WHERE status = 'ACTIVE' GROUP BY grade HAVING count(*) >= :h_min
|
||||
ORDER BY grade;
|
||||
EXEC SQL OPEN mgh;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
for (;;) {
|
||||
EXEC SQL FETCH mgh INTO :h_grade, :h_cnt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE mgh; return -1; }
|
||||
grades++;
|
||||
}
|
||||
EXEC SQL CLOSE mgh;
|
||||
return grades;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_grade_insert_sel_dbio.h
Normal file
9
app/src/mm/dbio/mm_grade_insert_sel_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_grade_insert_sel_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_grade_insert_sel_dbio, part of libmmdbio.a).
|
||||
* 등급별 가맹점 수 통계 일괄 적재 (INSERT..SELECT).
|
||||
* Return convention: >=0 ok(적재건수), -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_GRADE_INSERT_SEL_DBIO_H
|
||||
#define MM_GRADE_INSERT_SEL_DBIO_H
|
||||
long mmdb_grade_insert_sel(const char *statdate);
|
||||
#endif /* MM_GRADE_INSERT_SEL_DBIO_H */
|
||||
24
app/src/mm/dbio/mm_grade_insert_sel_dbio.pgc
Normal file
24
app/src/mm/dbio/mm_grade_insert_sel_dbio.pgc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* mm_grade_insert_sel_dbio.pgc - mm 모듈 DB 접근 함수 (mm_grade_insert_sel_dbio), archived into libmmdbio.a.
|
||||
* 등급별 가맹점 수 통계 일괄 적재 (INSERT..SELECT).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_grade_insert_sel_dbio.h"
|
||||
|
||||
/* 활성 가맹점을 등급별로 집계해 mm_grade_stat 에 한 문장으로 적재/갱신. */
|
||||
long mmdb_grade_insert_sel(const char *statdate)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_date[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_date, statdate, sizeof(h_date)-1); h_date[sizeof(h_date)-1] = 0;
|
||||
EXEC SQL INSERT INTO mm_grade_stat (stat_date, grade, merch_cnt)
|
||||
SELECT :h_date, grade, count(*) FROM mm_merchant_ext
|
||||
WHERE status = 'ACTIVE' GROUP BY grade
|
||||
ON CONFLICT (stat_date, grade) DO UPDATE
|
||||
SET merch_cnt = EXCLUDED.merch_cnt, updated_at = now();
|
||||
if (sqlca.sqlcode < 0) { userlog("mmdb_grade_insert_sel FAIL [%d]", sqlca.sqlcode); return -1; }
|
||||
return (long) sqlca.sqlerrd[2];
|
||||
}
|
||||
9
app/src/mm/dbio/mm_hist_purge_dbio.h
Normal file
9
app/src/mm/dbio/mm_hist_purge_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_hist_purge_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_hist_purge_dbio, part of libmmdbio.a).
|
||||
* 수수료율 이력 범위 삭제 후 삭제건수 반환 (DELETE range).
|
||||
* Return convention: >=0 ok(삭제건수), -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_HIST_PURGE_DBIO_H
|
||||
#define MM_HIST_PURGE_DBIO_H
|
||||
long mmdb_hist_purge(const char *cutoff);
|
||||
#endif /* MM_HIST_PURGE_DBIO_H */
|
||||
20
app/src/mm/dbio/mm_hist_purge_dbio.pgc
Normal file
20
app/src/mm/dbio/mm_hist_purge_dbio.pgc
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* mm_hist_purge_dbio.pgc - mm 모듈 DB 접근 함수 (mm_hist_purge_dbio), archived into libmmdbio.a.
|
||||
* 수수료율 이력 범위 삭제 후 삭제건수 반환 (DELETE range).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_hist_purge_dbio.h"
|
||||
|
||||
/* eff_date 이전 수수료율 이력 삭제, 삭제 행수 반환. */
|
||||
long mmdb_hist_purge(const char *cutoff)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_cutoff[16];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_cutoff, cutoff, sizeof(h_cutoff)-1); h_cutoff[sizeof(h_cutoff)-1] = 0;
|
||||
EXEC SQL DELETE FROM mm_fee_rate_hist WHERE eff_date < :h_cutoff;
|
||||
if (sqlca.sqlcode < 0) { userlog("mmdb_hist_purge FAIL [%d]", sqlca.sqlcode); return -1; }
|
||||
return (long) sqlca.sqlerrd[2];
|
||||
}
|
||||
9
app/src/mm/dbio/mm_issuer_corr_dbio.h
Normal file
9
app/src/mm/dbio/mm_issuer_corr_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_issuer_corr_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_issuer_corr_dbio, part of libmmdbio.a).
|
||||
* 발급사별 BIN 수 상관 서브쿼리 순회 최대치 (correlated subquery + cursor).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_ISSUER_CORR_DBIO_H
|
||||
#define MM_ISSUER_CORR_DBIO_H
|
||||
long mmdb_issuer_corr_max_bin(void);
|
||||
#endif /* MM_ISSUER_CORR_DBIO_H */
|
||||
33
app/src/mm/dbio/mm_issuer_corr_dbio.pgc
Normal file
33
app/src/mm/dbio/mm_issuer_corr_dbio.pgc
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* mm_issuer_corr_dbio.pgc - mm 모듈 DB 접근 함수 (mm_issuer_corr_dbio), archived into libmmdbio.a.
|
||||
* 발급사별 BIN 수 상관 서브쿼리 순회 최대치 (correlated subquery + cursor).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_issuer_corr_dbio.h"
|
||||
|
||||
/* 각 발급사의 활성 BIN 수를 상관 서브쿼리로 뽑아 커서로 훑어 최대값 반환. */
|
||||
long mmdb_issuer_corr_max_bin(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_issuer[16];
|
||||
long h_bins;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
long peak = 0;
|
||||
EXEC SQL DECLARE mic CURSOR FOR
|
||||
SELECT i.issuer_cd,
|
||||
(SELECT count(*) FROM mm_bin b WHERE b.issuer_cd = i.issuer_cd AND b.status = 'ACTIVE')
|
||||
FROM mm_issuer i WHERE i.status = 'ACTIVE'
|
||||
ORDER BY i.issuer_cd;
|
||||
EXEC SQL OPEN mic;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
for (;;) {
|
||||
EXEC SQL FETCH mic INTO :h_issuer, :h_bins;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE mic; return -1; }
|
||||
if (h_bins > peak) peak = h_bins;
|
||||
}
|
||||
EXEC SQL CLOSE mic;
|
||||
return peak;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_mcc_risk_cursor_dbio.h
Normal file
9
app/src/mm/dbio/mm_mcc_risk_cursor_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_mcc_risk_cursor_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_mcc_risk_cursor_dbio, part of libmmdbio.a).
|
||||
* MCC 위험도 가맹점수 가중 합 (cursor + 누적).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_MCC_RISK_CURSOR_DBIO_H
|
||||
#define MM_MCC_RISK_CURSOR_DBIO_H
|
||||
long mmdb_mcc_weighted_risk(void);
|
||||
#endif /* MM_MCC_RISK_CURSOR_DBIO_H */
|
||||
32
app/src/mm/dbio/mm_mcc_risk_cursor_dbio.pgc
Normal file
32
app/src/mm/dbio/mm_mcc_risk_cursor_dbio.pgc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* mm_mcc_risk_cursor_dbio.pgc - mm 모듈 DB 접근 함수 (mm_mcc_risk_cursor_dbio), archived into libmmdbio.a.
|
||||
* MCC 위험도 가맹점수 가중 합 (cursor + 누적).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_mcc_risk_cursor_dbio.h"
|
||||
|
||||
/* MCC 를 커서로 훑어 각 MCC 의 가맹점 수 x risk_level 을 누적. */
|
||||
long mmdb_mcc_weighted_risk(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_mcc[8];
|
||||
long h_risk, h_merch;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
long total = 0;
|
||||
EXEC SQL DECLARE mrc CURSOR FOR
|
||||
SELECT mcc, risk_level FROM mm_mcc ORDER BY mcc;
|
||||
EXEC SQL OPEN mrc;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
for (;;) {
|
||||
EXEC SQL FETCH mrc INTO :h_mcc, :h_risk;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE mrc; return -1; }
|
||||
EXEC SQL SELECT count(*) INTO :h_merch FROM mm_merchant_ext WHERE mcc = :h_mcc;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE mrc; return -1; }
|
||||
total += h_risk * h_merch;
|
||||
}
|
||||
EXEC SQL CLOSE mrc;
|
||||
return total;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_noterm_dbio.h
Normal file
9
app/src/mm/dbio/mm_noterm_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_noterm_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_noterm_dbio, part of libmmdbio.a).
|
||||
* 단말 미보유 활성 가맹점 수 (NOT EXISTS).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_NOTERM_DBIO_H
|
||||
#define MM_NOTERM_DBIO_H
|
||||
long mmdb_noterm_count(void);
|
||||
#endif /* MM_NOTERM_DBIO_H */
|
||||
22
app/src/mm/dbio/mm_noterm_dbio.pgc
Normal file
22
app/src/mm/dbio/mm_noterm_dbio.pgc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* mm_noterm_dbio.pgc - mm 모듈 DB 접근 함수 (mm_noterm_dbio), archived into libmmdbio.a.
|
||||
* 단말 미보유 활성 가맹점 수 (NOT EXISTS).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_noterm_dbio.h"
|
||||
|
||||
/* mm_terminal 에 단말이 하나도 없는 활성 가맹점 수. */
|
||||
long mmdb_noterm_count(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT count(*) INTO :h_v FROM mm_merchant_ext m
|
||||
WHERE m.status = 'ACTIVE'
|
||||
AND NOT EXISTS (SELECT 1 FROM mm_terminal t
|
||||
WHERE t.merchant_id = m.merchant_id AND t.status = 'ACTIVE');
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
return h_v;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_rate_minmax_dbio.h
Normal file
9
app/src/mm/dbio/mm_rate_minmax_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_rate_minmax_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_rate_minmax_dbio, part of libmmdbio.a).
|
||||
* 카드유형 수수료율 최소/최대 (min/max).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_RATE_MINMAX_DBIO_H
|
||||
#define MM_RATE_MINMAX_DBIO_H
|
||||
int mmdb_rate_minmax(const char *card_type, long *lo, long *hi);
|
||||
#endif /* MM_RATE_MINMAX_DBIO_H */
|
||||
23
app/src/mm/dbio/mm_rate_minmax_dbio.pgc
Normal file
23
app/src/mm/dbio/mm_rate_minmax_dbio.pgc
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* mm_rate_minmax_dbio.pgc - mm 모듈 DB 접근 함수 (mm_rate_minmax_dbio), archived into libmmdbio.a.
|
||||
* 카드유형 수수료율 최소/최대 (min/max).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_rate_minmax_dbio.h"
|
||||
|
||||
/* card_type 수수료율의 최소/최대 bps 를 반환. */
|
||||
int mmdb_rate_minmax(const char *card_type, long *lo, long *hi)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_ct[16];
|
||||
long h_lo = 0, h_hi = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
strncpy(h_ct, card_type, sizeof(h_ct)-1); h_ct[sizeof(h_ct)-1] = 0;
|
||||
EXEC SQL SELECT coalesce(min(rate_bps),0), coalesce(max(rate_bps),0)
|
||||
INTO :h_lo, :h_hi FROM mm_fee_rate WHERE card_type = :h_ct;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
*lo = h_lo; *hi = h_hi;
|
||||
return 0;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_risk_case_dbio.h
Normal file
9
app/src/mm/dbio/mm_risk_case_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_risk_case_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_risk_case_dbio, part of libmmdbio.a).
|
||||
* MCC 위험도 구간별 건수 (CASE 집계).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_RISK_CASE_DBIO_H
|
||||
#define MM_RISK_CASE_DBIO_H
|
||||
int mmdb_risk_case(long *lo, long *mid, long *hi);
|
||||
#endif /* MM_RISK_CASE_DBIO_H */
|
||||
24
app/src/mm/dbio/mm_risk_case_dbio.pgc
Normal file
24
app/src/mm/dbio/mm_risk_case_dbio.pgc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* mm_risk_case_dbio.pgc - mm 모듈 DB 접근 함수 (mm_risk_case_dbio), archived into libmmdbio.a.
|
||||
* MCC 위험도 구간별 건수 (CASE 집계).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_risk_case_dbio.h"
|
||||
|
||||
/* risk_level 을 저/중/고 구간으로 CASE 분류해 각 건수 반환. */
|
||||
int mmdb_risk_case(long *lo, long *mid, long *hi)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_lo = 0, h_mid = 0, h_hi = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT
|
||||
coalesce(sum(CASE WHEN risk_level <= 1 THEN 1 ELSE 0 END),0),
|
||||
coalesce(sum(CASE WHEN risk_level = 2 THEN 1 ELSE 0 END),0),
|
||||
coalesce(sum(CASE WHEN risk_level >= 3 THEN 1 ELSE 0 END),0)
|
||||
INTO :h_lo, :h_mid, :h_hi FROM mm_mcc;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
*lo = h_lo; *mid = h_mid; *hi = h_hi;
|
||||
return 0;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_status_filter_dbio.h
Normal file
9
app/src/mm/dbio/mm_status_filter_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_status_filter_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_status_filter_dbio, part of libmmdbio.a).
|
||||
* 가맹점 상태별 건수 한 행 분리집계 (FILTER).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_STATUS_FILTER_DBIO_H
|
||||
#define MM_STATUS_FILTER_DBIO_H
|
||||
int mmdb_status_filter(long *active, long *hold, long *deleted);
|
||||
#endif /* MM_STATUS_FILTER_DBIO_H */
|
||||
24
app/src/mm/dbio/mm_status_filter_dbio.pgc
Normal file
24
app/src/mm/dbio/mm_status_filter_dbio.pgc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* mm_status_filter_dbio.pgc - mm 모듈 DB 접근 함수 (mm_status_filter_dbio), archived into libmmdbio.a.
|
||||
* 가맹점 상태별 건수 한 행 분리집계 (FILTER).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_status_filter_dbio.h"
|
||||
|
||||
/* ACTIVE/HOLD/DELETED 건수를 FILTER 로 한 번에 반환. */
|
||||
int mmdb_status_filter(long *active, long *hold, long *deleted)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_a = 0, h_h = 0, h_d = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT
|
||||
count(*) FILTER (WHERE status = 'ACTIVE'),
|
||||
count(*) FILTER (WHERE status = 'HOLD'),
|
||||
count(*) FILTER (WHERE status = 'DELETED')
|
||||
INTO :h_a, :h_h, :h_d FROM mm_merchant_ext;
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
*active = h_a; *hold = h_h; *deleted = h_d;
|
||||
return 0;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_term_join_dbio.h
Normal file
9
app/src/mm/dbio/mm_term_join_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_term_join_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_term_join_dbio, part of libmmdbio.a).
|
||||
* 활성 가맹점의 활성 단말 수 (JOIN).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_TERM_JOIN_DBIO_H
|
||||
#define MM_TERM_JOIN_DBIO_H
|
||||
long mmdb_active_terminals(void);
|
||||
#endif /* MM_TERM_JOIN_DBIO_H */
|
||||
21
app/src/mm/dbio/mm_term_join_dbio.pgc
Normal file
21
app/src/mm/dbio/mm_term_join_dbio.pgc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* mm_term_join_dbio.pgc - mm 모듈 DB 접근 함수 (mm_term_join_dbio), archived into libmmdbio.a.
|
||||
* 활성 가맹점의 활성 단말 수 (JOIN).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_term_join_dbio.h"
|
||||
|
||||
/* mm_terminal 을 mm_merchant_ext 와 조인해 활성 가맹점의 활성 단말 수. */
|
||||
long mmdb_active_terminals(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_v = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT count(*) INTO :h_v
|
||||
FROM mm_terminal t JOIN mm_merchant_ext m ON t.merchant_id = m.merchant_id
|
||||
WHERE t.status = 'ACTIVE' AND m.status = 'ACTIVE';
|
||||
if (sqlca.sqlcode < 0) { userlog("mmdb_active_terminals FAIL [%d]", sqlca.sqlcode); return -1; }
|
||||
return h_v;
|
||||
}
|
||||
9
app/src/mm/dbio/mm_wavg_limit_dbio.h
Normal file
9
app/src/mm/dbio/mm_wavg_limit_dbio.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* mm_wavg_limit_dbio.h - mm 모듈 DB 접근 계층 copybook (mm_wavg_limit_dbio, part of libmmdbio.a).
|
||||
* 한도 가중 수수료율 평균 (weighted average + JOIN).
|
||||
* Return convention: >=0 ok, -1 = SQL error.
|
||||
*/
|
||||
#ifndef MM_WAVG_LIMIT_DBIO_H
|
||||
#define MM_WAVG_LIMIT_DBIO_H
|
||||
long mmdb_wavg_rate(void);
|
||||
#endif /* MM_WAVG_LIMIT_DBIO_H */
|
||||
23
app/src/mm/dbio/mm_wavg_limit_dbio.pgc
Normal file
23
app/src/mm/dbio/mm_wavg_limit_dbio.pgc
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* mm_wavg_limit_dbio.pgc - mm 모듈 DB 접근 함수 (mm_wavg_limit_dbio), archived into libmmdbio.a.
|
||||
* 한도 가중 수수료율 평균 (weighted average + JOIN).
|
||||
* ECPG (EXEC SQL) functions; run on the caller's XA branch. No EXEC SQL CONNECT.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <userlog.h>
|
||||
#include "mm_wavg_limit_dbio.h"
|
||||
|
||||
/* 일한도로 가중한 CREDIT 수수료율 평균 = sum(rate*limit)/sum(limit). */
|
||||
long mmdb_wavg_rate(void)
|
||||
{
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
long h_num = 0, h_den = 0;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
EXEC SQL SELECT coalesce(sum(f.rate_bps * l.daily_limit),0), coalesce(sum(l.daily_limit),0)
|
||||
INTO :h_num, :h_den
|
||||
FROM mm_fee_rate f JOIN mm_limit l ON f.merchant_id = l.merchant_id
|
||||
WHERE f.card_type = 'CREDIT';
|
||||
if (sqlca.sqlcode < 0) return -1;
|
||||
if (h_den <= 0) return 0;
|
||||
return h_num / h_den;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue