이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은에 대해 같은 페이지를 볼 수 있습니다PostgreSQL : 문서 : 17 : 32.14. 메이저 토토 사이트 시스템버전 또는 위에 나열된 다른 지원되는 버전 중 하나입니다.

30.12. 롤 토토 시스템

libpq의 롤 토토 시스템입니다 등록 된 롤 토토 핸들러에게 흥미로운 것에 대해 알리도록 설계되었습니다libpq롤 토토와 같은 롤 토토 창조 또는 파괴pgconnandpgresult개체. 주요 용도 사례는 응용 프로그램이 자신의 데이터를 연관시킬 수 있도록하는 것입니다. A와 함께pgconn또는pgresult그리고 해당 데이터가 해당되는지 확인하십시오 적절한 시간.

각 등록 된 롤 토토 핸들러는 두 조각과 관련이 있습니다. 알려진 데이터libpq만 불투명체void *포인터.Passthrough포인터가 제공합니다 롤 토토 핸들러가 A에 등록 된 경우 응용 프로그램pgconn. 패스 스루 포인터는 결코 없습니다 삶의 변화pgconn및 allpgresults에서 생성 된; 따라서 사용되면 오래 지속되는 데이터를 가리켜 야합니다. 또한 거기에인스턴스 데이터포인터 모든 곳에서 널 시작pgconnandpgresult. 이 포인터는 될 수 있습니다 를 사용하여 조작PQINSTANCETA, PQSETINSTANCETA, pqresultinstancedataandPQSETRESULTINSTANCETA함수. 주목하십시오 패스 스루 포인터와 달리 A의 인스턴스 데이터pgconn에 의해 자동으로 상속되지 않습니다pgresults에서 생성되었습니다.libpq무엇을 모릅니다 통과 및 인스턴스 데이터 포인터는 (무엇이든)를 가리 킵니다. 그들을 해방 시키려고하지 않을 것입니다 - 그것은 의무입니다. 이벤트 핸들러.

30.12.1. 롤 토토 유형

ENUMpgeventid유형의 이름을 지정합니다 롤 토토 시스템에서 처리하는 롤 토토. 모든 가치가 있습니다 로 시작하는 이름PGEVT. 각각에 대해 이벤트 유형, 해당 이벤트 정보 구조가 있습니다. 전달 된 매개 변수를 이벤트 핸들러로 전달합니다. 이벤트 유형은 다음과 같습니다.

pgevt_register

레지스터 롤 토토는 발생합니다PQREGISTEREVENTPROC호출됩니다. 그것은 모든 초기화에 이상적인 시간instanceata롤 토토 절차가 필요할 수 있습니다. 롤 토토 핸들러 당 하나의 레지스터 롤 토토 만 해고됩니다. 연결 당. 롤 토토 절차가 실패하면 등록이 중단되었습니다.

typedef struct

    pgconn *conn;
 pgeventRegister;

apgevt_register롤 토토 접수,evtinfo포인터가 a에 캐스트해야합니다pgeventRegister *. 이 구조 포함pgconnConnection_ok상태; 전화가 보장 보장PQREGISTEREVENTPROC직후 좋은 획득pgconn. 언제 실패 코드를 반환하면 모든 정리가 수행되어야합니다 아니요PGEVT_CONNDESTROY롤 토토 발송됩니다.

PGEVT_CONNRESET

연결 재설정 롤 토토는 완료되면pqreset또는pqresetpoll. 두 경우 모두 롤 토토 재설정이 성공한 경우에만 해고됩니다. 롤 토토 인 경우 프로 시저가 실패하면 전체 연결 재설정이 실패합니다. 그만큼pgconnConnection_Bad상태 및pqresetpoll복귀 할 것입니다pgres_polling_failed.

typedef struct

    pgconn *conn;
 pgeventconnreset;

aPGEVT_CONNRESET롤 토토 접수,evtinfo포인터가 a에 캐스트해야합니다pgeventconnreset *. 비록 포함pgconn그냥이었다 재설정, 모든 롤 토토 데이터는 변경되지 않았습니다. 이 행사 관련된 모든 것을 재설정/새로 고침/요청하는 데 사용해야합니다instanceata. 더라도 롤 토토 절차가 처리되지 않습니다PGEVT_CONNRESET, 여전히 a를받을 것입니다.PGEVT_CONNDESTROY연결이 닫혔습니다.

