libpq의 롤 토토 시스템은 등록된 롤 토토 핸들러에게 흥미로운 내용을 알리도록 설계되었습니다.libpq롤 토토, 예: 생성 또는 파괴PGconn그리고PGresult객체. 주요 용도 이는 애플리케이션이 자신의 데이터를 연결할 수 있게 해준다는 것입니다. 와 함께PGconn또는PGresult그리고 해당 데이터가 다음 시점에 해제되었는지 확인하세요. 적절한 시간.
등록된 각 롤 토토 핸들러는 두 개의 롤 토토 핸들러와 연관되어 있습니다.
알려진 데이터libpq다음으로만
불투명공허 *포인터. 가 있습니다.통과다음에서 제공하는 포인터
이벤트 핸들러가 a에 등록된 경우의 애플리케이션PGconn. 통과 포인터는 절대로
의 삶에 대한 변화PGconn그리고 모두PGresults가 생성되었습니다.
따라서 사용되는 경우 수명이 긴 데이터를 가리켜야 합니다. 게다가 거기에
는인스턴스 데이터포인터, 이는
매번 NULL로 시작합니다.PGconn그리고PGresult. 이 포인터는
를 사용하여 조작됨PQinstanceData, PQsetInstanceData, PQresultInstanceData그리고PQsetResultInstanceData함수. 참고하세요
통과 포인터와 달리 a의 인스턴스 데이터PGconn다음에 의해 자동으로 상속되지 않습니다.PGresult그것으로부터 생성되었습니다.libpq무엇을 모릅니다
통과 및 인스턴스 데이터 포인터는 (있는 경우) 및
결코 그들을 해방시키려고 시도하지 않을 것입니다. 그것은
이벤트 핸들러입니다.
열거형PGEventId유형의 이름을 지정합니다. 롤 토토 시스템이 처리하는 롤 토토. 그 모든 가치는 로 시작하는 이름PGEVT. 각각에 대해 이벤트 유형에 해당하는 이벤트 정보 구조가 있습니다. 이벤트 핸들러에 전달된 매개변수를 전달합니다. 이벤트 유형은 다음과 같습니다.
등록 이벤트는 다음과 같은 경우에 발생합니다.PQregisterEventProc호출됩니다. 그것은
초기화하기에 이상적인 시간입니다.인스턴스데이터롤 토토 절차가 필요할 수 있습니다.
롤 토토 핸들러당 하나의 등록 롤 토토만 실행됩니다.
연결당. 롤 토토 프로시저가 실패하면
등록이 중단되었습니다.
typedef 구조체
PGconn *콘;
PGEventRegister;
때PGEVT_REGISTER롤 토토
수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEvent등록 *. 이 구조
포함PGconn그러면 됩니다
에 있다CONNECTION_OK상태;
전화하면 보장됨PQregisterEventProc직후
좋은 것을 얻는다PGconn. 언제
실패 코드를 반환하면 모든 정리 작업을 수행해야 합니다.
아니오로PGEVT_CONNDESTROY롤 토토
발송됩니다.
연결 재설정 롤 토토는 완료 시 시작됩니다.PQreset또는PQresetPoll. 두 경우 모두 롤 토토는
재설정이 성공한 경우에만 실행됩니다. 롤 토토의 경우
절차가 실패하면 전체 연결 재설정이 실패합니다.
그만큼PGconn넣어짐CONNECTION_BAD상태 및PQresetPoll반환할 것이다PGRES_POLLING_FAILED.
typedef 구조체
PGconn *콘;
PGEventConnReset;
때PGEVT_CONNRESET롤 토토 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventConnReset *. 비록 포함됨PGconn그냥 재설정하면 모든 롤 토토 데이터가 변경되지 않습니다. 이번 롤 토토 연관된 모든 것을 재설정/다시 로드/재쿼리하는 데 사용해야 합니다.instanceData. 참고하세요. 롤 토토 프로시저가 처리되지 않습니다.PGEVT_CONNRESET, 여전히를 수신합니다.PGEVT_CONNDESTROY롤 토토 발생 시 연결이 종료되었습니다.
다음에 대한 응답으로 연결 파괴 이벤트가 시작됩니다.PQfinish. 이벤트입니다
해당 이벤트를 적절하게 정리하는 프로시저의 책임
libpq는 이 메모리를 관리할 수 있는 능력이 없기 때문에 데이터를 사용합니다.
정리하지 않으면 메모리 누수가 발생합니다.
typedef 구조체
PGconn *콘;
PGEventConnDestroy;
때PGEVT_CONNDESTROY롤 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventConnDestroy *. 이번 이벤트는
이전에 해고됨PQfinish다른 정리를 수행 중입니다. 반환 값은
롤 토토 프로시저는 무시됩니다. 왜냐하면 방법이 없기 때문입니다.
실패를 나타냄PQfinish. 또한, 롤 토토 절차
실패로 인해 정리 프로세스가 중단되어서는 안 됩니다.
원치 않는 기억.
결과 생성 이벤트는 다음에 대한 응답으로 시작됩니다.
결과를 생성하는 쿼리 실행 함수,
포함PQgetResult. 이
롤 토토는 결과가 나온 후에만 시작됩니다.
성공적으로 생성되었습니다.
typedef 구조체
PGconn *콘;
PGresult *결과;
PGEventResultCreate;
때PGEVT_RESULTCREATE롤 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventResultCreate *.콘생성하는 데 사용되는 연결입니다.
결과. 이곳은 무엇이든 초기화하기에 이상적인 장소입니다.인스턴스데이터그건 그래야만 해
결과와 연관됩니다. 이벤트 프로시저가 실패하는 경우
결과는 삭제되고 실패는 취소됩니다.
전파. 이벤트 프로시저는 다음을 시도해서는 안 됩니다.PQclear결과 객체
그 자체로. 실패 코드를 반환하면 모든 정리
아니요로 수행되어야 합니다.PGEVT_RESULTDESTROY이벤트는 다음과 같습니다
보냈습니다.
다음에 대한 응답으로 결과 복사 이벤트가 시작됩니다.PQcopyResult. 이번 롤 토토
복사가 완료된 후에만 실행됩니다. 롤 토토만
성공적으로 처리한 절차PGEVT_RESULTCREATE또는PGEVT_RESULTCOPY소스에 대한 롤 토토
결과가 수신됩니다PGEVT_RESULTCOPY롤 토토.
typedef 구조체
const PGresult *src;
PGresult *dest;
PGEventResultCopy;
때PGEVT_RESULTCOPY롤 토토 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventResultCopy *.src결과는 다음 동안 복사된 것입니다.대상결과는 사본입니다 목적지. 이 이벤트는 심층적인 정보를 제공하는 데 사용될 수 있습니다. 사본인스턴스데이터, 이후PQcopyResult그렇게 할 수 없습니다. 만약에 롤 토토 프로시저가 실패하면 전체 복사 작업이 실패하고대상결과는 삭제됩니다. 실패 코드를 반환하면 모든 정리 아니요로 수행되어야 합니다.PGEVT_RESULTDESTROY이벤트가 다음에 대해 전송됩니다. 목적지 결과.
결과 파괴 이벤트는 다음에 대한 응답으로 시작됩니다.PQclear. 이벤트입니다
해당 이벤트를 적절하게 정리하는 프로시저의 책임
libpq는 이 메모리를 관리할 수 있는 능력이 없기 때문에 데이터를 사용합니다.
정리하지 않으면 메모리 누수가 발생합니다.
typedef 구조체
PGresult *결과;
PGEventResultDestroy;
때 aPGEVT_RESULTDESTROY롤 토토가 수신되었습니다.evtInfo포인터는 a로 캐스팅되어야 합니다.PGEventResultDestroy *. 이번 이벤트는
이전에 해고됨PQclear다른 정리를 수행 중입니다. 반환 값은
롤 토토 프로시저는 무시됩니다. 왜냐하면 방법이 없기 때문입니다.
실패를 나타냄PQclear. 또한, 롤 토토 절차
실패로 인해 정리 프로세스가 중단되어서는 안 됩니다.
원치 않는 기억.
PGEventProc다음에 대한 형식 정의입니다. 이벤트 프로시저에 대한 포인터, 즉 사용자 libpq에서 이벤트를 수신하는 콜백 함수입니다. 는 이벤트 프로시저의 서명은 다음과 같아야 합니다.
int eventproc(PGEventId evtId, void *evtInfo, void *passThrough)
그evtId매개변수
어느 것을 나타냅니다PGEVT롤 토토
발생했습니다.evtInfo포인터
얻으려면 적절한 구조 유형으로 캐스팅되어야 합니다.
이벤트에 대한 추가 정보. 그만큼통과매개변수는 포인터입니다.
에 제공됨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 이벤트가 시작될 때 호출됩니다. 그 메모리 주소는 조회에도 사용됨instanceData.이름인수는 다음을 참조하는 데 사용됩니다. 오류 메시지의 이벤트 프로시저. 이 값은 NULL 또는 길이가 0인 문자열입니다. 이름 문자열이 복사됩니다. 안으로PGconn그래서 뭔데요? 합격이 오래 지속될 필요는 없습니다.통과포인터가 다음으로 전달되었습니다.proc롤 토토가 발생할 때마다. 이 인수는 NULL일 수 있습니다.
PQsetInstanceData proc에 대한 conn의 인스턴스 데이터를 데이터로 설정합니다. 이 성공하면 0이 아닌 값을 반환하고 실패하면 0을 반환합니다. (실패는 proc이 실행되지 않은 경우에만 가능합니다. 연결에 올바르게 등록되었습니다.)
int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data);
PQinstanceData proc과 관련된 conn의 인스턴스 데이터를 반환합니다. 또는 아무것도 없으면 NULL입니다.
void *PQinstanceData(const PGconn *conn, PGEventProc proc);
PQresultSetInstanceData proc에 대한 결과의 인스턴스 데이터를 데이터로 설정합니다. 이 성공하면 0이 아닌 값을 반환하고 실패하면 0을 반환합니다. (실패는 proc이 실행되지 않은 경우에만 가능합니다. 결과에 제대로 등록되었습니다.)
int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data);
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 *conn = PQconnectdb("dbname = postgres");
if (PQstatus(conn) != CONNECTION_OK)
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에서 복사) */
PQsetResultInstanceData(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);
/* 앱별 데이터를 결과와 연결(결과에서 복사) */
PQsetResultInstanceData(e-dest, myEventProc, dest_data);
부서지다;
사례 PGEVT_RESULTDESTROY:
PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo;
mydata *data = PQresultInstanceData(e-result, myEventProc);
/* 결과가 삭제되므로 무료 인스턴스 데이터 */
만약 (데이터)
free_mydata(데이터);
부서지다;
/* 알 수 없는 이벤트 ID, TRUE를 반환합니다. */
기본값:
휴식;
TRUE를 반환합니다. /* 이벤트 처리 성공 */