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

version» Context lines:

pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:139:   //! Registers yourself as a user of this backend. If the backend   //! has not been started yet, it will be spawned automatically.   final Thread.ResourceCountKey register_backend() {    int startbackend = clientsregistered->drained();    Thread.ResourceCountKey key = clientsregistered->acquire();    if (startbackend)    Thread.Thread(run_local_backend);    return key;   }    - final void throwdelayederror(sql_result|proxy parent) { + final void throwdelayederror(Result|proxy parent) {    if (mixed err = parent->delayederror) {    if (!objectp(parent->pgsqlsess))    parent->untolderror = 0;    else if (parent->pgsqlsess)    parent->pgsqlsess->untolderror = 0;    parent.delayederror = 0;    if (stringp(err))    err = ({err, backtrace()[..<2]});    throw(err);    }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:209:       final bufcon start(void|int waitforreal) {    dirty = realbuffer->stashcount->acquire();   #ifdef PG_DEBUG    if (waitforreal)    error("pgsql.bufcon not allowed here\n");   #endif    return this;    }    -  final void sendcmd(int mode, void|sql_result portal) { +  final void sendcmd(int mode, void|Result portal) {    Thread.MutexKey lock = realbuffer->shortmux->lock();    if (portal)    realbuffer->stashqueue->write(portal);    if (mode == SYNCSEND) {    add(PGSYNC);    realbuffer->stashqueue->write(1);    mode = SENDOUT; // Demote it to prevent an extra SYNC upon stashflush    }    realbuffer->stash->add(this);    PD("%d>Stashed mode %d > %d\n",
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:307:    private Thread.Queue qportals;    final Thread.Mutex shortmux;    private int closenext;       final sfile   #if constant(SSL.File)    |SSL.File   #endif    socket;    private int towrite; -  final multiset(sql_result) runningportals = (<>); +  final multiset(Result) runningportals = (<>);       final Thread.Mutex nostash;    final Thread.MutexKey started;    final Thread.Queue stashqueue;    final Thread.Condition stashavail;    final Stdio.Buffer stash;    /* FIXME actually: int(KEEP..SYNCSEND) stashflushmode    * but the PikeParser does not approve, and refdoc    * generation aborts    */
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:329:    final Thread.ResourceCount stashcount;    final int synctransact;   #ifdef PG_DEBUGRACE    final mixed nostrack;   #endif   #ifdef PG_DEBUG    final int queueoutidx;    final int queueinidx = -1;   #endif    -  private inline void queueup(sql_result portal) { +  private inline void queueup(Result portal) {    qportals->write(portal); portal->_synctransact = synctransact;    PD("%d>%O %d %d Queue portal %d bytes\n", socket->query_fd(),    portal._portalname, ++queueoutidx, synctransact, sizeof(this));    }       final bufcon|conxsess start(void|int waitforreal) {    Thread.MutexKey lock;    if (lock = (waitforreal ? nostash->lock : nostash->trylock)(1)) {    int mode;   #ifdef PG_DEBUGRACE
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:372:    lock = 0;    if (!i->fillread && !sizeof(this))    close();    }    return 0;    }       private int getstash(int mode) {    if (sizeof(stash)) {    add(stash); stash->clear(); -  foreach (stashqueue->try_read_array(); ; int|sql_result portal) +  foreach (stashqueue->try_read_array(); ; int|Result portal)    if (intp(portal))    qportals->write(synctransact++);    else    queueup(portal);    PD("%d>Got stash mode %d > %d\n",    socket->query_fd(), stashflushmode, mode);    if (stashflushmode > mode)    mode = stashflushmode;    stashflushmode = KEEP;    }    return mode;    }    -  final void sendcmd(void|int mode, void|sql_result portal) { +  final void sendcmd(void|int mode, void|Result portal) {    Thread.MutexKey lock;    if (portal)    queueup(portal);   unfinalised:    do {    switch (mode) {    default:    break unfinalised;    case SYNCSEND:    PD("%d>Sync %d %d Queue\n",
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:460:    i->read_cb(socket->query_id(), 0);    return 0;    } else    return -1;    }       final void purge() {    if (stashcount) {    stashcount = 0;    PD("%d>Purge conxion %d\n", socket ? socket->query_fd() : -1, !!nostash); -  int|sql_result portal; +  int|Result portal;    if (qportals) // CancelRequest does not use qportals    while (portal = qportals->try_read())    if (objectp(portal))    portal->_purgeportal();    if (nostash) {    while (sizeof(runningportals))    catch { -  foreach (runningportals; sql_result result; ) +  foreach (runningportals; Result result; )    if (!result.datarowtypes) {    result.datarowtypes = emptyarray;    if (result._state != PURGED && !result.delayederror)    result.delayederror = LOSTERROR;    result._ddescribe->broadcast();    runningportals[result] = 0;    } else    destruct(result);    };    destruct(nostash);
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:595: Inside #if defined(PG_DEBUGRACE)
      private void create(conxion parent) {    if (parent->started)    werror("Overwriting conxsess %s %s\n",    describe_backtrace(({"new ", backtrace()[..<1]})),    describe_backtrace(({"old ", parent->nostrack})));    parent->nostrack = backtrace();    chain = parent;    }    -  final void sendcmd(int mode, void|sql_result portal) { +  final void sendcmd(int mode, void|Result portal) {    chain->sendcmd(mode, portal);    chain = 0;    }       private void _destruct() {    if (chain)    werror("Untransmitted conxsess %s\n",    describe_backtrace(({"", backtrace()[..<1]})));    }   };   #endif      //! The result object returned by @[Sql.pgsql()->big_query()], except for - //! the noted differences it behaves the same as @[Sql.sql_result]. + //! the noted differences it behaves the same as @[Sql.Result].   //!   //! @seealso - //! @[Sql.sql_result], @[Sql.pgsql], @[Sql.Sql], @[Sql.pgsql()->big_query()] - class sql_result { + //! @[Sql.Result], @[Sql.pgsql], @[Sql.Sql], @[Sql.pgsql()->big_query()] + class Result {       inherit __builtin.Sql.Result;       private proxy pgsqlsess;    private int(0..1) eoffound;    private conxion c;    private conxiin cr;    final mixed delayederror;    final int(0..7) _state; // FIXME actually: int(PORTALINIT..PURGED)    final int _fetchlimit;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:659:    private function(:void) gottimeout;    private int timeout;       protected string _sprintf(int type) {    string res;    switch (type) {    case 'O':    int fd = -1;    if (c && c->socket)    catch(fd = c->socket->query_fd()); -  res = sprintf("sql_result state: %d numrows: %d eof: %d inflight: %d\n" +  res = sprintf("Result state: %d numrows: %d eof: %d inflight: %d\n"    "query: %O\n"    "fd: %O portalname: %O datarows: %d"    " synctransact: %d laststatus: %s\n",    _state, rowsreceived, eoffound, inflight,    _query, fd, _portalname,    datarowtypes && sizeof(datarowtypes), _synctransact,    statuscmdcomplete    || (_unnamedstatementkey ? "*parsing*" : ""));    break;    }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:735:    if (!datarowtypes)    PT(_ddescribe->wait(lock));    lock = 0;    if (this) // If object already destructed, skip the next call    trydelayederror(); // since you cannot call functions anymore    else    error(LOSTERROR);    }       //! @seealso -  //! @[Sql.sql_result()->num_fields()] +  //! @[Sql.Result()->num_fields()]    /*semi*/final int num_fields() {    if (!datarowtypes)    waitfordescribe();    return sizeof(datarowtypes);    }       //! @note    //! This method returns the number of rows already received from    //! the database for the current query. Note that this number    //! can still increase between subsequent calls if the results from    //! the query are not complete yet. This function is only guaranteed to    //! return the correct count after EOF has been reached.    //! @seealso -  //! @[Sql.sql_result()->num_rows()] +  //! @[Sql.Result()->num_rows()]    /*semi*/final int num_rows() {    trydelayederror();    return rowsreceived;    }       private void losterror() {    string err;    if (pgsqlsess)    err = pgsqlsess->geterror(1);    error("%s\n", err || LOSTERROR);    }       private void trydelayederror() {    if (delayederror)    throwdelayederror(this);    else if (_state == PURGED)    losterror();    }       //! @seealso -  //! @[Sql.sql_result()->eof()] +  //! @[Sql.Result()->eof()]    /*semi*/final int eof() {    trydelayederror();    return eoffound;    }       //! @seealso -  //! @[Sql.sql_result()->fetch_fields()] +  //! @[Sql.Result()->fetch_fields()]    /*semi*/final array(mapping(string:mixed)) fetch_fields() {    if (!datarowtypes)    waitfordescribe();    if (!datarowdesc)    error(LOSTERROR);    return datarowdesc + emptyarray;    }      #ifdef PG_DEBUG   #define INTVOID int
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1325:    if (copydata) {    PD("CopyData\n");    void|bufcon|conxsess cs = c->start();    CHAIN(cs)->add_int8('d')->add_hstring(copydata, 4, 4);    cs->sendcmd(SENDOUT);    } else    _releasesession();    }       private void run_result_cb( -  function(sql_result, array(mixed), mixed ...:void) callback, +  function(Result, array(mixed), mixed ...:void) callback,    array(mixed) args) {    int|array datarow;    for (;;) {    array cid = callout(gottimeout, timeout);    PT(datarow = datarows->read());    local_backend->remove_call_out(cid);    if (!arrayp(datarow))    break;    callout(callback, 0, this, datarow, @args);    }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1347:    callout(callback, 0, this, 0, @args);    }       //! Sets up a callback for every row returned from the database.    //! First argument passed is the resultobject itself, second argument    //! is the result row (zero on EOF).    //!    //! @seealso    //! @[fetch_row()]    /*semi*/final void set_result_callback( -  function(sql_result, array(mixed), mixed ...:void) callback, +  function(Result, array(mixed), mixed ...:void) callback,    mixed ... args) {    if (callback)    Thread.Thread(run_result_cb, callback, args);    }       private void run_result_array_cb( -  function(sql_result, array(array(mixed)), mixed ...:void) callback, +  function(Result, array(array(mixed)), mixed ...:void) callback,    array(mixed) args) {    array(array|int) datarow;    for (;;) {    array cid = callout(gottimeout, timeout);    PT(datarow = datarows->read_array());    local_backend->remove_call_out(cid);    if (!datarow || !arrayp(datarow[-1]))    break;    callout(callback, 0, this, datarow, @args);    }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1378:    callout(callback, 0, this, 0, @args);    }       //! Sets up a callback for sets of rows returned from the database.    //! First argument passed is the resultobject itself, second argument    //! is the array of result rows (zero on EOF).    //!    //! @seealso    //! @[fetch_row()]    /*semi*/final void set_result_array_callback( -  function(sql_result, array(array(mixed)), mixed ...:void) callback, +  function(Result, array(array(mixed)), mixed ...:void) callback,    mixed ... args) {    if (callback)    Thread.Thread(run_result_array_cb, callback, args);    }      };      class proxy {    final int _fetchlimit = FETCHLIMIT;    final Thread.Mutex unnamedportalmux;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1420:    final int bytesreceived; // Number of bytes received    final int warningsdropcount; // Number of uncollected warnings    private int warningscollected;    final int(0..1) invalidatecache;    private Thread.Queue qportals;    final mixed delayederror;    private function (:void) readyforquery_cb;       final string host;    final int(0..65535) port; -  private string database, user, pass; +  final string database, user, pass;    private Crypto.SCRAM SASLcontext;    final Thread.Condition waitforauthready;    final Thread.Mutex shortmux;    final int readyforquerycount;       private string _sprintf(int type) {    string res;    switch (type) {    case 'O':    res = sprintf(DRIVERNAME".proxy(%s@%s:%d/%s,%d,%d)",
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1535:    if (k <= 0)    return MARKSTART + query + MARKEND;    return MARKSTART + (k > 1 ? query[..k-2] : "")    + MARKERROR + query[k - 1..] + MARKEND;    }       private void connect_cb() {    PD("%O\n", runtimeparameter);    }    -  private array(string) showbindings(sql_result portal) { +  private array(string) showbindings(Result portal) {    array(string) msgs = emptyarray;    array from;    if (portal && (from = portal._params)) {    array to, paramValues;    [from, to, paramValues] = from;    if (sizeof(paramValues)) {    string val;    int i;    string fmt = sprintf("%%%ds %%3s %%.61s", max(@map(from, sizeof)));    foreach (paramValues; i; val)
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1560:    }       private void preplastmessage(mapping(string:string) msgresponse) {    lastmessage = ({    sprintf("%s %s:%s %s\n (%s:%s:%s)",    msgresponse.S, msgresponse.C, msgresponse.P || "",    msgresponse.M, msgresponse.F || "", msgresponse.R || "",    msgresponse.L||"")});    }    -  private int|sql_result portal; // state information procmessage +  private int|Result portal; // state information procmessage    #ifdef PG_DEBUG    private string datarowdebug;    private int datarowdebugcount;    #endif       final void processloop(conxion ci) {    (c = ci)->socket->set_id(procmessage);    cancelsecret = 0;    portal = 0;    {
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1606:    int terminating = 0;    err = catch {    conxion ci = c; // cache value FIXME sensible?    conxiin cr = ci->i; // cache value FIXME sensible?    #ifdef PG_DEBUG    PD("Processloop\n");       #ifdef PG_DEBUGMORE    void showportalstack(string label) {    PD(sprintf(">>>>>>>>>>> Portalstack %s: %O\n", label, portal)); -  foreach (qportals->peek_array(); ; int|sql_result qp) +  foreach (qportals->peek_array(); ; int|Result qp)    PD(" =========== Portal: %O\n", qp);    PD("<<<<<<<<<<<<<< Portalstack end\n");    };    #endif    void showportal(int msgtype) {    if (objectp(portal))    PD("%d<%O %d %c switch portal\n",    ci->socket->query_fd(), portal._portalname, ++ci->queueinidx, msgtype);    else if (portal>0)    PD("%d<Sync %d %d %c portal\n",
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1884:    showportal(msgtype);    #endif    if (backendstatus == 'I' && intransaction    && portal->transtype != TRANSEND)    keeplooking = 1;    portal->_purgeportal();    }    while (keeplooking && (portal = qportals->read()));    if (backendstatus == 'I')    intransaction = 0; -  foreach (qportals->peek_array(); ; sql_result qp) { +  foreach (qportals->peek_array(); ; Result qp) {    if (objectp(qp) && qp._synctransact    && qp._synctransact <= portal) {    PD("Checking portal %O %d<=%d\n",    qp._portalname, qp._synctransact, portal);    qp->_purgeportal();    }    }    portal = 0;    #ifdef PG_DEBUGMORE    showportalstack("AFTER READYFORQUERY");
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:2241:    }; // We only get here if there is an error    if (err == MAGICTERMINATE) { // Announce connection termination to server    catch {    void|bufcon|conxsess cs = ci->start();    CHAIN(cs)->add("X\0\0\0\4");    cs->sendcmd(SENDOUT);    };    terminating = 1;    err = 0;    } else if (stringp(err)) { -  sql_result or; +  Result or;    if (!objectp(or = portal))    or = this;    if (!or.delayederror)    or.delayederror = err;    #ifdef PG_DEBUGMORE    showportalstack("THROWN");    #endif    if (objectp(portal))    portal->_releasesession();    portal = 0;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:2293:    throwdelayederror(this);    Thread.MutexKey lock;    if (qportals && qportals->size())    catch(cancelquery());    if (unnamedstatement)    termlock = unnamedstatement->lock(1);    if (c) // Prevent trivial backtraces    c->close();    if (unnamedstatement)    lock = unnamedstatement->lock(1); +  if (c)    c->purge();    lock = 0;    destruct(waitforauthready);    }       private void _destruct() {    string errstring;    mixed err = catch(close());    backendreg = 0;    if (untolderror) {
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:2334:    if ((cb = notifylist[condition] || notifylist[""])    && (pid != backendpid || sizeof(cb) > 1 && cb[1]))    callout(cb[0], 0, pid, condition, extrainfo, @cb[2..]);    }       private inline void closestatement(    bufcon|conxsess plugbuffer, string oldprep) {    closestatement(plugbuffer, oldprep);    }   }; +  + #pragma deprecation_warnings +  + //! @class sql_result + //! @deprecated Result +  + //! @endclass +  + __deprecated__(program(Result)) sql_result = +  (__deprecated__(program(Result)))Result;