PGEVT_CONNDESTROY

연결 파괴 롤 토토가 해고되어pqfinish. 롤 토토입니다 롤 토토를 올바르게 정리하는 절차의 책임 LIBPQ로서의 데이터는이 메모리를 관리 할 능력이 없습니다. 정리하지 않으면 메모리 누출이 발생합니다.

typedef struct

    pgconn *conn;
 pgeventconndestroy;

언제pgevt_conndestroy롤 토토가 접수되었습니다.evtinfo포인터가 a에 캐스트해야합니다pgeventconndestroy *. 이 이벤트입니다 이전에 해고pqfinish다른 정리 수행. 의 반환 값 방법이 없기 때문에 롤 토토 절차는 무시됩니다. 실패를 나타내는pqfinish. 또한 롤 토토 절차 실패는 청소 과정을 중단해서는 안됩니다 원치 않는 기억.

pgevt_resultcreate

결과 생성 롤 토토는 어떤 것에 대응하여 해고됩니다. 결과를 생성하는 쿼리 실행 기능 포함pqgetresult. 이것 결과는 결과가 발생한 후에 만 해고됩니다. 성공적으로 만들어졌습니다.

typedef struct

    pgconn *conn;
    pgresult *결과;
 pgeventresultcreate;

apgevt_resultcreate롤 토토가 접수되었습니다.evtinfo포인터가 a에 캐스트해야합니다pgeventresultcreate *. 그만큼conn생성에 사용되는 연결입니다 결과. 이곳은 모든 것을 초기화하기에 이상적인 장소입니다instanceata그것은 필요합니다 결과와 관련이 있습니다. 롤 토토 절차가 실패하면 결과가 지워지고 실패는 전파. 롤 토토 절차는 시도해서는 안됩니다PQCLEAR결과 객체 그 자체로. 실패 코드를 반환 할 때는 모두 정리하십시오 아니오로 수행해야합니다pgevt_resultdestroy롤 토토가 될 것입니다 전송된.

pgevt_resultcopy

결과 사본 롤 토토가 응답하여 해고됩니다pqcopyresult. 이 행사 사본이 완료된 후에 만 해고됩니다. 롤 토토 만 롤 토토 성공적으로 처리 한 절차pgevt_resultcreate또는pgevt_resultcopy소스의 롤 토토 결과가 수신됩니다pgevt_resultcopy롤 토토.

typedef struct

    const pgresult *src;
    pgresult *dest;
 pgeventresultcopy;

언제pgevt_resultcopy롤 토토 접수,Evtinfo포인터가 a에 캐스트해야합니다pgeventresultcopy *. 그만큼SRC결과는 복사 한 내용입니다dest결과는 사본입니다 목적지. 이 롤 토토는 깊은 곳을 제공하는 데 사용될 수 있습니다 사본instanceata이후pqcopyresult그렇게 할 수 없습니다. 만약에 롤 토토 절차가 실패하면 전체 사본 작업이 발생합니다 실패와dest결과 지우십시오. 실패 코드를 반환 할 때는 모두 정리하십시오 아니오로 수행해야합니다pgevt_resultdestroy롤 토토가 발송됩니다 목적지 결과.

pgevt_resultdestroy

결과 파괴 롤 토토는 A에 대한 응답으로 해고되었습니다PQCLEAR. 롤 토토입니다 롤 토토를 올바르게 정리하는 절차의 책임 LIBPQ로서의 데이터는이 메모리를 관리 할 능력이 없습니다. 정리하지 않으면 메모리 누출이 발생합니다.

typedef struct

    pgresult *결과;
 pgeventresultdestroy;

언제pgevt_resultdestroy롤 토토가 접수되었습니다.evtinfo포인터가 a에 캐스트해야합니다pgeventresultdestroy *. 이 이벤트입니다 이전에 해고PQCLEAR다른 청소 수행. 의 반환 값 방법이 없기 때문에 롤 토토 절차는 무시됩니다. 실패를 나타내는PQCLEAR. 또한 롤 토토 절차 실패는 청소 과정을 중단해서는 안됩니다 원치 않는 기억.

