pike.git
/
lib
/
modules
/
Sql.pmod
/
pgsql.pike
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/lib/modules/Sql.pmod/pgsql.pike:63:
object _c; private string SSauthdata,cancelsecret; private int backendpid; private int backendstatus; private mapping(string:mixed) options; private string lastmessage; private int clearmessage; private int earlyclose; private mapping(string:array(mixed)) notifylist=([]);
-
private mapping(string:string) msgresponse;
+
private mapping(string:string) runtimeparameter; state _mstate; private enum querystate {queryidle,inquery,cancelpending,canceled}; private querystate qstate; private mapping(string:mapping(string:mixed)) prepareds=([]); private mapping(string:mixed) tprepared; private int pstmtcount; private int pportalcount; private int totalhits; private int cachedepth=STATEMENTCACHEDEPTH;
pike.git/lib/modules/Sql.pmod/pgsql.pike:533:
if(msglen<1) errtype=protocolerror; s=_c.getstring(msglen); if(s[--msglen]) errtype=protocolerror; if(!msglen) return ({}); s=s[..msglen-1];msglen=0; return s/"\0"; };
-
void
getresponse() {
+
mapping(string:string)
getresponse() {
+
mapping(string:string) msgresponse=([]);
msglen-=4;
-
msgresponse=([]);
+
foreach(getstrings();;string f) if(sizeof(f)) msgresponse[f[..0]]=f[1..]; PD("%O\n",msgresponse);
-
+
return msgresponse;
}; case 'R':PD("Authentication\n"); { string sendpass; int authtype; msglen-=4+4; switch(authtype=_c.getint32()) { case 0:PD("Ok\n"); _mstate=authenticated; break; case 2:PD("KerberosV5\n");
pike.git/lib/modules/Sql.pmod/pgsql.pike:787:
_c.portal->_fetchlimit=0; // disables further Executes break; case 'G':PD("CopyInResponse\n"); getcols(); _mstate=copyinresponse; break; case 'c':PD("CopyDone\n"); msglen-=4; break; case 'E':PD("ErrorResponse\n");
-
getresponse();
+
{
mapping(string:string)
msgresponse;
+
msgresponse=
getresponse();
warningsdropcount+=warningscollected; warningscollected=0; switch(msgresponse->C) { #define USERERROR(msg) throw(({msg, backtrace()[..<1]})) case "P0001": lastmessage=sprintf("%s: %s",msgresponse->S,msgresponse->M); USERERROR(lastmessage +"\n"+pinpointerror(_c.portal->query,msgresponse->P)); break; default:
pike.git/lib/modules/Sql.pmod/pgsql.pike:811:
addnlifpresent(msgresponse->D),addnlifpresent(msgresponse->H), pinpointerror(_c.portal&&_c.portal->query,msgresponse->P), pinpointerror(msgresponse->q,msgresponse->p), addnlifpresent(msgresponse->W)); switch(msgresponse->S) { case "PANIC":werror(lastmessage); } USERERROR(lastmessage); } break;
+
}
case 'N':PD("NoticeResponse\n");
-
getresponse();
+
{
mapping(string:string)
msgresponse;
+
msgresponse=
getresponse();
if(clearmessage) { warningsdropcount+=warningscollected; clearmessage=warningscollected=0; lastmessage=UNDEFINED; } warningscollected++; lastmessage=sprintf("%s%s %s: %s", lastmessage?lastmessage+"\n":"", msgresponse->S,msgresponse->C,msgresponse->M); break;
-
+
}
case 'A':PD("NotificationResponse\n"); { msglen-=4+4; int pid=_c.getint32(); string condition,extrainfo=UNDEFINED; { array(string) ts=getstrings(); switch(sizeof(ts)) { case 0:errtype=protocolerror; break; default:errtype=protocolerror; case 2:extrainfo=ts[1]; case 1:condition=ts[0]; } } PD("%d %s\n%s\n",pid,condition,extrainfo);
-
array cb;
-
if
(
(cb=notifylist[condition]||notifylist[""])
-
&& (
pid
!=backendpid || sizeof(cb)>1 && cb[1]))
-
cb[0](pid
,condition,extrainfo
,@cb[2..]
);
+
runcallback
(pid,condition,extrainfo);
break; } default:PD("Unknown message received %c\n",msgtype); msglen-=4;PD("%O\n",_c.getstring(msglen));msglen=0; errtype=protocolunsupported; break; } if(msglen) errtype=protocolerror; switch(errtype) {
pike.git/lib/modules/Sql.pmod/pgsql.pike:928:
plugbuf+=({name,"\0",(string)value,"\0"}); plugbuf+=({"\0"}); int len=4; foreach(plugbuf;;string s) len+=sizeof(s); plugbuf[0]=_c.plugint32(len); _c.write(plugbuf); PD("%O\n",plugbuf); _decodemsg(readyforquery); PD("%O\n",runtimeparameter);
+
if(force)
+
runcallback(backendpid,"_reconnect","");
} //! @decl void reload() //! //! Resets the connection to the database. Can be used for //! a variety of reasons, for example to detect the status of a connection. //! //! @seealso //! cancelquery void reload(void|int special) {
pike.git/lib/modules/Sql.pmod/pgsql.pike:986:
//! //! @note //! This function @b{can@} raise exceptions if something goes wrong //! (backend process not running, not enough permissions..) //! //! @seealso //! create void select_db(string dbname) { database=dbname; reconnect();
+
reconnected=0;
} //! With PostgreSQL you can LISTEN to NOTIFY events. //! This function allows you to detect and handle such events. //! //! @param condition //! Name of the notification event we're listening //! to. A special case is the empty string, which matches all events, //! and can be used as fallback function which is called only when the
-
//! specific condition is not handled..
+
//! specific condition is not handled.
Another special case is
+
//! @[_reconnect] which gets called whenever the connection unexpectedly
+
//! drops and reconnects to the database
.
//! //! @param notify_cb //! Function to be called on receiving a notification-event of //! condition @[condition]. //! The callback function is invoked with //! @expr{void notify_cb(pid,condition,extrainfo, .. args);@} //! @[pid] is the process id of the database session that originated //! the event. @[condition] contains the current condition. //! @[extrainfo] contains optional extra information specified by //! the database.
pike.git/lib/modules/Sql.pmod/pgsql.pike:1036:
if(!old) old=({notify_cb}); if(selfnotify||args) old+=({selfnotify}); if(args) old+=args; notifylist[condition]=old; } }
+
final private void runcallback(int pid,string condition,string extrainfo) {
+
array cb;
+
if((cb=notifylist[condition]||notifylist[""])
+
&& (pid!=backendpid || sizeof(cb)>1 && cb[1]))
+
cb[0](pid,condition,extrainfo,@cb[2..]);
+
}
+
//! This function quotes magic characters inside strings embedded in a //! textual query. Quoting must not be done for parameters passed in //! bindings. //! //! @seealso //! big_query, quotebinary, create string quote(string s) { string r=runtimeparameter->standard_conforming_strings; if(r && r=="on") return replace(s, "'", "''");
pike.git/lib/modules/Sql.pmod/pgsql.pike:1290:
PD("Close portal %s & Sync\n",portalname); _c.sendcmd(({"C",_c.plugint32(4+1+sizeof(portalname)+1), "P",portalname,"\0"})); } _c.sendcmd(({"S",_c.plugint32(4)}),2); } } final private void sendclose(void|int hold) { string portalname;
-
portalsinflight--;
+
if(_c.portal && (portalname=_c.portal->_portalname)) { _c.portal->_portalname = UNDEFINED; _c.setportal();
-
+
portalsinflight--;
#ifdef DEBUGMORE PD("Closetrace %O\n",backtrace()); #endif if(!sizeof(portalname)) unnamedportalinuse--; if(sizeof(portalname)) { if(!earlyclose) { PD("Close portal %s\n",portalname); _c.sendcmd(({"C",_c.plugint32(4+1+sizeof(portalname)+1), "P",portalname,"\0"}),!hold||portalsinflight?1:0);
pike.git/lib/modules/Sql.pmod/pgsql.pike:1443:
if(unnamedportalinuse) portalname=PORTALPREFIX+(string)pportalcount++; else unnamedportalinuse++; _c.portal->_portalname=portalname; qstate=inquery; portalsinflight++; portalsopened++; clearmessage=1; mixed err; if(err = catch {
-
_c.set_read_callback(0);
+
if(!sizeof(preparedname) || !tp || !tp->preparedname) { PD("Parse statement %s\n",preparedname); // Even though the protocol doesn't require the Parse command to be // followed by a flush, it makes a VERY noticeable difference in // performance if it is omitted; seems like a flaw in the PostgreSQL // server v8.3.3 _c.sendcmd(({"P",_c.plugint32(4+sizeof(preparedname)+1+sizeof(q)+1+2), preparedname,"\0",q,"\0",_c.plugint16(0)}),3); PD("Query: %O\n",q); } // sends Parameter- and RowDescription for 'S'