pike.git / lib / modules / Sql.pmod / pgsql.pike

version» Context lines:

pike.git/lib/modules/Sql.pmod/pgsql.pike:59:   int _closesent;   int _fetchlimit=FETCHLIMIT;   private int unnamedportalinuse;   private int portalsinflight;      object _c;   private string SSauthdata,cancelsecret;   private int backendpid;   private int backendstatus;   private mapping(string:mixed) options; - private string lastmessage; + private string lastmessage="";   private int clearmessage;   private int earlyclose;   private mapping(string:array(mixed)) notifylist=([]);   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;
pike.git/lib/modules/Sql.pmod/pgsql.pike:92:   int _bytessent; // Number of bytes sent   private int warningsdropcount; // Number of uncollected warnings   private int prepstmtused; // Number of times prepared statements were used   private int warningscollected;   private int invalidatecache;      private string host, database, user, pass;   private int port;   private object createprefix    =Regexp("^[ \t\f\r\n]*[Cc][Rr][Ee][Aa][Tt][Ee][ \t\f\r\n]"); - private object fetchprefix -  =Regexp("^[ \t\f\r\n]*[Ff][Ee][Tt][Cc][Hh][ \t\f\r\n]"); + private object dontcacheprefix +  =Regexp("^[ \t\f\r\n]*([Ff][Ee][Tt][Cc][Hh]|[Cc][Oo][Pp][Yy])[ \t\f\r\n]");   private object limitpostfix    =Regexp("[ \t\f\r\n][Ll][Ii][Mm][Ii][Tt][ \t\f\r\n]+[12][; \t\f\r\n]*$");   Thread.Mutex _querymutex;   Thread.Mutex _stealmutex;    -  + #define USERERROR(msg) throw(({msg, backtrace()[..<1]})) +    protected string _sprintf(int type, void|mapping flags) {    string res=UNDEFINED;    switch(type) {    case 'O': -  res=sprintf(DRIVERNAME"://%s@%s:%d/%s pid:%d %s reconnected:%d\n" -  "mstate: %O qstate: %O pstmtcount: %d pportalcount: %d prepcache: %d\n" -  "Last message: %s", -  user,host,port,database,backendpid,status_commit(),reconnected, -  _mstate,qstate,pstmtcount,pportalcount,sizeof(prepareds), -  lastmessage||""); +  res=sprintf(DRIVERNAME"(%s@%s:%d/%s,%d)", +  user,host,port,database,backendpid);    break;    }    return res;   }      #define BOOLOID 16   #define BYTEAOID 17   #define CHAROID 18   #define INT8OID 20   #define INT2OID 21
pike.git/lib/modules/Sql.pmod/pgsql.pike:227:   //! generate any errors, this function will return all collected messages   //! from the last statement.   //!   //! To clear the error, pass 1 as argument.   //!   //! @seealso   //! big_query   string error(void|int clear) {    string s=lastmessage;    if(clear) -  lastmessage=UNDEFINED; +  lastmessage="";    warningscollected=0;    return s;   }      //! @decl string host_info()   //!   //! This function returns a string describing what host are we talking to,   //! and how (TCP/IP or UNIX sockets).   //!   //! @seealso
pike.git/lib/modules/Sql.pmod/pgsql.pike:506:      final private string pinpointerror(void|string query,void|string offset) {    if(!query)    return "";    int k=(int)offset;    if(k<=0)    return MARKSTART+query+MARKEND;    return MARKSTART+(k>1?query[..k-2]:"")+MARKERROR+query[k-1..]+MARKEND;   }    - final private string lastmsgnl() { -  return lastmessage?lastmessage+"\n":""; - } -  +    final int _decodemsg(void|state waitforstate) {   #ifdef DEBUG    { array line;   #ifdef DEBUGMORE    line=backtrace();   #endif    PD("Waiting for state %O %O\n",waitforstate,line&&line[sizeof(line)-2]);    }   #endif    while(_mstate!=waitforstate) {
pike.git/lib/modules/Sql.pmod/pgsql.pike:842:    break;    case 'c':PD("CopyDone\n");    msglen-=4;    break;    case 'E':PD("ErrorResponse\n");    { 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)); +  lastmessage=sprintf("%s: %s\n",msgresponse->S,msgresponse->M); +  USERERROR(sprintf("%s%s\n", +  lastmessage,pinpointerror(_c.portal->query,msgresponse->P)));    break;    case "08P01":case "42P05":    errtype=protocolerror;    case "XX000":case "42883":case "42P01":    invalidatecache=1;    default:    lastmessage=sprintf("%s %s:%s %s\n (%s:%s:%s)\n%s%s%s%s\n%s",    msgresponse->S,msgresponse->C,msgresponse->P||"",msgresponse->M,    msgresponse->F||"",msgresponse->R||"",msgresponse->L||"",    addnlifpresent(msgresponse->D),addnlifpresent(msgresponse->H),
pike.git/lib/modules/Sql.pmod/pgsql.pike:873:    USERERROR(lastmessage);    }    break;    }    case 'N':PD("NoticeResponse\n");    { mapping(string:string) msgresponse;    msgresponse=getresponse();    if(clearmessage) {    warningsdropcount+=warningscollected;    clearmessage=warningscollected=0; -  lastmessage=UNDEFINED; +  lastmessage="";    }    warningscollected++; -  lastmessage=sprintf("%s%s %s: %s", -  lastmsgnl(),msgresponse->S,msgresponse->C,msgresponse->M); +  lastmessage=sprintf("%s%s %s: %s\n", +  lastmessage,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;
pike.git/lib/modules/Sql.pmod/pgsql.pike:904:    runcallback(pid,condition,extrainfo);    break;    }    default:    if(msgtype!=-1) {    PD("Unknown message received %c\n",msgtype);    msglen-=4;PD("%O\n",_c.getstring(msglen));msglen=0;    errtype=protocolunsupported;    }    else { -  string msg=lastmsgnl(); +  string msg=lastmessage;    if(!reconnect(1)) {    sleep(RECONNECTDELAY);    if(!reconnect(1)) {    sleep(RECONNECTBACKOFF);    reconnect(1);    }    }    ERROR("%s%sConnection lost to database %s@%s:%d/%s %d\n", -  msg,lastmsgnl(),user,host,port,database,backendpid); +  msg,lastmessage,user,host,port,database,backendpid);    }    break;    }    if(msglen)    errtype=protocolerror;    switch(errtype) {    case protocolunsupported:    ERROR("Unsupported servermessage received %c\n",msgtype);    break;    case protocolerror: -  string msg=lastmsgnl(); -  lastmessage=UNDEFINED; +  string msg=lastmessage; +  lastmessage="";    reconnect(1);    ERROR("%s%sProtocol error with database %s\n", -  msg,lastmsgnl(),host_info()); +  msg,lastmessage,host_info());    break;    case noerror:    break;    }    if(zero_type(waitforstate))    break;    }    PD("Found state %O\n",_mstate);    return _mstate;   }
pike.git/lib/modules/Sql.pmod/pgsql.pike:984:    _c.sendterminate();    _c.close(); _c=0;    foreach(prepareds;;mapping tp)    m_delete(tp,"preparedname");    if(!(connectmtxkey = _stealmutex.trylock(2)))    return 0; // Recursive reconnect, bailing out    }    if(!(_c=getsocket())) {    string msg=sprintf("Couldn't connect to database on %s:%d\n",host,port);    if(force) { -  lastmessage=lastmsgnl()+msg; +  lastmessage+=msg;    return 0;    }    else    ERROR(msg);    }    _closesent=0;    _mstate=unauthenticated;    qstate=queryidle;    runtimeparameter=([]);    array(string) plugbuf=({"",_c.plugint32(PG_PROTOCOL(3,0))});
pike.git/lib/modules/Sql.pmod/pgsql.pike:1018:    PD("%O\n",plugbuf);    { mixed err=catch(_decodemsg(readyforquery));    if(err)    if(force)    throw(err);    else    return 0;    }    PD("%O\n",runtimeparameter);    if(force) { -  lastmessage=lastmsgnl()+"Reconnected to database "+host_info(); +  lastmessage=sprintf("%sReconnected to database %s\n", +  lastmessage,host_info());    runcallback(backendpid,"_reconnect","");    }    return 1;   }      //! @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.   //!
pike.git/lib/modules/Sql.pmod/pgsql.pike:1422:    }    }   }      final private string trbackendst(int c) {    switch(c) {    case 'I':return "idle";    case 'T':return "intransaction";    case 'E':return "infailedtransaction";    } -  return "unknown"; +  return "";   }      //! Returns the current commitstatus of the connection. Returns either one of: - //! unknown +    //! idle   //! intransaction   //! infailedtransaction   //!   //! This function is PostgreSQL-specific, and thus it is not available   //! through the generic SQL-interface.   final string status_commit() {    return trbackendst(backendstatus);   }   
pike.git/lib/modules/Sql.pmod/pgsql.pike:1608:    int len=4+sizeof(portalname)+1+sizeof(preparedname)+1    +2+sizeof(paramValues)*(2+4)+2+2;    plugbuf+=({portalname,"\0",preparedname,"\0",    _c.plugint16(sizeof(paramValues))});    if(!tp || !tp->datatypeoid) {    _decodemsg(gotparameterdescription);    if(tp)    tp->datatypeoid=_c.portal->_datatypeoid;    }    array dtoid=_c.portal->_datatypeoid; +  if(sizeof(dtoid)!=sizeof(paramValues)) +  USERERROR(sprintf("Invalid number of bindings, wanted %d, got %d\n", +  sizeof(dtoid),sizeof(paramValues)));    foreach(dtoid;;int textbin)    plugbuf+=({_c.plugint16(oidformat(textbin))});    plugbuf+=({_c.plugint16(sizeof(paramValues))});    foreach(paramValues;int i;mixed value) {    if(zero_type(value))    plugbuf+=({_c.plugint32(-1)}); // NULL    else    switch(dtoid[i]) {    default:    { int k;
pike.git/lib/modules/Sql.pmod/pgsql.pike:1660:    case OIDOID:    case INT4OID:len+=4;    plugbuf+=({_c.plugint32(4),_c.plugint32((int)value)});    break;    case INT2OID:len+=2;    plugbuf+=({_c.plugint32(2),_c.plugint16((int)value)});    break;    }    }    if(!tp || !tp->datarowdesc) { -  if(tp && fetchprefix->match(q)) // Don't cache FETCH +  if(tp && dontcacheprefix->match(q)) // Don't cache FETCH/COPY    m_delete(prepareds,q),tp=0;    _decodemsg(gotrowdescription);    if(tp)    tp->datarowdesc=_c.portal->_datarowdesc;    }    { array a;int i;    len+=(i=sizeof(a=_c.portal->_datarowdesc))*2;    plugbuf+=({_c.plugint16(i)});    foreach(a;;mapping col)    plugbuf+=({_c.plugint16(oidformat(col->type))});