30.12.2. 롤 토토 콜백 절차

pgeventproc

pgeventproc는 typedef입니다 이벤트 절차, 즉 사용자에 대한 포인터 LIBPQ로부터 이벤트를 수신하는 콜백 함수. 그만큼 이벤트 절차의 서명은이어야합니다.

int eventProc (pgeventid evtid, void *evtinfo, void *passthrough)

theevtid매개 변수 어느 것을 나타냅니다pgevt이벤트 발생했습니다. 그만큼evtinfo포인터 얻기 위해 적절한 구조 유형으로 캐스트해야합니다. 이벤트에 대한 추가 정보. 그만큼Passthrough매개 변수는 포인터입니다 제공PQREGISTEREVENTPROC롤 토토 시점 절차가 등록되었습니다. 함수는 a 성공하면 0이 아닌 값이 실패하면 0입니다.

특정 롤 토토 절차 만 등록 할 수 있습니다 한 번pgconn. 이것은 절차의 주소는 조회로 사용되기 때문에 관련 인스턴스 데이터를 식별하는 키

주의

Windows에서는 기능이 서로 다를 수 있습니다 주소 : 하나는 DLL 외부에서 볼 수 있습니다 DLL 내부에서 보이는 또 다른. 하나 야 이 주소 중 하나만이라도 조심하십시오 와 함께libpq의 이벤트 처리 기능은 그렇지 않으면 혼란이 발생합니다. 그만큼 작동하는 코드를 작성하는 가장 간단한 규칙입니다 이벤트 절차가 선언되도록정적. 만약 절차 주소는 외부에서 사용할 수 있어야합니다 자체 소스 파일, 별도의 기능을 노출시킵니다 주소를 반환하십시오.

30.12.3. 이벤트 지원 기능

PQREGISTEREVENTPROC

롤 토토 콜백 절차를 LIBPQ로 등록합니다.

int pqregistereventProc (pgconn *conn, pgeventproc Proc,
                                const char *name, void *passthrough);

롤 토토 절차는 각각에 한 번 등록해야합니다pgconn당신은 받고 싶습니다 롤 토토. 메모리 외에는 제한이 없습니다 등록 할 수있는 이벤트 절차 수 연결과 함께. 함수는 0이 아닌 값을 반환합니다 실패하면 성공하고 0이되면

theProc인수가 될 것입니다 LIBPQ 롤 토토가 발사 될 때 호출됩니다. 메모리 주소입니다 또한 조회에 익숙해instanceata. 그만큼이름인수는 오류 메시지의 이벤트 절차. 이 가치는 될 수 없습니다 NULL 또는 제로 길이 문자열. 이름 문자열이 복사됩니다 에pgconn통과 된 것은 오래 지속될 필요는 없습니다. 그만큼Passthrough포인터가 전달됩니다Proc롤 토토가 발생할 때마다. 이 주장은 무일하다.

PQSETINSTANCETA

Proc에 대한 Conn의 Instancedata를 데이터로 설정합니다. 이것 성공을 위해 0이 아닌 반환하고 실패로 0이됩니다. (실패는 Proc가없는 경우에만 가능합니다. Conn에 올바르게 등록되었습니다.)

int pqsetinstanctata (pgconn *conn, pgeventproc proc, void *data);
PQINSTANCETA

Proc와 관련된 Conn의 Instanceata를 반환합니다. 또는 없으면 null.

void *pqinstancedata (const pgconn *conn, pgeventproc proc);
pqresultsetinstancedata

Proc에 대한 결과의 instancedata를 데이터로 설정합니다. 이것 성공을 위해 0이 아닌 반환하고 실패로 0이됩니다. (실패는 Proc가없는 경우에만 가능합니다. 결과에 올바르게 등록되었습니다.)

int pqresultsetinstancedata (pgresult *res, pgeventproc proc, void *data);
PQRESULTINSTANCETA

