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

version» Context lines:

pike.git/lib/modules/Sql.pmod/pgsql.pike:243:   }      //! @decl string host_info()   //!   //! This function returns a string describing what host are we talking to,   //! and how (TCP/IP or UNIX sockets).   //!   //! @seealso   //! server_info   string host_info() { -  return sprintf("Via fd:%d over TCP/IP to %s:%d PID %d", -  _c.query_fd(),host,port,backendpid); +  return sprintf("fd:%d TCP/IP %s:%d PID %d", +  _c?_c.query_fd():-1,host,port,backendpid);   }      final private object getsocket(void|int nossl) {    object lcon = Stdio.File();    if(!lcon.connect(host,port))    return UNDEFINED;       object fcon;   #if constant(SSL.sslfile)    if(!nossl && (options->use_ssl || options->force_ssl)) {
pike.git/lib/modules/Sql.pmod/pgsql.pike:509:      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:868:    case 'N':PD("NoticeResponse\n");    { 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); +  lastmsgnl(),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:896:    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=lastmessage?lastmessage+"\n":""; +  string msg=lastmsgnl(); +  if(!reconnect(1)) { +  sleep(RECONNECTDELAY); +  if(!reconnect(1)) { +  sleep(RECONNECTBACKOFF);    reconnect(1); -  ERROR("%sConnection lost to database %s@%s:%d/%s %d\n", -  msg,user,host,port,database,backendpid); +     } -  +  } +  ERROR("%s%sConnection lost to database %s@%s:%d/%s %d\n", +  msg,lastmsgnl(),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;    reconnect(1); -  ERROR("Protocol error with database %s@%s:%d/%s PID %d\n", -  user,host,port,database,backendpid); +  ERROR("%s%sProtocol error with database %s\n", +  msg,lastmsgnl(),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:948:   void close() {    cancelquery();    if(_c)    _c.sendterminate();   }      void destroy() {    close();   }    - private void reconnect(void|int force) { + private int reconnect(void|int force) {    Thread.MutexKey connectmtxkey;    if(_c) {    reconnected++;    prepstmtused=0;   #ifdef DEBUG    ERROR("While debugging, reconnects are forbidden\n");    exit(1);   #endif    if(!force)    _c.sendterminate(); -  +  _c.close(); _c=0;    foreach(prepareds;;mapping tp)    m_delete(tp,"preparedname");    if(!(connectmtxkey = _stealmutex.trylock(2))) -  ERROR("Recursive reconnect, bailing out\n"); +  return 0; // Recursive reconnect, bailing out    } -  if(!(_c=getsocket())) -  ERROR("Couldn't connect to database on %s:%d\n",host,port); +  if(!(_c=getsocket())) { +  string msg=sprintf("Couldn't connect to database on %s:%d\n",host,port); +  if(force) { +  lastmessage=lastmsgnl()+msg; +  return 0; +  } +  else +  ERROR(msg); +  }    _closesent=0;    _mstate=unauthenticated;    qstate=queryidle;    runtimeparameter=([]);    array(string) plugbuf=({"",_c.plugint32(PG_PROTOCOL(3,0))});    if(user)    plugbuf+=({"user\0",user,"\0"});    if(database)    plugbuf+=({"database\0",database,"\0"});    foreach(options-(<"use_ssl","force_ssl","bool_results_as_text",    "all_results_as_text">);    string name;mixed value)    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); +  { 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();    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.   //!   //! @seealso   //! cancelquery   void reload(void|int special) {    mixed err;
pike.git/lib/modules/Sql.pmod/pgsql.pike:1023:    foreach(prepareds;;mapping tp) {    m_delete(tp,"datatypeoid");    m_delete(tp,"datarowdesc");    }    }    }    earlyclose=0;    }) {    earlyclose=0;    PD("%O\n",err); -  reconnect(1); +  if(!reconnect(1)) +  ERROR(lastmessage);    }    else if(didsync && special==2)    _decodemsg(readyforquery);   #ifndef UNBUFFEREDIO    _c.set_read_callback(read_cb);   #endif   }      //! @decl void select_db(string dbname)   //!