30.4. ÐÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð¾Ð±ÑабоÑка команд
ФÑнкÑÐ¸Ñ PQexec Ñ
оÑоÑо подÑ
Ð¾Ð´Ð¸Ñ Ð´Ð»Ñ Ð¾ÑпÑавки команд ÑеÑвеÑÑ Ð² ноÑмалÑнÑÑ
, ÑинÑ
ÑоннÑÑ
пÑиложениÑÑ
. Ðднако она Ð¸Ð¼ÐµÐµÑ ÑÑд недоÑÑаÑков, коÑоÑÑе могÑÑ Ð¸Ð¼ÐµÑÑ Ð·Ð½Ð°Ñение Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑÑÑ
полÑзоваÑелей:
PQexecÐ¾Ð¶Ð¸Ð´Ð°ÐµÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ. ÐÑиложение Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¸ дÑÑгÑÑ ÑабоÑÑ, коÑоÑÑÑ Ð½Ñжно делаÑÑ (ÑакÑÑ, как поддеÑжание полÑзоваÑелÑÑкого инÑеÑÑейÑа), в Ñаком ÑлÑÑае оно не Ð·Ð°Ñ Ð¾ÑÐµÑ Ð±Ð»Ð¾ÐºÐ¸ÑоваÑÑÑÑ, Ð¾Ð¶Ð¸Ð´Ð°Ñ Ð¾ÑвеÑа.ÐоÑколÑÐºÑ Ð²Ñполнение клиенÑÑкого пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿ÑиоÑÑанавливаеÑÑÑ, пока оно Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ ÑезÑлÑÑаÑа, Ñо пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑÑÑдно ÑеÑиÑÑ, ÑÑо оно Ñ Ð¾Ñело Ð±Ñ Ð¿Ð¾Ð¿ÑÑаÑÑÑÑ Ð¾ÑмениÑÑ Ð²ÑполнÑÑÑÑÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ. (ÐÑо можно ÑделаÑÑ Ð¸Ð· обÑабоÑÑика Ñигнала, но никак инаÑе.)
PQexecÐ¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑиÑÑ ÑолÑко Ð¾Ð´Ð½Ñ ÑÑÑÑкÑÑÑÑPGresult. ÐÑли оÑпÑÐ°Ð²Ð»ÐµÐ½Ð½Ð°Ñ ÑеÑвеÑÑ ÑÑÑока-команда ÑодеÑÐ¶Ð¸Ñ Ð¼Ð½Ð¾Ð¶ÐµÑÑвеннÑе SQL-командÑ, Ñо вÑе ÑÑÑÑкÑÑÑÑPGresult, кÑоме поÑледней, оÑбÑаÑÑваÑÑÑÑ ÑÑнкÑиейPQexec.PQexecвÑегда ÑобиÑÐ°ÐµÑ Ð²Ñе ÑезÑлÑÑаÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ, бÑÑеÑизÑÑ Ð¸Ñ Ð² единÑÑвенной ÑÑÑÑкÑÑÑеPGresult. Ð Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº Ð´Ð»Ñ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑÑо ÑпÑоÑÐ°ÐµÑ Ð»Ð¾Ð³Ð¸ÐºÑ Ð¾Ð±ÑабоÑки оÑибок, ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÐµÐ¿ÑакÑиÑно, когда ÑезÑлÑÑÐ°Ñ ÑодеÑÐ¶Ð¸Ñ Ð¼Ð½Ð¾Ð³Ð¾ ÑÑÑок.
ÐÑиложениÑ, коÑоÑÑм ÑÑи огÑаниÑÐµÐ½Ð¸Ñ Ð½Ðµ подÑ
одÑÑ, могÑÑ Ð²Ð¼ÐµÑÑо PQexec иÑполÑзоваÑÑ Ð±Ð°Ð·Ð¾Ð²Ñе ÑÑнкÑии, на оÑнове коÑоÑÑÑ
и поÑÑÑоена ÑÑнкÑÐ¸Ñ PQexec: PQsendQuery и PQgetResult. ÐÑÑÑ Ñакже ÑÑнкÑии PQsendQueryParams, PQsendPrepare, PQsendQueryPrepared, PQsendDescribePrepared и PQsendDescribePortal, коÑоÑÑе можно иÑполÑзоваÑÑ ÑовмеÑÑно Ñ PQgetResult, ÑÑÐ¾Ð±Ñ Ð¿ÑодÑблиÑоваÑÑ ÑÑнкÑионалÑноÑÑÑ PQexecParams, PQprepare, PQexecPrepared, PQdescribePrepared и PQdescribePortal ÑооÑвеÑÑÑвенно.
-
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, Ð´Ð°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð½Ðµ бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¿Ñи подклÑÑениÑÑ Ð¿Ð¾ пÑоÑÐ¾ÐºÐ¾Ð»Ñ Ð²ÐµÑÑии 2.0, Ñакже она позволÑÐµÑ Ð²ÐºÐ»ÑÑиÑÑ ÑолÑко Ð¾Ð´Ð½Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð² ÑÑÑÐ¾ÐºÑ Ð·Ð°Ð¿ÑоÑа.-
PQsendPrepare ÐоÑÑÐ»Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° Ñоздание подгоÑовленного опеÑаÑоÑа Ñ Ð´Ð°Ð½Ð½Ñми паÑамеÑÑами и не дожидаеÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ вÑполнениÑ.
int PQsendPrepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes);ÐÑо аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии
PQprepare. Ðна возвÑаÑÐ°ÐµÑ 1, еÑли ей ÑдалоÑÑ Ð¾ÑпÑавиÑÑ Ð·Ð°Ð¿ÑоÑ, и 0 в пÑоÑивном ÑлÑÑае. ÐоÑле ÐµÑ ÑÑпеÑного вÑзова ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑиÑPQgetResult, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ, ÑÑпеÑно ли Ñоздал ÑеÑÐ²ÐµÑ Ð¿Ð¾Ð´Ð³Ð¾ÑовленнÑй опеÑаÑоÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQprepare. ÐналогиÑно ÑÑнкÑииPQprepare, Ð´Ð°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð½Ðµ бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¿Ñи подклÑÑениÑÑ Ð¿Ð¾ пÑоÑÐ¾ÐºÐ¾Ð»Ñ Ð²ÐµÑÑии 2.0.-
PQsendQueryPrepared ÐоÑÑÐ»Ð°ÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° вÑполнение подгоÑовленного опеÑаÑоÑа Ñ Ð´Ð°Ð½Ð½Ñми паÑамеÑÑами, не Ð¾Ð¶Ð¸Ð´Ð°Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа.
int PQsendQueryPrepared(PGconn *conn, const char *stmtName, int nParams, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat);ÐÑа ÑÑнкÑÐ¸Ñ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ð° ÑÑнкÑии
PQsendQueryParams, но команда, коÑоÑÐ°Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° бÑÑÑ Ð²Ñполнена, задаÑÑÑÑ Ð¿ÑÑÑм ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð¿ÑедваÑиÑелÑно подгоÑовленного опеÑаÑоÑа, вмеÑÑо Ð·Ð°Ð´Ð°Ð½Ð¸Ñ ÑÑÑоки запÑоÑа. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQexecPrepared. ÐналогиÑно ÑÑнкÑииPQexecPrepared, Ð´Ð°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð½Ðµ бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¿Ñи подклÑÑениÑÑ Ð¿Ð¾ пÑоÑÐ¾ÐºÐ¾Ð»Ñ Ð²ÐµÑÑии 2.0.-
PQsendDescribePrepared ÐÑпÑавлÑÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° полÑÑение инÑоÑмаÑии об Ñказанном подгоÑовленном опеÑаÑоÑе и не дожидаеÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа.
int PQsendDescribePrepared(PGconn *conn, const char *stmtName);
ÐÑо аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии
PQdescribePrepared. Ðна возвÑаÑÐ°ÐµÑ 1, еÑли ей ÑдалоÑÑ Ð¾ÑпÑавиÑÑ Ð·Ð°Ð¿ÑоÑ, и 0 в пÑоÑивном ÑлÑÑае. ÐоÑле ÐµÑ ÑÑпеÑного вÑзова ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑиÑPQgetResultÐ´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQdescribePrepared. ÐналогиÑно ÑÑнкÑииPQdescribePrepared, Ð´Ð°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð½Ðµ бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¿Ñи подклÑÑениÑÑ Ð¿Ð¾ пÑоÑÐ¾ÐºÐ¾Ð»Ñ Ð²ÐµÑÑии 2.0.-
PQsendDescribePortal ÐÑпÑавлÑÐµÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ð° полÑÑение инÑоÑмаÑии об Ñказанном поÑÑале и не дожидаеÑÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа.
int PQsendDescribePortal(PGconn *conn, const char *portalName);
ÐÑо аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÑÑнкÑии
PQdescribePortal. Ðна возвÑаÑÐ°ÐµÑ 1, еÑли ей ÑдалоÑÑ Ð¾ÑпÑавиÑÑ Ð·Ð°Ð¿ÑоÑ, и 0 в пÑоÑивном ÑлÑÑае. ÐоÑле ÐµÑ ÑÑпеÑного вÑзова ÑледÑÐµÑ Ð²ÑзваÑÑ ÑÑнкÑиÑPQgetResultÐ´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа. ÐÑа ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ Ñвои паÑамеÑÑÑ ÑоÑно Ñак же, как и ÑÑнкÑиÑPQdescribePortal. ÐналогиÑно ÑÑнкÑииPQdescribePortal, Ð´Ð°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð½Ðµ бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¿Ñи подклÑÑениÑÑ Ð¿Ð¾ пÑоÑÐ¾ÐºÐ¾Ð»Ñ Ð²ÐµÑÑии 2.0.-
PQgetResult ÐÐ¶Ð¸Ð´Ð°ÐµÑ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑледÑÑÑего ÑезÑлÑÑаÑа поÑле пÑедÑеÑÑвÑÑÑего вÑзова
PQsendQuery,PQsendQueryParams,PQsendPrepare,PQsendQueryPrepared,PQsendDescribePreparedилиPQsendDescribePortalи возвÑаÑÐ°ÐµÑ ÐµÐ³Ð¾. Ðогда команда завеÑÑена и ÑезÑлÑÑаÑов болÑÑе не бÑдеÑ, Ñогда возвÑаÑаеÑÑÑ Ð½Ñлевой ÑказаÑелÑ.PGresult *PQgetResult(PGconn *conn);
ФÑнкÑиÑ
PQgetResultдолжна вÑзÑваÑÑÑÑ Ð¿Ð¾Ð²ÑоÑно до ÑÐµÑ Ð¿Ð¾Ñ, пока она не веÑнÑÑ Ð½Ñлевой ÑказаÑелÑ, ознаÑаÑÑий, ÑÑо команда завеÑÑена. (ÐÑли она вÑзвана, когда Ð½ÐµÑ Ð½Ð¸ одной акÑивной командÑ, ÑогдаPQgetResultпÑоÑÑо возвÑаÑÐ¸Ñ Ð½Ñлевой ÑказаÑÐµÐ»Ñ ÑÑÐ°Ð·Ñ Ð¶Ðµ.) ÐаждÑй ненÑлевой ÑезÑлÑÑаÑ, полÑÑеннÑй оÑPQgetResult, должен обÑабаÑÑваÑÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÐµÑ Ð¶Ðµ ÑамÑÑ ÑÑнкÑий доÑÑÑпа к ÑÑÑÑкÑÑÑеPGresult, коÑоÑÑе бÑли опиÑÐ°Ð½Ñ Ð²ÑÑе. Ðе забÑвайÑе оÑвобождаÑÑ Ð¿Ð°Ð¼ÑÑÑ, занимаемÑÑ ÐºÐ°Ð¶Ð´Ñм ÑезÑлÑÑиÑÑÑÑим обÑекÑом, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑнкÑииPQclear, когда ÑабоÑа Ñ ÑÑим обÑекÑом законÑена. ÐбÑаÑиÑе внимание, ÑÑоPQgetResultзаблокиÑÑеÑÑÑ, ÑолÑко еÑли какаÑ-либо команда акÑивна, а Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñе оÑвеÑнÑе даннÑе еÑÑ Ð½Ðµ бÑли пÑоÑиÑÐ°Ð½Ñ ÑÑнкÑиейPQconsumeInput.ÐÑимеÑание
Ðаже когда
PQresultStatusпоказÑÐ²Ð°ÐµÑ ÑаÑалÑнÑÑ Ð¾ÑибкÑ, вÑе Ñавно ÑледÑÐµÑ Ð²ÑзÑваÑÑ ÑÑнкÑиÑPQgetResultдо ÑÐµÑ Ð¿Ð¾Ñ, пока она не возвÑаÑÐ¸Ñ Ð½Ñлевой ÑказаÑелÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸ÑÑ libpq полноÑÑÑÑ Ð¾Ð±ÑабоÑаÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ð± оÑибке.
ÐÑполÑзование PQsendQuery и PQgetResult ÑеÑÐ°ÐµÑ Ð¾Ð´Ð½Ñ Ð¸Ð· пÑоблем PQexec: еÑли ÑÑÑока ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ ÑодеÑÐ¶Ð¸Ñ Ð½ÐµÑколÑко SQL-команд, Ñо ÑезÑлÑÑаÑÑ ÐºÐ°Ð¶Ð´Ð¾Ð¹ из ниÑ
можно полÑÑиÑÑ Ð¸Ð½Ð´Ð¸Ð²Ð¸Ð´ÑалÑно. (ÐÐµÐ¶Ð´Ñ Ð¿ÑоÑим, ÑÑо позволÑÐµÑ Ð¾ÑганизоваÑÑ ÑаÑÑиÑное ÑовмеÑение обÑабоÑки: ÐºÐ»Ð¸ÐµÐ½Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±ÑабаÑÑваÑÑ ÑезÑлÑÑаÑÑ Ð¾Ð´Ð½Ð¾Ð¹ командÑ, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº ÑеÑÐ²ÐµÑ ÐµÑÑ ÑабоÑÐ°ÐµÑ Ñ Ð±Ð¾Ð»ÐµÐµ поздними запÑоÑами, ÑодеÑжаÑимиÑÑ Ð² Ñой же Ñамой ÑÑÑоке-команде.)
ÐÑÑ Ð¾Ð´Ð½Ð¾Ð¹ ÑаÑÑо ÑÑебÑÑÑейÑÑ ÑÑнкÑионалÑной возможноÑÑÑÑ, коÑоÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ полÑÑиÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ PQsendQuery и PQgetResult, ÑвлÑеÑÑÑ Ð¸Ð·Ð²Ð»ÐµÑение болÑÑиÑ
вÑбоÑок по одной ÑÑÑоке за Ñаз. ÐÑо обÑÑждаеÑÑÑ Ð² Разделе 30.5.
Сам по Ñебе вÑзов 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, а поÑле Ð½ÐµÑ Ñже PQgetResult, еÑли PQisBusy возвÑаÑÐ¸Ñ false (0). ÐлавнÑй Ñикл Ð¼Ð¾Ð¶ÐµÑ Ñакже вÑзваÑÑ PQnotifies, ÑÑÐ¾Ð±Ñ Ð¾Ð±Ð½Ð°ÑÑжиÑÑ ÑообÑÐµÐ½Ð¸Ñ NOTIFY (Ñм. Раздел 30.8).
ÐлиенÑ, коÑоÑÑй иÑполÑзÑÐµÑ PQsendQuery/PQgetResult, Ð¼Ð¾Ð¶ÐµÑ Ñакже попÑÑаÑÑÑÑ Ð¾ÑмениÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ, коÑоÑÐ°Ñ Ð²ÑÑ ÐµÑÑ Ð¾Ð±ÑабаÑÑваеÑÑÑ ÑеÑвеÑом; Ñм. Раздел 30.6. Ðо, незавиÑимо Ð¾Ñ Ð²Ð¾Ð·Ð²ÑаÑаемого знаÑÐµÐ½Ð¸Ñ ÑÑнкÑии PQcancel, пÑиложение должно пÑодолжаÑÑ Ð¾Ð±ÑÑнÑÑ Ð¿Ð¾ÑледоваÑелÑноÑÑÑ Ð¾Ð¿ÐµÑаÑий ÑÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑов запÑоÑа, иÑполÑзÑÑ 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, подождиÑе, пока ÑÐ¾ÐºÐµÑ Ð½Ðµ ÑÑÐ°Ð½ÐµÑ Ð³Ð¾ÑовÑм к ÑÑениÑ, а заÑем пÑоÑиÑайÑе оÑвеÑ, как опиÑано вÑÑе.