본문으로 건너뛰기

dbclient

dbclient는 XML SQL 계약을 기준으로 관계형 데이터베이스 요청을 실행하는 모듈입니다. SQL Server, Oracle, MySQL/MariaDB, PostgreSQL, SQLite 데이터 원본을 설정할 수 있으며, transact에서는 CommandType=D 거래의 기본 실행 모듈로 사용합니다.

책임 범위​

  • DataSource 설정을 읽어 애플리케이션/프로젝트별 데이터베이스 연결을 관리합니다.
  • XML statement 계약을 로드하고 ApplicationID|ProjectID|TransactionID|StatementID 기준으로 실행합니다.
  • 요청 파라미터를 DB provider별 native parameter로 변환합니다.
  • Json, Scalar, NonQuery, Xml, SchemeOnly, CodeHelp 같은 반환 형식을 처리합니다.
  • SQL 실행 로그와 프로파일 로그를 설정에 따라 파일 또는 logger 모듈로 전송합니다.

주요 API​

메서드경로용도
GET/dbclient/api/query/hasstatement 계약 존재 여부를 확인합니다.
GET/dbclient/api/query/refresh계약 파일을 다시 로드합니다.
GET/dbclient/api/query/retrieve계약 원문 또는 상세 정보를 조회합니다.
GET/dbclient/api/query/meta입력/출력 메타 정보를 반환합니다.
GET/dbclient/api/query/reports계약 기반 보고용 정보를 조회합니다.
POST/dbclient/api/querySQL 계약을 실행합니다.

핵심 구현​

  • Areas/dbclient/Controllers/QueryController.cs: query API 진입점입니다.
  • DataClient/QueryDataClient.cs: 계약 해석, 파라미터 바인딩, SQL 실행 핵심 구현입니다.
  • Extensions/DatabaseMapper.cs: XML statement와 데이터 원본 매핑을 관리합니다.
  • Events/DbClientRequestHandler.cs: 모듈 내부 DB 실행 요청을 처리합니다.
  • Events/ManagedRequestHandler.cs: 운영/관리 화면에서 전달되는 데이터 원본 변경 요청을 반영합니다.
  • Profiler: provider별 DB command 실행 프로파일을 수집합니다.

결과 변환과 메모리 사용​

일반 SQL 실행은 ExecuteReader → DataTableHelper.DataReaderToDataSet → 관계/메타 처리 → JSON 변환 순서로 진행합니다. 다중 결과 집합, 열 이름·타입·문자열 길이, 행 순서와 null 처리를 유지하며, 반환된 DataSet은 호출자가 해제합니다.

IgnoreResult=true인 입력은 현재 결과 집합을 끝까지 읽고 형식을 검증하면서 후속 BaseFieldMappings에 필요한 행만 보관합니다.

반환 형식후속 매핑에 사용할 행
Json, Scalar, NonQuery, Xml마지막 행
SchemeOnly, SQLText첫 행

첫 행을 보관할 때는 검증용 행 하나를 추가로 재사용합니다. 이 경로에서 다음 결과 집합으로 직접 이동하지 않으며, NonQuery의 영향받은 행 수는 기존과 같이 첫 Read 전에 누적합니다. Reader 종료와 트랜잭션 처리는 기존 실행 경로가 담당합니다.

Form 출력은 첫 행의 값을 사용하고, Grid/Chart 출력은 모든 행의 순서와 값을 유지합니다. 내부 컬렉션 용량 지정과 불필요한 배열/테이블 생성 제거에는 별도 설정이 필요하지 않습니다. 일반 결과의 전체 DataSet 구성은 관계 처리와 메타 생성을 위해 유지됩니다.

계약과 식별자​

계약은 기본적으로 다음 위치에 둡니다.

contracts/dbclient/{ApplicationID}/{ProjectID}/{TransactionID}.xml

쿼리 ID는 다음 형식입니다.

ApplicationID|ProjectID|TransactionID|StatementID

statement ID는 보통 GD01, LD01, MD01, DD01처럼 조회, 목록, 수정, 삭제 성격이 드러나도록 나눕니다. 계약에는 DataSourceID, SQL 본문, 입력 파라미터, 반환 형식을 함께 선언합니다.

런타임 쿼리 ID의 마지막 항목은 XML의 id와 최소 두 자리로 채운 seq를 합친 값입니다. 예를 들어 id="GD01", seq="0"이면 HDS|TST|TST010|GD0100처럼 요청합니다.

주요 설정​

설정설명
ContractBasePathdbclient XML 계약 루트 목록입니다.
DataSource애플리케이션/프로젝트별 DB provider와 연결 문자열입니다.
DefaultCommandTimeoutstatement의 timeout이 음수일 때 적용되는 기본 SQL 제한 시간입니다. 생략하거나 파싱에 실패하면 현재 매퍼는 0을 사용합니다.
IsContractFileWatching계약 파일 변경 감시 여부입니다.
IsTransactionLogging요청/응답 거래 로그 기록 여부입니다.
IsProfileLoggingDB provider 호출 프로파일 로그 기록 여부입니다.
SubscribeAction기본 수신 이벤트는 dbclient.Events.DbClientRequest, dbclient.Events.ManagedRequest입니다.

DataSource 예시는 다음과 같습니다.

{
"ApplicationID": "HDS",
"ProjectID": "*",
"DataSourceID": "DB01",
"DataProvider": "SQLite",
"ConnectionString": "URI=file:../sqlite/HDS/dbclient/HDS.db;Journal Mode=Off;BinaryGUID=False;DateTimeFormat=Ticks;Version=3;",
"IsEncryption": "N"
}

ack 또는 rdy의 AppSettings:IsConfigurationWatching이 true이면 실행 중 실제로 로드된 module.json의 DataSource 변경을 감지해 DatabaseMapper.DataSourceMappings를 다시 구성합니다. 새 목록 전체가 유효할 때만 기존 캐시를 교체하며, 오류가 있으면 이전 설정과 캐시를 유지합니다. 교체 완료 후 시작하는 요청부터 새 연결 정보를 사용하고 빈 배열은 캐시 삭제로 반영됩니다.

transact 연동​

transact 거래 계약에서는 CommandType을 D로 둡니다.

{
"ServiceID": "LD01",
"CommandType": "D",
"ReturnType": "Json"
}

라우팅 예시는 다음과 같습니다.

{
"HDS|*|D|D": "http://localhost:8421/dbclient/api/query",
"HDS|*|D|P": "http://localhost:8421/dbclient/api/query",
"HDS|*|D|T": "http://localhost:8421/dbclient/api/query"
}

운영 주의사항​

  • 연결 문자열과 DB 계정은 환경별 설정으로 분리하고 실제 비밀번호를 공개 저장소에 두지 않습니다.
  • IsProfileLogging은 성능 분석에는 유용하지만 SQL과 파라미터가 남을 수 있으므로 운영에서는 목적과 보관 기간을 명확히 합니다.
  • 계약 파일 hot reload를 사용할 때는 변경 배포와 refresh 시점을 운영 절차에 포함합니다.
  • SQL provider별 파라미터 타입과 날짜/숫자 변환 규칙이 다르므로 계약 작성 후 실제 provider에서 검증합니다.