Phase 2c: 전 11모듈 per-service 레거시 구조 분해·확장 (실동작 유지)
- 10개 모듈(au py rc st lg cl mm vl mg cm)을 ac 템플릿대로 분해: svc/ 30 서비스 .pgc + 카피북 .h, 얇은 <mod>_svr 디스패처 dbio/ ~25 .pgc(+.h), batch/ ~17 .pgc, run/ ~17 .sh (모듈마다) - 파일: svc 330 + dbio 276 + batch 187 + run 187, 총 소스 1602본 - 서비스별 고유 실로직(정규화 md5), build.sh 자동발견(inline/split 양립) - 통합 검증: build DONE modules=11 servers=11 batches=187, 12서버 runok, 333 서비스 AVAIL, 매입체인 XA 커밋(status=S), prepared_xacts=0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c3b99a8b75
commit
fd8b418c6e
1404 changed files with 30322 additions and 5994 deletions
34
app/src/py/batch/py_account_batch.pgc
Normal file
34
app/src/py/batch/py_account_batch.pgc
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* py_account_batch.pgc - py 계좌 현황 집계 (dbio 전용 배치, XA).
|
||||
*
|
||||
* Uses only the dbio layer (no direct EXEC SQL here) to read the active-account
|
||||
* balance total and count under ONE XA transaction. Usage: py_account_batch
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
#include "py_account_agg_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
long total, cnt;
|
||||
|
||||
(void)argc; (void)argv;
|
||||
|
||||
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; }
|
||||
|
||||
total = pydb_account_active_balance();
|
||||
if (total < 0) { fprintf(stderr, "py_account_batch balance FAIL\n"); tpabort(0); return 1; }
|
||||
cnt = pydb_account_active_count();
|
||||
if (cnt < 0) { fprintf(stderr, "py_account_batch count FAIL\n"); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_account_batch COMMIT: active_accounts=%ld total_balance=%ld\n", cnt, total);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
50
app/src/py/batch/py_adjust_apply_batch.pgc
Normal file
50
app/src/py/batch/py_adjust_apply_batch.pgc
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* py_adjust_apply_batch.pgc - py 조정 반영 (커서 + inline UPDATE, XA).
|
||||
*
|
||||
* Cursors the day's adjustments and applies each delta to the linked payout's
|
||||
* net with an inline UPDATE, under ONE XA transaction.
|
||||
* Usage: py_adjust_apply_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_pay, h_delta;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 DECLARE pyaac CURSOR FOR
|
||||
SELECT payout_id, delta FROM py_adjust WHERE biz_date = :h_bizdate ORDER BY adj_id;
|
||||
EXEC SQL OPEN pyaac;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pyaac INTO :h_pay, :h_delta;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pyaac; tpabort(0); return 1; }
|
||||
EXEC SQL UPDATE py_payout SET net = net + :h_delta, updated_at = now() WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pyaac; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pyaac;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_adjust_apply_batch COMMIT: bizdate=%s applied=%ld\n", bizdate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
38
app/src/py/batch/py_close_batch.pgc
Normal file
38
app/src/py/batch/py_close_batch.pgc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* py_close_batch.pgc - py 일마감 (단건 UPDATE 배치, XA).
|
||||
*
|
||||
* Flips the day's paid(P) payouts to closed(X) with ONE guarded UPDATE and
|
||||
* reports the affected count via sqlca.sqlerrd[2], all under ONE XA transaction.
|
||||
* Usage: py_close_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 UPDATE py_payout SET status = 'X' WHERE biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_close_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_close_batch COMMIT: bizdate=%s closed(P->X)=%ld\n", bizdate, h_aff);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
37
app/src/py/batch/py_daily_batch.pgc
Normal file
37
app/src/py/batch/py_daily_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* py_daily_batch.pgc - py 일일 지급 총계 (단건 집계 배치, XA).
|
||||
*
|
||||
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
|
||||
* transaction, an EXEC SQL aggregate runs on the biz_date, then tpcommit drives
|
||||
* XA 2PC. Usage: py_daily_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cnt, h_gross, h_fee, h_net;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 SELECT count(*), coalesce(sum(amount),0), coalesce(sum(fee),0), coalesce(sum(net),0) INTO :h_cnt, :h_gross, :h_fee, :h_net FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_daily_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_daily_batch COMMIT: bizdate=%s payouts=%ld gross=%ld fee=%ld net=%ld\n", bizdate, h_cnt, h_gross, h_fee, h_net);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
55
app/src/py/batch/py_fee_recalc_batch.pgc
Normal file
55
app/src/py/batch/py_fee_recalc_batch.pgc
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* py_fee_recalc_batch.pgc - py 수수료 재계산 (커서 + 계산 + inline UPDATE, XA).
|
||||
*
|
||||
* Cursors the day's requested(R) payouts, recomputes fee (30bps) and net in C,
|
||||
* and writes them back with an inline UPDATE, under ONE XA transaction.
|
||||
* Usage: py_fee_recalc_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0, fee, net;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_pay, h_amt, h_fee, h_net;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 DECLARE pyfrc CURSOR FOR
|
||||
SELECT payout_id, amount FROM py_payout
|
||||
WHERE biz_date = :h_bizdate AND status = 'R'
|
||||
ORDER BY payout_id;
|
||||
EXEC SQL OPEN pyfrc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pyfrc INTO :h_pay, :h_amt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pyfrc; tpabort(0); return 1; }
|
||||
fee = h_amt * 30 / 10000;
|
||||
net = h_amt - fee;
|
||||
h_fee = fee; h_net = net;
|
||||
EXEC SQL UPDATE py_payout SET fee = :h_fee, net = :h_net, updated_at = now() WHERE payout_id = :h_pay;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pyfrc; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pyfrc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_fee_recalc_batch COMMIT: bizdate=%s recalced=%ld\n", bizdate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
39
app/src/py/batch/py_file_confirm_batch.pgc
Normal file
39
app/src/py/batch/py_file_confirm_batch.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* py_file_confirm_batch.pgc - py 지급파일 확정 (조회 후 UPDATE 배치, XA).
|
||||
*
|
||||
* Counts the day's generated(G) files, then flips them to confirmed(C) stamping
|
||||
* confirmed_at, under ONE XA transaction. Usage: py_file_confirm_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cnt, h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 SELECT count(*) INTO :h_cnt FROM py_file WHERE biz_date = :h_bizdate AND status = 'G';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "COUNT FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
EXEC SQL UPDATE py_file SET status = 'C', confirmed_at = now() WHERE biz_date = :h_bizdate AND status = 'G';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_file_confirm_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_file_confirm_batch COMMIT: bizdate=%s generated=%ld confirmed=%ld\n", bizdate, h_cnt, h_aff);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
39
app/src/py/batch/py_ledger_batch.pgc
Normal file
39
app/src/py/batch/py_ledger_batch.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* py_ledger_batch.pgc - py 지급 원장 생성 (INSERT..SELECT 배치, XA).
|
||||
*
|
||||
* Bulk-inserts one XFER ledger row per paid(P) payout of the biz_date using a
|
||||
* single INSERT ... SELECT, under ONE XA transaction. Usage: py_ledger_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_rows;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 INSERT INTO py_ledger (ledger_id, payout_id, entry_type, amount, biz_date)
|
||||
SELECT nextval('py_ledger_seq'), payout_id, 'XFER', net, biz_date
|
||||
FROM py_payout WHERE biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_ledger_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_rows = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_ledger_batch COMMIT: bizdate=%s xfer_rows=%ld\n", bizdate, h_rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
50
app/src/py/batch/py_merchsum_batch.pgc
Normal file
50
app/src/py/batch/py_merchsum_batch.pgc
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* py_merchsum_batch.pgc - py 가맹점 지급 집계 (커서 + dbio upsert 배치, XA).
|
||||
*
|
||||
* Cursors the day's paid(P) payouts and rolls a per-merchant summary via the
|
||||
* dbio upsert, under ONE XA transaction. Usage: py_merchsum_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_merch[64];
|
||||
long h_pay, h_net;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 DECLARE pymsc CURSOR FOR
|
||||
SELECT payout_id, merchant_id, net FROM py_payout
|
||||
WHERE biz_date = :h_bizdate AND status = 'P'
|
||||
ORDER BY payout_id;
|
||||
EXEC SQL OPEN pymsc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pymsc INTO :h_pay, :h_merch, :h_net;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pymsc; tpabort(0); return 1; }
|
||||
if (pydb_upsert_summary(h_merch, bizdate, 1, h_net) < 0) { EXEC SQL CLOSE pymsc; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pymsc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_merchsum_batch COMMIT: bizdate=%s rolled=%ld\n", bizdate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
40
app/src/py/batch/py_netoff_batch.pgc
Normal file
40
app/src/py/batch/py_netoff_batch.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* py_netoff_batch.pgc - py 일괄 상계 (단건 산술 UPDATE 배치, XA).
|
||||
*
|
||||
* Applies a flat offset amount to the net of every requested(R) payout of the
|
||||
* biz_date with a single arithmetic UPDATE, under ONE XA transaction.
|
||||
* Usage: py_netoff_batch [YYYY-MM-DD] [OFFSET]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_off, h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
h_off = (argc > 2) ? atol(argv[2]) : 100;
|
||||
|
||||
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 py_payout SET net = net - :h_off, updated_at = now()
|
||||
WHERE biz_date = :h_bizdate AND status = 'R';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_netoff_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_netoff_batch COMMIT: bizdate=%s offset=%ld affected=%ld\n", bizdate, h_off, h_aff);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
50
app/src/py/batch/py_reject_report_batch.pgc
Normal file
50
app/src/py/batch/py_reject_report_batch.pgc
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* py_reject_report_batch.pgc - py 반려 현황 리포트 (읽기 전용 커서 누적 배치, XA).
|
||||
*
|
||||
* Cursors the day's rejected(J) payouts, accumulating count and amount in C
|
||||
* (no writes), under ONE XA transaction. Usage: py_reject_report_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0, total = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_pay, h_amt;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 DECLARE pyjrc CURSOR FOR
|
||||
SELECT payout_id, amount FROM py_payout
|
||||
WHERE biz_date = :h_bizdate AND status = 'J'
|
||||
ORDER BY payout_id;
|
||||
EXEC SQL OPEN pyjrc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pyjrc INTO :h_pay, :h_amt;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pyjrc; tpabort(0); return 1; }
|
||||
total += h_amt;
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pyjrc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_reject_report_batch COMMIT: bizdate=%s rejects=%ld amount=%ld\n", bizdate, rows, total);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
39
app/src/py/batch/py_retry_batch.pgc
Normal file
39
app/src/py/batch/py_retry_batch.pgc
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* py_retry_batch.pgc - py 실패 지급 재시도 (단건 UPDATE 배치, XA).
|
||||
*
|
||||
* One guarded UPDATE flips the day's failed/held(J,H) payouts back to requested(R)
|
||||
* and bumps retry_count, reporting the affected count via sqlca.sqlerrd[2].
|
||||
* Usage: py_retry_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_aff;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 UPDATE py_payout SET status = 'R', retry_count = retry_count + 1, updated_at = now()
|
||||
WHERE biz_date = :h_bizdate AND status IN ('J', 'H');
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_retry_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
h_aff = sqlca.sqlerrd[2];
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_retry_batch COMMIT: bizdate=%s requeued=%ld\n", bizdate, h_aff);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
53
app/src/py/batch/py_schedule_run_batch.pgc
Normal file
53
app/src/py/batch/py_schedule_run_batch.pgc
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* py_schedule_run_batch.pgc - py 예약 지급 실행 (커서 + dbio + inline UPDATE, XA).
|
||||
*
|
||||
* Cursors the day's pending(S) schedules; per row it flips the linked payout to
|
||||
* requested(R) via dbio and marks the schedule done(D) inline, under ONE XA
|
||||
* transaction. Usage: py_schedule_run_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *rundate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_rundate[16];
|
||||
long h_sched, h_pay;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_rundate, rundate, sizeof(h_rundate)-1); h_rundate[sizeof(h_rundate)-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 DECLARE pyrsc CURSOR FOR
|
||||
SELECT schedule_id, payout_id FROM py_schedule
|
||||
WHERE run_date = :h_rundate AND status = 'S'
|
||||
ORDER BY schedule_id;
|
||||
EXEC SQL OPEN pyrsc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pyrsc INTO :h_sched, :h_pay;
|
||||
if (sqlca.sqlcode == 100) break;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "FETCH FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); EXEC SQL CLOSE pyrsc; tpabort(0); return 1; }
|
||||
if (pydb_update_status(h_pay, "R") < 0) { EXEC SQL CLOSE pyrsc; tpabort(0); return 1; }
|
||||
EXEC SQL UPDATE py_schedule SET status = 'D' WHERE schedule_id = :h_sched;
|
||||
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE pyrsc; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pyrsc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_schedule_run_batch COMMIT: rundate=%s executed=%ld\n", rundate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
37
app/src/py/batch/py_settle_batch.pgc
Normal file
37
app/src/py/batch/py_settle_batch.pgc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* py_settle_batch.pgc - py 지급완료 정산 집계 (단건 집계 배치, XA).
|
||||
*
|
||||
* ATMI client: opens the ECPG XA RM, starts ONE global transaction, aggregates
|
||||
* paid(P) payouts for the biz_date, then tpcommit drives XA 2PC.
|
||||
* Usage: py_settle_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_cnt, h_net;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 SELECT count(*), coalesce(sum(net),0) INTO :h_cnt, :h_net FROM py_payout WHERE biz_date = :h_bizdate AND status = 'P';
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_settle_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_settle_batch COMMIT: bizdate=%s paid=%ld net=%ld\n", bizdate, h_cnt, h_net);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
40
app/src/py/batch/py_stat_batch.pgc
Normal file
40
app/src/py/batch/py_stat_batch.pgc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* py_stat_batch.pgc - py 집중 가맹점 통계 (GROUP BY HAVING 서브쿼리 배치, XA).
|
||||
*
|
||||
* Counts merchants whose daily payout amount clears a threshold using a single
|
||||
* GROUP BY ... HAVING subquery, under ONE XA transaction.
|
||||
* Usage: py_stat_batch [YYYY-MM-DD] [THRESHOLD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16];
|
||||
long h_thr, h_merchants;
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
|
||||
h_thr = (argc > 2) ? atol(argv[2]) : 1000000;
|
||||
|
||||
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 count(*) INTO :h_merchants FROM (
|
||||
SELECT merchant_id FROM py_payout WHERE biz_date = :h_bizdate
|
||||
GROUP BY merchant_id HAVING coalesce(sum(net),0) >= :h_thr) t;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "py_stat_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_stat_batch COMMIT: bizdate=%s threshold=%ld top_merchants=%ld\n", bizdate, h_thr, h_merchants);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
49
app/src/py/batch/py_summary_reset_batch.pgc
Normal file
49
app/src/py/batch/py_summary_reset_batch.pgc
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* py_summary_reset_batch.pgc - py 집계 리셋 (커서 DISTINCT + dbio upsert, XA).
|
||||
*
|
||||
* Cursors the DISTINCT merchants that traded on the biz_date and zeroes each
|
||||
* merchant's daily summary via the dbio ON CONFLICT reset, under ONE XA
|
||||
* transaction. Usage: py_summary_reset_batch [YYYY-MM-DD]
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <atmi.h>
|
||||
#include "py_dbio.h"
|
||||
#include "py_summary_upsert_dbio.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *bizdate = (argc > 1) ? argv[1] : "2026-07-19";
|
||||
long rows = 0;
|
||||
|
||||
EXEC SQL BEGIN DECLARE SECTION;
|
||||
char h_bizdate[16], h_merch[64];
|
||||
EXEC SQL END DECLARE SECTION;
|
||||
|
||||
strncpy(h_bizdate, bizdate, sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-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 DECLARE pysrc CURSOR FOR
|
||||
SELECT DISTINCT merchant_id FROM py_payout WHERE biz_date = :h_bizdate;
|
||||
EXEC SQL OPEN pysrc;
|
||||
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
|
||||
|
||||
for (;;) {
|
||||
EXEC SQL FETCH pysrc INTO :h_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 pysrc; tpabort(0); return 1; }
|
||||
if (pydb_summary_reset(h_merch, bizdate) < 0) { EXEC SQL CLOSE pysrc; tpabort(0); return 1; }
|
||||
rows++;
|
||||
}
|
||||
EXEC SQL CLOSE pysrc;
|
||||
|
||||
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
|
||||
printf(">>> py_summary_reset_batch COMMIT: bizdate=%s merchants=%ld\n", bizdate, rows);
|
||||
|
||||
tpclose(); tpterm();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue