libpq의 젠 토토 시스템은 등록된 젠 토토 핸들러에게 흥미로운 내용을 알리도록 설계되었습니다.libpq생성 또는 파괴와 같은 젠 토토PGconn그리고PGresult객체. 주요 사용 사례는 이를 통해 애플리케이션이 자신의 데이터를PGconn또는PGresult그리고 해당 데이터가 적절한 시기에 해제되었는지 확인하세요.
등록된 각 이벤트 핸들러는 다음과 같은 두 가지 데이터와 연결되어 있습니다.libpq불투명하게만무효 *포인터. 가 있습니다.통과젠 토토 핸들러가 등록될 때 애플리케이션에서 제공하는 포인터PGconn. 통과 포인터는의 수명 동안 변경되지 않습니다.PGconn그리고 모두PGresult10660_10753인스턴스 데이터시작하는 포인터NULL매번PGconn그리고PGresult. 이 포인터는를 사용하여 조작할 수 있습니다.PQinstanceData, PQsetInstanceData, PQresultInstanceData그리고PQresultSetInstanceData함수. 통과 포인터와 달리 a의 인스턴스 데이터는PGconn다음에 의해 자동으로 상속되지 않습니다.PGresult그것에서 생성되었습니다.libpq통과 및 인스턴스 데이터 포인터가 무엇을 가리키는지 알지 못하며(있는 경우) 이를 해제하려고 시도하지 않습니다. 이는 이벤트 핸들러의 책임입니다.
열거형PGEventId젠 토토 시스템이 처리하는 젠 토토 유형의 이름을 지정합니다. 모든 값의 이름은PGEVT. 각 이벤트 유형마다 이벤트 핸들러에 전달된 매개변수를 전달하는 해당 이벤트 정보 구조가 있습니다. 이벤트 유형은 다음과 같습니다.
PGEVT_REGISTER #등록 이벤트는 다음과 같은 경우에 발생합니다.PQregisterEventProc호출됩니다. 지금은 초기화하기에 가장 좋은 시기입니다.instanceData젠 토토 절차가 필요할 수 있습니다. 연결당 젠 토토 핸들러당 하나의 등록 젠 토토만 실행됩니다. 젠 토토 프로시저가 실패하면(0을 반환) 등록이 취소됩니다.
typedef 구조체
PGconn *콘;
PGEventRegister;
때PGEVT_REGISTER젠 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEvent등록 *. 이 구조에는PGconn그것은 다음에 있어야 합니다CONNECTION_OK상태; 전화하면 보장됨PQregisterEventProc상품을 얻은 직후PGconn. 실패 코드를 반환할 때 모든 정리는 no로 수행되어야 합니다PGEVT_CONNDESTROY젠 토토가 전송됩니다.
PGEVT_CONNRESET #연결 재설정 젠 토토는 완료 시 시작됩니다.PQreset또는PQresetPoll. 두 경우 모두 재설정이 성공한 경우에만 이벤트가 시작됩니다. 이벤트 프로시저의 반환 값은 다음에서 무시됩니다.PostgreSQLv15 이상. 그러나 이전 버전에서는 성공(0이 아님)을 반환하는 것이 중요합니다. 그렇지 않으면 연결이 중단됩니다.
typedef 구조체
PGconn *콘;
PGEventConnReset;
때PGEVT_CONNRESET젠 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventConnReset *. 포함되어 있지만PGconn방금 재설정되었으므로 모든 젠 토토 데이터는 변경되지 않습니다. 이 젠 토토는 연관된 모든 것을 재설정/다시 로드/재쿼리하는 데 사용되어야 합니다.instanceData. 젠 토토 프로시저가 처리에 실패하더라도 주의하세요PGEVT_CONNRESET, 여전히를 수신합니다.PGEVT_CONNDESTROY연결이 종료될 때의 젠 토토입니다.
PGEVT_CONNDESTROY #다음에 대한 응답으로 연결 파괴 이벤트가 시작됩니다.PQfinish. libpq에는 이 메모리를 관리할 수 있는 기능이 없으므로 해당 이벤트 데이터를 적절하게 정리하는 것은 이벤트 프로시저의 책임입니다. 정리하지 않으면 메모리 누수가 발생합니다.
typedef 구조체
PGconn *콘;
PGEventConnDestroy;
언제PGEVT_CONNDESTROY젠 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventConnDestroy *. 이 이벤트는 다음 날짜 이전에 시작됩니다.PQfinish다른 정리를 수행 중입니다. 실패를 표시할 방법이 없으므로 젠 토토 프로시저의 반환 값은 무시됩니다.PQfinish. 또한 젠 토토 프로시저 오류로 인해 원치 않는 메모리 정리 프로세스가 중단되어서는 안 됩니다.
PGEVT_RESULTCREATE #결과 생성 이벤트는 다음을 포함하여 결과를 생성하는 모든 쿼리 실행 함수에 대한 응답으로 시작됩니다.PQgetResult. 이 젠 토토는 결과가 성공적으로 생성된 후에만 시작됩니다.
typedef 구조체
PGconn *콘;
PGresult *결과;
PGEventResultCreate;
때PGEVT_RESULTCREATE젠 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventResultCreate *.콘은 결과를 생성하는 데 사용되는 연결입니다. 이곳은 무엇이든 초기화하기에 이상적인 장소입니다.instanceData결과와 연결되어야 합니다. 젠 토토 프로시저가 실패하면(0을 반환) 해당 젠 토토 프로시저는 결과의 남은 수명 동안 무시됩니다. 즉, 수신되지 않습니다.PGEVT_RESULTCOPY또는PGEVT_RESULTDESTROY이 결과 또는 여기에서 복사된 결과에 대한 젠 토토.
PGEVT_RESULTCOPY #다음에 대한 응답으로 결과 복사 이벤트가 시작됩니다.PQcopyResult. 이 젠 토토는 복사가 완료된 후에만 시작됩니다. 성공적으로 처리한 젠 토토 프로시저만PGEVT_RESULTCREATE또는PGEVT_RESULTCOPY소스 결과에 대한 젠 토토가 수신됩니다PGEVT_RESULTCOPY젠 토토.
typedef 구조체
const PGresult *src;
PGresult *dest;
PGEventResultCopy;
때 aPGEVT_RESULTCOPY젠 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventResultCopy *.src결과는 동안 복사된 것입니다.대상결과는 복사 대상입니다. 이 이벤트는 다음의 전체 복사본을 제공하는 데 사용될 수 있습니다.instanceData, 이후PQcopyResult그렇게 할 수 없습니다. 젠 토토 프로시저가 실패하면(0을 반환) 새 결과의 남은 수명 동안 해당 젠 토토 프로시저가 무시됩니다. 즉, 수신되지 않습니다.PGEVT_RESULTCOPY또는PGEVT_RESULTDESTROY해당 결과 또는 복사된 결과에 대한 젠 토토.
PGEVT_RESULTDESTROY #결과 삭제 이벤트는 다음에 대한 응답으로 시작됩니다.PQclear. libpq에는 이 메모리를 관리할 수 있는 기능이 없으므로 해당 이벤트 데이터를 적절하게 정리하는 것은 이벤트 프로시저의 책임입니다. 정리하지 않으면 메모리 누수가 발생합니다.
typedef 구조체
PGresult *결과;
PGEventResultDestroy;
언제PGEVT_RESULTDESTROY젠 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventResultDestroy *. 이 이벤트는 다음 날짜 이전에 시작됩니다.PQclear다른 정리를 수행 중입니다. 실패를 표시할 방법이 없으므로 젠 토토 프로시저의 반환 값은 무시됩니다.PQclear. 또한 젠 토토 프로시저 오류로 인해 원치 않는 메모리 정리 프로세스가 중단되어서는 안 됩니다.
PGEventProc #PGEventProc는 이벤트 프로시저, 즉 libpq에서 이벤트를 수신하는 사용자 콜백 함수에 대한 포인터에 대한 형식 정의입니다. 이벤트 프로시저의 서명은 다음과 같아야 합니다.
int eventproc(PGEventId evtId, void *evtInfo, void *passThrough)
그evtId매개변수는 다음을 나타냅니다.PGEVT젠 토토가 발생했습니다.evtInfo22221_22330통과매개변수는 다음에 제공된 포인터입니다.PQregisterEventProc젠 토토 프로시저가 등록되었을 때. 함수는 성공하면 0이 아닌 값을 반환하고, 실패하면 0을 반환해야 합니다.
특정 젠 토토 프로시저는 한 번만 등록될 수 있습니다.PGconn. 프로시저의 주소가 연관된 인스턴스 데이터를 식별하는 조회키로 사용되기 때문입니다.
Windows에서 함수는 두 개의 서로 다른 주소를 가질 수 있습니다. 하나는 DLL 외부에서 볼 수 있고 다른 하나는 DLL 내부에서 볼 수 있습니다. 이 주소 중 하나만 사용된다는 점에 주의해야 합니다.libpq의 젠 토토 절차 기능을 사용하지 않으면 혼란이 발생합니다. 작동하는 코드 작성을 위한 가장 간단한 규칙은 젠 토토 프로시저가 선언되었는지 확인하는 것입니다.정적. 프로시저의 주소를 자체 소스 파일 외부에서 사용할 수 있어야 하는 경우 주소를 반환하는 별도의 함수를 노출하세요.
PQregisterEventProc #libpq를 사용하여 이벤트 콜백 프로시저를 등록합니다.
int PQregisterEventProc(PGconn *conn, PGEventProc proc,
const char *이름, void *passThrough);
젠 토토 프로시저는 각각에 한 번씩 등록되어야 합니다.PGconn젠 토토를 수신하고 싶습니다. 연결에 등록할 수 있는 젠 토토 프로시저 수에는 메모리 외에는 제한이 없습니다. 이 함수는 성공하면 0이 아닌 값을 반환하고 실패하면 0을 반환합니다.
그proc인수는 libpq 이벤트가 시작될 때 호출됩니다. 해당 메모리 주소는 조회에도 사용됩니다.인스턴스데이터.이름인수는 오류 메시지에서 젠 토토 프로시저를 참조하는 데 사용됩니다. 이 값은 될 수 없습니다.NULL또는 길이가 0인 문자열. 이름 문자열은PGconn, 따라서 통과된 것은 오래 지속될 필요가 없습니다.통과포인터가 다음에 전달되었습니다.proc이벤트가 발생할 때마다. 이 인수는 다음과 같습니다.NULL.
PQsetInstanceData #연결을 설정합니다콘'sinstanceData절차용proc에데이터. 성공하면 0이 아닌 값을 반환하고 실패하면 0을 반환합니다. (실패는 다음의 경우에만 가능합니다.proc다음에 제대로 등록되지 않았습니다.콘.)
int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data);
PQinstanceData #연결을 반환합니다.콘's인스턴스데이터프로시저와 연결됨proc, 또는NULL아무것도 없다면.
void *PQinstanceData(const PGconn *conn, PGEventProc proc);
PQresultSetInstanceData #결과를 설정합니다instanceDataforproc에데이터. 성공하면 0이 아닌 값을 반환하고 실패하면 0을 반환합니다. (실패는 다음의 경우에만 가능합니다.proc결과에 제대로 등록되지 않았습니다.)
int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data);
다음으로 표시되는 저장소는 다음과 같습니다.데이터다음에 의해 설명되지 않습니다.PQresultMemorySize, 다음을 사용하여 할당되지 않은 경우PQresultAlloc. (그렇게 하면 결과가 삭제될 때 해당 저장소를 명시적으로 해제할 필요가 없기 때문에 권장됩니다.)
PQresultInstanceData #결과를 반환합니다인스턴스데이터다음과 연결됨proc또는NULL아무것도 없다면.
void *PQresultInstanceData(const PGresult *res, PGEventProc proc);
다음은 libpq 연결 및 결과와 관련된 개인 데이터를 관리하는 기본 예입니다.
/* libpq 이벤트에 필요한 헤더(참고: libpq-fe.h 포함) */
#include <libpq-events.h
/* 인스턴스 데이터 */
typedef 구조체
int n;
문자 *str;
마이데이터;
/* PGEventProc */
static int myEventProc(PGEventId evtId, void *evtInfo, void *passThrough);
정수
메인(공허)
마이데이터 *데이터;
PGresult *res;
PGconn *콘 =
PQconnectdb("dbname=postgres 옵션=-csearch_path=");
if (PQstatus(conn) != CONNECTION_OK)
/* PQerrorMessage의 결과에는 후행 개행 문자가 포함됩니다 */
fprintf(stderr, "%s", PQerrorMessage(conn));
PQfinish(콘);
1을 반환합니다.
/* 이벤트를 수신해야 하는 모든 연결에서 한 번 호출됩니다.
* myEventProc에 PGEVT_REGISTER를 보냅니다.
*/
if (!PQregisterEventProc(conn, myEventProc, "mydata_proc", NULL))
fprintf(stderr, "PGEventProc를 등록할 수 없습니다\n");
PQfinish(콘);
1을 반환합니다.
/* conn 인스턴스 데이터를 사용할 수 있습니다 */
데이터 = PQinstanceData(conn, myEventProc);
/* myEventProc에 PGEVT_RESULTCREATE를 보냅니다 */
res = PQexec(conn, "SELECT 1 + 1");
/* 결과 인스턴스 데이터를 사용할 수 있습니다 */
데이터 = PQresultInstanceData(res, myEventProc);
/* PG_COPYRES_EVENTS가 사용되면 PGEVT_RESULTCOPY를 myEventProc에 보냅니다. */
res_copy = PQcopyResult(res, PG_COPYRES_TUPLES | PG_COPYRES_EVENTS);
/* PG_COPYRES_EVENTS가 있는 경우 결과 인스턴스 데이터를 사용할 수 있습니다.
* PQcopyResult 호출 중에 사용됩니다.
*/
데이터 = PQresultInstanceData(res_copy, myEventProc);
/* 두 지우기 모두 myEventProc에 PGEVT_RESULTDESTROY를 보냅니다. */
PQclear(res);
PQclear(res_copy);
/* myEventProc에 PGEVT_CONNDESTROY를 보냅니다 */
PQfinish(콘);
0을 반환합니다.
정적 정수
myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
스위치(evtId)
PGEVT_REGISTER:
PGEventRegister *e = (PGEventRegister *)evtInfo;
mydata *data = get_mydata(e-conn);
/* 앱별 데이터를 연결과 연결 */
PQsetInstanceData(e-conn, myEventProc, data);
부서지다;
사례 PGEVT_CONNRESET:
PGEventConnReset *e = (PGEventConnReset *)evtInfo;
mydata *data = PQinstanceData(e-conn, myEventProc);
만약 (데이터)
memset(data, 0, sizeof(mydata));
부서지다;
사례 PGEVT_CONNDESTROY:
PGEventConnDestroy *e = (PGEventConnDestroy *)evtInfo;
mydata *data = PQinstanceData(e-conn, myEventProc);
/* conn이 파괴되기 때문에 무료 인스턴스 데이터 */
만약 (데이터)
free_mydata(데이터);
부서지다;
PGEVT_RESULTCREATE:
PGEventResultCreate *e = (PGEventResultCreate *)evtInfo;
mydata *conn_data = PQinstanceData(e-conn, myEventProc);
mydata *res_data = dup_mydata(conn_data);
/* 앱별 데이터를 결과와 연결합니다(conn에서 복사) */
PQresultSetInstanceData(e-result, myEventProc, res_data);
부서지다;
사례 PGEVT_RESULTCOPY:
PGEventResultCopy *e = (PGEventResultCopy *)evtInfo;
mydata *src_data = PQresultInstanceData(e-src, myEventProc);
mydata *dest_data = dup_mydata(src_data);
/* 앱별 데이터를 결과와 연결(결과에서 복사) */
PQresultSetInstanceData(e-dest, myEventProc, dest_data);
부서지다;
사례 PGEVT_RESULTDESTROY:
PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo;
mydata *data = PQresultInstanceData(e-result, myEventProc);
/* 결과가 삭제되므로 무료 인스턴스 데이터 */
만약 (데이터)
free_mydata(데이터);
부서지다;
/* 알 수 없는 이벤트 ID, true를 반환합니다. */
기본값:
휴식;
사실을 반환; /* 이벤트 처리 성공 */
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.