관련된 instanceata를 반환합니다 Proc, 또는 NOLL이없는 경우 NULL.

void *pqresultinstancedata (const pgresult *res, pgeventproc proc);

30.12.4. 롤 토토 예

개인 데이터 관리의 골격 예입니다 LIBPQ 연결 및 결과와 관련이 있습니다.

/ * LIBPQ 이벤트에 필수 헤더 (참고 : libpq-fe.h 포함) */
#include <libpq-events.h

/ * instancedata */
typedef struct

    int n;
    char *str;
 myData;

/ * pgeventProc */
정적 int myeventProc (pgeventid evtid, void *evtinfo, void *passthrough);

int
메인 (void)

    MyData *데이터;
    pgresult *res;
    pgconn *conn = pqconnectdb ( "dbname = postgres");

    if (pqstatus (conn)! = connection_ok)

        fprintf (stderr, "데이터베이스 연결 실패 : %s",
                pqerrormessage (conn));
        pqfinish (conn);
        반환 1;

    /* 이벤트를 수신 해야하는 모든 연결에서 한 번 호출.
     * pgevt_register를 MyeventProc에 보냅니다.
     */
    if (! pqregistereventProc (Conn, MyEventProc, "MyData_Proc", NULL))))

        fprintf (stderr, "pgeventproc \ n 등록 할 수 없음);
        pqfinish (conn);
        반환 1;

    / * Conn Instancedata를 사용할 수 있습니다 */
    data = pqinstancedata (Conn, MyeventProc);

    / * pgevt_resultcreate를 MyeventProc */로 보냅니다.
    res = pqexec (conn, "select 1 + 1");

    / * 결과 instanceata를 사용할 수 있습니다 */
    data = pqresultinstancedata (res, myeventproc);

    / * pg_copyres_events가 사용되는 경우 pgevt_resultcopy를 MyeventProc */로 보냅니다.
    res_copy = pqcopyresult (res, pg_copyres_tuples | pg_copyres_events);

    /* pg_copyres_events 인 경우 결과 instancedata를 사용할 수 있습니다
     * pqcopyresult 호출 중에 사용됩니다.
     */
    data = pqresultinstancedata (res_copy, myeventProc);

    / * 두 가지 모두 PGEVT_RESULTDESTROY를 MyEventProc */에 보냅니다.
    PQCLEAR (RES);
    pqclear (res_copy);

    / * PGEVT_CONNDESTROY를 MyEventProc */로 보냅니다.
    pqfinish (conn);

    반환 0;

정적 int
MyeventProc (pgeventid evtid, void *evtinfo, void *passthrough)

    스위치 (evtid)

        CASE PGEVT_REGISTER :

            pgeventregister *e = (pgeventregister *) evtinfo;
            myData *data = get_mydata (e- conn);

            / * 앱 특정 데이터를 연결 */
            pqsetinstancedata (e- conn, myeventProc, data);
            부서지다;

        CASE PGEVT_CONNRESET :

            pgeventconnreset *e = (pgeventconnreset *) evtinfo;
            myData *data = pqinstancedata (e- conn, myeventProc);

            if (데이터)
              memset (data, 0, sizeof (mydata));
            부서지다;

        사례 PGEVT_CONNDESTROY :

            pgeventconndestroy *e = (pgeventconndestroy *) evtinfo;
            myData *data = pqinstancedata (e- conn, myeventProc);

            / * 무료 인스턴스 데이터 Conn이 파괴 되었기 때문에 */
            if (데이터)
              free_mydata (데이터);
            부서지다;

        CASE 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);
            부서지다;

        CASE 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);
            부서지다;

        CASE PGEVT_RESULTDESTROY :

            pgeventresultdestroy *e = (pgeventresultdestroy *) evtinfo;
            myData *data = pqresultinstancedata (e- result, myeventProc);

            / * 결과가 파괴 되었기 때문에 무료 인스턴스 데이터 */
            if (데이터)
              free_mydata (데이터);
            부서지다;

        /* 알 수없는 이벤트 ID, 그냥 true를 반환하십시오. */
        기본:
            부서지다;

    진실을 반환하십시오. / * 이벤트 처리 성공 */