32.4. ÐÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð¾Ð±ÑабоÑка команд #
ФÑнкÑÐ¸Ñ PQexec Ñ
оÑоÑо подÑ
Ð¾Ð´Ð¸Ñ Ð´Ð»Ñ Ð¾ÑпÑавки команд ÑеÑвеÑÑ Ð² ноÑмалÑнÑÑ
, ÑинÑ
ÑоннÑÑ
пÑиложениÑÑ
. Ðднако она Ð¸Ð¼ÐµÐµÑ ÑÑд недоÑÑаÑков, коÑоÑÑе могÑÑ Ð¸Ð¼ÐµÑÑ Ð·Ð½Ð°Ñение Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑÑÑ
полÑзоваÑелей:
PQexecÐ¾Ð¶Ð¸Ð´Ð°ÐµÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ. Ðднако пÑиложение Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð·Ð°Ð½ÑÑо Ñем-Ñо дÑÑгим (напÑимеÑ, обÑабаÑÑваÑÑ Ð°ÐºÑивноÑÑÑ Ð² полÑзоваÑелÑÑком инÑеÑÑейÑе), в Ñаком ÑлÑÑае блокиÑовка пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² ожидании оÑвеÑа бÑÐ´ÐµÑ Ð½ÐµÐ¶ÐµÐ»Ð°ÑелÑной.ÐоÑколÑÐºÑ Ð²Ñполнение клиенÑÑкого пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿ÑиоÑÑанавливаеÑÑÑ, пока оно Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ ÑезÑлÑÑаÑа, Ñо пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑÑÑдно ÑеÑиÑÑ, ÑÑо оно Ñ Ð¾Ñело Ð±Ñ Ð¿Ð¾Ð¿ÑÑаÑÑÑÑ Ð¾ÑмениÑÑ Ð²ÑполнÑÑÑÑÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ. (ÐÑо можно ÑделаÑÑ Ð¸Ð· обÑабоÑÑика Ñигнала, но никак инаÑе.)
PQexecÐ¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑиÑÑ ÑолÑко Ð¾Ð´Ð½Ñ ÑÑÑÑкÑÑÑÑPGresult. ÐÑли оÑпÑÐ°Ð²Ð»ÐµÐ½Ð½Ð°Ñ ÑеÑвеÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ ÑÑÑока ÑодеÑÐ¶Ð¸Ñ Ð½ÐµÑколÑко SQL-команд, ÑÑнкÑиÑPQexecоÑбÑаÑÑÐ²Ð°ÐµÑ Ð²Ñе ÑезÑлÑÑаÑÑPGresult, кÑоме поÑледнего.PQexecвÑегда ÑобиÑÐ°ÐµÑ Ð²Ñе ÑезÑлÑÑаÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ, бÑÑеÑизÑÑ Ð¸Ñ Ð² единÑÑвенной ÑÑÑÑкÑÑÑеPGresult. Ð Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº Ð´Ð»Ñ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑÑо ÑпÑоÑÐ°ÐµÑ Ð»Ð¾Ð³Ð¸ÐºÑ Ð¾Ð±ÑабоÑки оÑибок, ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÐµÐ¿ÑакÑиÑно, когда ÑезÑлÑÑÐ°Ñ ÑодеÑÐ¶Ð¸Ñ Ð¼Ð½Ð¾Ð³Ð¾ ÑÑÑок.
ÐÑиложениÑ, коÑоÑÑм ÑÑи огÑаниÑÐµÐ½Ð¸Ñ Ð½Ðµ подÑ
одÑÑ, могÑÑ Ð²Ð¼ÐµÑÑо PQexec иÑполÑзоваÑÑ ÑÑнкÑии, на коÑоÑÑÑ
она базиÑÑеÑÑÑ, PQsendQuery и PQgetResult. ÐÑÑÑ Ñакже ÑÑнкÑии PQsendQueryParams, PQsendPrepare, PQsendQueryPrepared, PQsendDescribePrepared, PQsendDescribePortal, PQsendClosePrepared и PQsendClosePortal, коÑоÑÑе в ÑоÑеÑании Ñ PQgetResult дейÑÑвÑÑÑ Ð°Ð½Ð°Ð»Ð¾Ð³Ð¸Ñно ÑÑнкÑиÑм PQexecParams, PQprepare, PQexecPrepared, PQdescribePrepared, PQdescribePortal, PQclosePrepared и PQclosePortal, ÑооÑвеÑÑÑвенно.
PQsendQuery#ÐÑпÑавлÑÐµÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ ÑеÑвеÑÑ, не Ð¾Ð¶Ð¸Ð´Ð°Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа. ÐÑли команда бÑла оÑпÑавлена ÑÑпеÑно, Ñо ÑÑнкÑÐ¸Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ¸Ñ Ð·Ð½Ð°Ñение 1, в пÑоÑивном ÑлÑÑае она возвÑаÑÐ¸Ñ 0 (Ñогда нÑжно воÑполÑзоваÑÑÑÑ ÑÑнкÑией
PQerrorMessageÐ´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑной инÑоÑмаÑии о Ñбое).int PQsendQuery(PGconn *conn, const char *command);
ÐоÑле ÑÑпеÑного вÑзова
PQsendQueryвÑзовиÑеPQgetResultодин или неÑколÑко Ñаз, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ ÑезÑлÑÑаÑÑ. ФÑнкÑиÑPQsendQueryнелÑÐ·Ñ Ð²ÑзваÑÑ Ð¿Ð¾Ð²ÑоÑно (на Ñом же Ñамом Ñоединении) до ÑÐµÑ Ð¿Ð¾Ñ, покаPQgetResultне веÑнÑÑ Ð½Ñлевой ÑказаÑелÑ, ознаÑаÑÑий, ÑÑо вÑполнение ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð·Ð°Ð²ÐµÑÑено.РконвейеÑном Ñежиме ÑÑÑ ÑÑнкÑÐ¸Ñ Ð²ÑзÑваÑÑ Ð½ÐµÐ»ÑзÑ.
PQsendQueryParams#ÐÑпÑавлÑÐµÑ ÑеÑвеÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¸ обоÑобленнÑе паÑамеÑÑÑ, не Ð¾Ð¶Ð¸Ð´Ð°Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑов.
int PQsendQueryParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);ÐÑа ÑÑнкÑÐ¸Ñ ÑквиваленÑна ÑÑнкÑии
PQsendQuery, за иÑклÑÑением Ñого, ÑÑо паÑамеÑÑÑ Ð·Ð°Ð¿ÑоÑа можно ÑказаÑÑ Ð¾ÑделÑно Ð¾Ñ Ñамой ÑÑÑоки запÑоÑа. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQexecParams. ÐналогиÑно ÑÑнкÑииPQexecParamsона позволÑÐµÑ Ð²ÐºÐ»ÑÑиÑÑ ÑолÑко Ð¾Ð´Ð½Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð² ÑÑÑÐ¾ÐºÑ Ð·Ð°Ð¿ÑоÑа.PQsendPrepare#ÐоÑÑÐ»Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° Ñоздание подгоÑовленного опеÑаÑоÑа Ñ Ð´Ð°Ð½Ð½Ñми паÑамеÑÑами и не дожидаеÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ вÑполнениÑ.
int PQsendPrepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes);ÐÑо аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии
PQprepare. Ðна возвÑаÑÐ°ÐµÑ 1, еÑли ей ÑдалоÑÑ Ð¾ÑпÑавиÑÑ Ð·Ð°Ð¿ÑоÑ, и 0 в пÑоÑивном ÑлÑÑае. ÐоÑле ÐµÑ ÑÑпеÑного вÑзова ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑиÑPQgetResult, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ, Ñоздал ли ÑеÑÐ²ÐµÑ Ð¿Ð¾Ð´Ð³Ð¾ÑовленнÑй опеÑаÑоÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQprepare.PQsendQueryPrepared#ÐоÑÑÐ»Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° вÑполнение подгоÑовленного опеÑаÑоÑа Ñ Ð´Ð°Ð½Ð½Ñми паÑамеÑÑами, не Ð¾Ð¶Ð¸Ð´Ð°Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа.
int PQsendQueryPrepared(PGconn *conn, const char *stmtName, int nParams, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);ÐÑа ÑÑнкÑÐ¸Ñ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ð° ÑÑнкÑии
PQsendQueryParams, но вÑполнÑемÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¾Ð¿ÑеделÑÐµÑ Ð½Ðµ ÑекÑÑ Ð·Ð°Ð¿ÑоÑа, а ÑÑÑлка на пÑедваÑиÑелÑно подгоÑовленнÑй опеÑаÑоÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQexecPrepared.PQsendDescribePrepared#ÐÑпÑавлÑÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° полÑÑение инÑоÑмаÑии об Ñказанном подгоÑовленном опеÑаÑоÑе и не дожидаеÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа.
int PQsendDescribePrepared(PGconn *conn, const char *stmtName);
ÐÑо аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии
PQdescribePrepared. Ðна возвÑаÑÐ°ÐµÑ 1, еÑли ей ÑдалоÑÑ Ð¾ÑпÑавиÑÑ Ð·Ð°Ð¿ÑоÑ, и 0 в пÑоÑивном ÑлÑÑае. ÐоÑле ÐµÑ ÑÑпеÑного вÑзова ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑиÑPQgetResultÐ´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQdescribePrepared.PQsendDescribePortal#ÐÑпÑавлÑÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° полÑÑение инÑоÑмаÑии об Ñказанном поÑÑале и не дожидаеÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа.
int PQsendDescribePortal(PGconn *conn, const char *portalName);
ÐÑо аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии
PQdescribePortal. Ðна возвÑаÑÐ°ÐµÑ 1, еÑли ей ÑдалоÑÑ Ð¾ÑпÑавиÑÑ Ð·Ð°Ð¿ÑоÑ, и 0 в пÑоÑивном ÑлÑÑае. ÐоÑле ÐµÑ ÑÑпеÑного вÑзова ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑиÑPQgetResultÐ´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQdescribePortal.PQsendClosePrepared#ÐÑпÑавлÑÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° закÑÑÑие Ñказанного подгоÑовленного опеÑаÑоÑа и не дожидаеÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа.
nt PQsendClosePrepared(PGconn *conn, const char *stmtName);
ÐÑо аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии
PQclosePrepared. Ðна возвÑаÑÐ°ÐµÑ 1, еÑли ей ÑдалоÑÑ Ð¾ÑпÑавиÑÑ Ð·Ð°Ð¿ÑоÑ, и 0 в пÑоÑивном ÑлÑÑае. ÐоÑле ÐµÑ ÑÑпеÑного вÑзова ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑиÑPQgetResultÐ´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQclosePrepared.PQsendClosePortal#ÐÑпÑавлÑÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° закÑÑÑие Ñказанного поÑÑала и не дожидаеÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа.
int PQsendClosePortal(PGconn *conn, const char *portalName);
ÐÑо аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии
PQclosePortal. Ðна возвÑаÑÐ°ÐµÑ 1, еÑли ей ÑдалоÑÑ Ð¾ÑпÑавиÑÑ Ð·Ð°Ð¿ÑоÑ, и 0 в пÑоÑивном ÑлÑÑае. ÐоÑле ÐµÑ ÑÑпеÑного вÑзова ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑиÑPQgetResultÐ´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQclosePortal.PQgetResult#ÐÐ¶Ð¸Ð´Ð°ÐµÑ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑледÑÑÑего ÑезÑлÑÑаÑа поÑле пÑедÑеÑÑвÑÑÑего вÑзова
PQsendQuery,PQsendQueryParams,PQsendPrepare,PQsendQueryPrepared,PQsendDescribePrepared,PQsendDescribePortal,PQsendClosePrepared,PQsendClosePortal,PQsendPipelineSyncилиPQpipelineSyncи возвÑаÑÐ°ÐµÑ ÐµÐ³Ð¾. Ðогда команда завеÑÑена и ÑезÑлÑÑаÑов болÑÑе не бÑдеÑ, возвÑаÑаеÑÑÑ Ð½Ñлевой ÑказаÑелÑ.PGresult *PQgetResult(PGconn *conn);
ФÑнкÑиÑ
PQgetResultдолжна вÑзÑваÑÑÑÑ Ð¿Ð¾Ð²ÑоÑно до ÑÐµÑ Ð¿Ð¾Ñ, пока она не веÑнÑÑ Ð½Ñлевой ÑказаÑелÑ, ознаÑаÑÑий, ÑÑо команда завеÑÑена. (ÐÑли она вÑзвана, когда Ð½ÐµÑ Ð½Ð¸ одной акÑивной командÑ, ÑогдаPQgetResultпÑоÑÑо возвÑаÑÐ¸Ñ Ð½Ñлевой ÑказаÑÐµÐ»Ñ ÑÑÐ°Ð·Ñ Ð¶Ðµ.) ÐаждÑй ненÑлевой ÑезÑлÑÑаÑ, полÑÑеннÑй оÑPQgetResult, должен обÑабаÑÑваÑÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÐµÑ Ð¶Ðµ ÑамÑÑ ÑÑнкÑий доÑÑÑпа к ÑÑÑÑкÑÑÑеPGresult, коÑоÑÑе бÑли опиÑÐ°Ð½Ñ Ð²ÑÑе. Ðе забÑвайÑе оÑвобождаÑÑ Ð¿Ð°Ð¼ÑÑÑ, занимаемÑÑ ÐºÐ°Ð¶Ð´Ñм ÑезÑлÑÑиÑÑÑÑим обÑекÑом, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑнкÑииPQclearкогда ÑабоÑа Ñ ÑÑим обÑекÑом законÑена. ÐбÑаÑиÑе внимание, ÑÑоPQgetResultзаблокиÑÑеÑÑÑ, ÑолÑко еÑли какаÑ-либо команда акÑивна, а Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñе оÑвеÑнÑе даннÑе еÑÑ Ð½Ðµ бÑли пÑоÑиÑÐ°Ð½Ñ ÑÑнкÑиейPQconsumeInput.РконвейеÑном Ñежиме
PQgetResultбÑÐ´ÐµÑ ÑабоÑаÑÑ ÐºÐ°Ðº обÑÑно, еÑли не пÑоизойдÑÑ Ð¾Ñибка; Ð´Ð»Ñ Ð»Ñбого запÑоÑа, оÑпÑавленного поÑле запÑоÑа, вÑзвавÑего оÑибкÑ, до ÑледÑÑÑей ÑоÑки ÑÐ¸Ð½Ñ ÑонизаÑии (но не вклÑÑÐ°Ñ ÐµÑ), бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑÑÑ ÑпеÑиалÑнÑй ÑезÑлÑÑÐ°Ñ ÑипаPGRES_PIPELINE_ABORTED, а поÑле него â нÑлевой ÑказаÑелÑ. ÐÑи доÑÑижении ÑоÑки ÑÐ¸Ð½Ñ ÑонизаÑии конвейеÑа бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑÑн ÑезÑлÑÑÐ°Ñ ÑипаPGRES_PIPELINE_SYNC. РезÑлÑÑÐ°Ñ ÑледÑÑÑего запÑоÑа поÑле ÑоÑки ÑÐ¸Ð½Ñ ÑонизаÑии поÑÑÑÐ¿Ð¸Ñ Ð½ÐµÐ¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾ (Ñо еÑÑÑ Ð¿Ð¾Ñле ÑоÑки ÑÐ¸Ð½Ñ ÑонизаÑии нÑлевой ÑказаÑÐµÐ»Ñ Ð½Ðµ возвÑаÑаеÑÑÑ).ÐÑимеÑание
Ðаже когда
PQresultStatusпоказÑÐ²Ð°ÐµÑ ÐºÑиÑиÑеÑкÑÑ Ð¾ÑибкÑ, вÑÑ Ñавно ÑледÑÐµÑ Ð²ÑзÑваÑÑ ÑÑнкÑиÑPQgetResultдо ÑÐµÑ Ð¿Ð¾Ñ, пока она не возвÑаÑÐ¸Ñ Ð½Ñлевой ÑказаÑелÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸ÑÑ libpq полноÑÑÑÑ Ð¾Ð±ÑабоÑаÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ð± оÑибке.
ÐÑполÑзование PQsendQuery и PQgetResult ÑеÑÐ°ÐµÑ Ð¾Ð´Ð½Ñ Ð¸Ð· пÑоблем PQexec: еÑли ÑÑÑока запÑоÑа ÑодеÑÐ¶Ð¸Ñ Ð½ÐµÑколÑко SQL-команд, Ñо ÑезÑлÑÑаÑÑ ÐºÐ°Ð¶Ð´Ð¾Ð¹ из ниÑ
можно полÑÑиÑÑ Ð¸Ð½Ð´Ð¸Ð²Ð¸Ð´ÑалÑно. (ÐÐµÐ¶Ð´Ñ Ð¿ÑоÑим, ÑÑо позволÑÐµÑ Ð¾ÑганизоваÑÑ ÑаÑÑиÑное ÑовмеÑение обÑабоÑки: ÐºÐ»Ð¸ÐµÐ½Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±ÑабаÑÑваÑÑ ÑезÑлÑÑаÑÑ Ð¾Ð´Ð½Ð¾Ð¹ командÑ, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº ÑеÑÐ²ÐµÑ ÐµÑÑ ÑабоÑÐ°ÐµÑ Ñ Ð±Ð¾Ð»ÐµÐµ поздними запÑоÑами, ÑодеÑжаÑимиÑÑ Ð² Ñой же ÑÑÑоке.)
ÐÑÑ Ð¾Ð´Ð½Ð¾Ð¹ ÑаÑÑо ÑÑебÑÑÑейÑÑ ÑÑнкÑионалÑной возможноÑÑÑÑ, коÑоÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ полÑÑиÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ PQsendQuery и PQgetResult, ÑвлÑеÑÑÑ Ð¸Ð·Ð²Ð»ÐµÑение болÑÑиÑ
вÑбоÑок по одной ÑÑÑоке за Ñаз. ÐÑо обÑÑждаеÑÑÑ Ð² Разделе 32.6.
Сам по Ñебе вÑзов PQgetResult вÑÑ Ð¶Ðµ пÑиведÑÑ Ðº блокиÑовке клиенÑа до ÑеÑ
поÑ, пока ÑеÑÐ²ÐµÑ Ð½Ðµ завеÑÑÐ¸Ñ Ð²Ñполнение ÑледÑÑÑей SQL-командÑ. ÐÑого можно избежаÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð½Ð°Ð´Ð»ÐµÐ¶Ð°Ñего иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐµÑÑ Ð´Ð²ÑÑ
ÑÑнкÑий:
PQconsumeInput#ÐÑли ÑеÑÐ²ÐµÑ Ð³Ð¾Ñов пеÑедаÑÑ Ð´Ð°Ð½Ð½Ñе, пÑинÑÑÑ Ð¸Ñ .
int PQconsumeInput(PGconn *conn);
PQconsumeInputобÑÑно возвÑаÑÐ°ÐµÑ 1, показÑваÑ, ÑÑо «оÑибки неÑ», но возвÑаÑÐ°ÐµÑ 0, еÑли имела меÑÑо какаÑ-либо пÑоблема (в Ñаком ÑлÑÑае можно обÑаÑиÑÑÑÑ Ðº ÑÑнкÑииPQerrorMessageза ÑÑоÑнением). ÐбÑаÑиÑе внимание, ÑÑо ÑезÑлÑÑÐ°Ñ Ð½Ðµ говоÑиÑ, бÑли ли какие-либо Ð²Ñ Ð¾Ð´Ð½Ñе даннÑе ÑакÑиÑеÑки ÑобÑанÑ. ÐоÑле вÑзова ÑÑнкÑииPQconsumeInputпÑиложение Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑовеÑиÑÑPQisBusyи/илиPQnotifies, ÑÑÐ¾Ð±Ñ Ð¿Ð¾ÑмоÑÑеÑÑ, не изменилоÑÑ Ð»Ð¸ Ð¸Ñ ÑоÑÑоÑние.PQconsumeInputможно вÑзваÑÑ, даже еÑли пÑиложение еÑÑ Ð½Ðµ гоÑово имеÑÑ Ð´ÐµÐ»Ð¾ Ñ ÑезÑлÑÑаÑом или Ñведомлением. ФÑнкÑÐ¸Ñ Ð¿ÑоÑиÑÐ°ÐµÑ Ð´Ð¾ÑÑÑпнÑе даннÑе и ÑÐ¾Ñ ÑÐ°Ð½Ð¸Ñ Ð¸Ñ Ð² бÑÑеÑе, пÑи ÑÑом обÑабаÑÑÐ²Ð°Ñ ÑÑловие гоÑовноÑÑи к ÑÑÐµÐ½Ð¸Ñ ÑÑнкÑииselect(). Таким обÑазом, пÑиложение Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑPQconsumeInput>, ÑÑÐ¾Ð±Ñ Ð½ÐµÐ¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾ обÑабоÑаÑÑ ÑÑо ÑоÑÑоÑниеselect(), а изÑÑаÑÑ ÑезÑлÑÑаÑÑ Ð¿Ð¾Ð·Ð¶Ðµ.PQisBusy#ÐозвÑаÑÐ°ÐµÑ 1, еÑли команда занÑÑа ÑабоÑой, Ñо еÑÑÑ ÑÑнкÑиÑ
PQgetResultв ÑлÑÑае вÑзова бÑÐ´ÐµÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñована в ожидании ввода. ÐозвÑаÑаемое знаÑение 0 показÑваеÑ, ÑÑо ÑÑнкÑиÑPQgetResultпÑи ÐµÑ Ð²Ñзове гаÑанÑиÑованно не бÑÐ´ÐµÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñована.int PQisBusy(PGconn *conn);
ФÑнкÑиÑ
PQisBusyÑама не бÑÐ´ÐµÑ Ð¿ÑÑаÑÑÑÑ Ð¿ÑоÑиÑаÑÑ Ð´Ð°Ð½Ð½Ñе Ñ ÑеÑвеÑа, поÑÑомÑ, ÑÑÐ¾Ð±Ñ Ð²ÑйÑи из занÑÑого ÑоÑÑоÑниÑ, Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ вÑзваÑÑPQconsumeInput, .
Ð ÑипиÑном пÑиложении, иÑполÑзÑÑÑем ÑÑи ÑÑнкÑии, бÑÐ´ÐµÑ Ð³Ð»Ð°Ð²Ð½Ñй Ñикл, в коÑоÑом Ñ Ð¿Ñименением ÑÑнкÑий select() или poll() оÑганизÑеÑÑÑ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ðµ вÑеÑ
ÑÑловий, на коÑоÑÑе нÑжно ÑеагиÑоваÑÑ Ð² ÑÑом Ñикле. Ðдним из ÑÑловий бÑÐ´ÐµÑ Ð¿Ð¾ÑÑÑпление на вÑ
од даннÑÑ
Ð¾Ñ ÑеÑвеÑа, ÑÑо в ÑеÑминаÑ
ÑÑнкÑии select() ознаÑÐ°ÐµÑ Ð½Ð°Ð»Ð¸Ñие даннÑÑ
, коÑоÑÑе можно пÑоÑиÑаÑÑ ÑеÑез ÑайловÑй деÑкÑипÑоÑ, вÑдаваемÑй ÑÑнкÑией PQsocket. Ðогда в главном Ñикле обнаÑÑживаÑÑÑÑ Ð³Ð¾ÑовÑе вÑ
однÑе даннÑе, ÑледÑÐµÑ Ð²ÑзваÑÑ PQconsumeInput , ÑÑÐ¾Ð±Ñ Ð¿ÑоÑиÑаÑÑ Ð¸Ñ
. ÐоÑле ÑÑого можно вÑзваÑÑ PQisBusy, и еÑли в ÑезÑлÑÑаÑе полÑÑен 0 (ÑÑо ÑвидеÑелÑÑÑвÑÐµÑ Ð¾ Ñвободном ÑоÑÑоÑнии), заÑем вÑзваÑÑ PQgetResult. Рглавном Ñикле Ñакже можно вÑзваÑÑ PQnotifies, ÑÑÐ¾Ð±Ñ Ð¿ÑовеÑиÑÑ ÑообÑÐµÐ½Ð¸Ñ NOTIFY (Ñм. Раздел 32.9).
ÐлиенÑ, коÑоÑÑй иÑполÑзÑÐµÑ PQsendQuery/PQgetResult, Ð¼Ð¾Ð¶ÐµÑ Ñакже попÑÑаÑÑÑÑ Ð¾ÑмениÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ, коÑоÑÐ°Ñ Ð²ÑÑ ÐµÑÑ Ð¾Ð±ÑабаÑÑваеÑÑÑ ÑеÑвеÑом; Ñм. Раздел 32.7. Ðо незавиÑимо Ð¾Ñ Ð²Ð¾Ð·Ð²ÑаÑаемого знаÑÐµÐ½Ð¸Ñ ÑÑнкÑии PQcancelBlocking, пÑиложение должно пÑодолжаÑÑ Ð¾Ð±ÑÑнÑÑ Ð¿Ð¾ÑледоваÑелÑноÑÑÑ Ð¾Ð¿ÐµÑаÑий ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑов запÑоÑа, вÑзÑÐ²Ð°Ñ PQgetResult. Ð ÑлÑÑае ÑÑпеÑной оÑÐ¼ÐµÐ½Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° пÑоÑÑо завеÑÑиÑÑÑ ÑанÑÑе, Ñем она завеÑÑилаÑÑ Ð±Ñ, вÑполнÑÑÑÑ Ð´Ð¾ конÑа.
ÐÑполÑзÑÑ ÑÑнкÑии, опиÑаннÑе вÑÑе, можно избежаÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑованиÑ, Ð¾Ð¶Ð¸Ð´Ð°Ñ Ð²Ð²Ð¾Ð´Ð° Ð¾Ñ ÑеÑвеÑа баз даннÑÑ
. Ðднако вÑÑ Ð¶Ðµ возможно, ÑÑо пÑиложение бÑÐ´ÐµÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñовано в ожидании оÑпÑавки вÑвода на ÑеÑвеÑ. ÐÑо бÑÐ²Ð°ÐµÑ Ð¾ÑноÑиÑелÑно неÑаÑÑо, но Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¼ÐµÑÑо, еÑли оÑпÑÐ°Ð²Ð»ÐµÐ½Ñ Ð¾ÑÐµÐ½Ñ Ð´Ð»Ð¸Ð½Ð½Ñе SQL-ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¸Ð»Ð¸ знаÑÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
. (Ðднако ÑÑо знаÑиÑелÑно более веÑоÑÑно, еÑли пÑиложение оÑпÑавлÑÐµÑ Ð´Ð°Ð½Ð½Ñе ÑеÑез ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ COPY IN.) ЧÑÐ¾Ð±Ñ Ð¿ÑедоÑвÑаÑиÑÑ ÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¸ доÑÑиÑÑ ÑовеÑÑенно неблокиÑÑÑÑего Ñежима ÑабоÑÑ Ñ Ð±Ð°Ð·Ð¾Ð¹ даннÑÑ
, можно иÑполÑзоваÑÑ ÑледÑÑÑие дополниÑелÑнÑе ÑÑнкÑии.
PQsetnonblocking#УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð½ÐµÐ±Ð»Ð¾ÐºÐ¸ÑÑÑÑий ÑÑаÑÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑениÑ.
int PQsetnonblocking(PGconn *conn, int arg);
УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑоÑÑоÑние подклÑÑÐµÐ½Ð¸Ñ ÐºÐ°Ðº неблокиÑÑÑÑее, еÑли
argÑавен 1, или блокиÑÑÑÑее, еÑлиargÑавен 0. ÐозвÑаÑÐ°ÐµÑ 0 в ÑлÑÑае ÑÑпеÑного завеÑÑÐµÐ½Ð¸Ñ Ð¸ -1 в ÑлÑÑае оÑибки.РнеблокиÑÑÑÑем ÑоÑÑоÑнии ÑÑпеÑнÑе вÑзовÑ
PQsendQuery,PQputline,PQputnbytes,PQputCopyDataиPQendcopyне блокиÑÑÑÑÑÑ; Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÐ¾Ñ ÑанÑÑÑÑÑ Ð² локалÑном бÑÑеÑе вÑвода до ÑÐµÑ Ð¿Ð¾Ñ, пока не бÑдÑÑ ÑбÑоÑенÑ. ÐеÑдаÑнÑе вÑÐ·Ð¾Ð²Ñ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ Ð¾ÑибкÑ, и Ð¸Ñ Ð¿ÑидÑÑÑÑ Ð¿Ð¾Ð²ÑоÑиÑÑ.ÐбÑаÑиÑе внимание, ÑÑо ÑÑнкÑиÑ
PQexecне ÑоблÑÐ´Ð°ÐµÑ Ð½ÐµÐ±Ð»Ð¾ÐºÐ¸ÑÑÑÑий Ñежим. ÐÑли она вÑзÑваеÑÑÑ, она вÑÑ Ñавно ÑабоÑÐ°ÐµÑ Ð² блокиÑÑÑÑем Ñежиме.PQisnonblocking#ÐозвÑаÑÐ°ÐµÑ Ñежим блокиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ .
int PQisnonblocking(const PGconn *conn);
ÐозвÑаÑÐ°ÐµÑ 1, еÑли подклÑÑение ÑÑÑановлено в неблокиÑÑÑÑем Ñежиме, и 0, еÑли Ñежим блокиÑÑÑÑий.
PQflush#ÐÑÑаеÑÑÑ ÑбÑоÑиÑÑ Ð»ÑбÑе вÑÑ Ð¾Ð´Ð½Ñе даннÑе, ÑÑоÑÑие в оÑеÑеди, на ÑеÑвеÑ. ÐозвÑаÑÐ°ÐµÑ 0 в ÑлÑÑае ÑÑÐ¿ÐµÑ Ð° (или еÑли оÑеÑÐµÐ´Ñ Ð½Ð° оÑпÑÐ°Ð²ÐºÑ Ð¿ÑÑÑа), -1 в ÑлÑÑае ÑÐ±Ð¾Ñ Ð¿Ð¾ какой-либо пÑиÑине или 1, еÑли она еÑÑ Ð½Ðµ Ñмогла оÑпÑавиÑÑ Ð²Ñе даннÑе, Ð½Ð°Ñ Ð¾Ð´ÑÑиеÑÑ Ð² оÑеÑеди (ÑÑÐ¾Ñ ÑлÑÑай Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¼ÐµÑÑо, ÑолÑко еÑли Ñоединение неблокиÑÑÑÑее).
int PQflush(PGconn *conn);
ÐоÑле оÑпÑавки лÑбой ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¸Ð»Ð¸ даннÑÑ
ÑеÑез неблокиÑÑÑÑее подклÑÑение ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑÐ¸Ñ PQflush. ÐÑли она возвÑаÑÐ¸Ñ 1, подождиÑе, пока ÑÐ¾ÐºÐµÑ ÑÑÐ°Ð½ÐµÑ Ð³Ð¾ÑовÑм к ÑÑÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ запиÑи. ÐÑли он ÑÑÐ°Ð½ÐµÑ Ð³Ð¾ÑовÑм к запиÑи, Ñнова вÑзовиÑе PQflush. ÐÑли он ÑÑÐ°Ð½ÐµÑ Ð³Ð¾ÑовÑм к ÑÑениÑ, вÑзовиÑе PQconsumeInput , а заÑем Ð²Ð½Ð¾Ð²Ñ Ð²ÑзовиÑе PQflush. ÐовÑоÑÑйÑе до ÑеÑ
поÑ, пока PQflush не возвÑаÑÐ¸Ñ 0. (ÐеобÑ
одимо вÑполнÑÑÑ Ð¿ÑовеÑÐºÑ Ð½Ð° ÑоÑÑоÑние гоÑовноÑÑи к ÑÑÐµÐ½Ð¸Ñ Ð¸ забиÑаÑÑ Ð²Ñ
однÑе даннÑе Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ PQconsumeInput , поÑÐ¾Ð¼Ñ ÑÑо ÑеÑÐ²ÐµÑ Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸ÑоваÑÑÑÑ, пÑÑаÑÑÑ Ð¾ÑпÑавиÑÑ Ð½Ð°Ð¼ даннÑе, напÑимеÑ, ÑообÑÐµÐ½Ð¸Ñ NOTICE, и не бÑÐ´ÐµÑ ÑиÑаÑÑ Ð½Ð°Ñи даннÑе до ÑеÑ
поÑ, пока Ð¼Ñ Ð½Ðµ пÑоÑиÑаем его.) Ðак ÑолÑко PQflush возвÑаÑÐ¸Ñ 0, подождиÑе, пока ÑÐ¾ÐºÐµÑ Ð½Ðµ ÑÑÐ°Ð½ÐµÑ Ð³Ð¾ÑовÑм к ÑÑениÑ, а заÑем пÑоÑиÑайÑе оÑвеÑ, как опиÑано вÑÑе.