pike.git
/
lib
/
modules
/
Sql.pmod
/
pgsql_util.pmod
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:58:
foreach(expr;;int c) if(c>='A'&&c<='Z') ret->add('[',c,c+'a'-'A',']'); else if(c=='\a') // Replace with generic whitespace ret->add("[ \t\f\r\n]"); else ret->add_int8(c); return Regexp(ret->read()); }
-
final void closestatement(bufcon|
conxion
plugbuffer,string oldprep) {
+
final void closestatement(bufcon|
conxsess
plugbuffer,string oldprep) {
if(oldprep) { PD("Close statement %s\n",oldprep);
-
plugbuffer->add_int8('C')->add_hstring(({'S',oldprep,0}),4,4);
+
CHAIN(
plugbuffer
)
->add_int8('C')->add_hstring(({'S',
oldprep,
0}),
4,
4);
} } private void run_local_backend() { Thread.MutexKey lock; int looponce; do { looponce=0; if(lock=backendmux->trylock()) { PD("Starting local backend\n");
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:143:
private inline mixed callout(function(mixed ...:void) f, float|int delay,mixed ... args) { return local_backend->call_out(f,delay,@args); } // Some pgsql utility functions class bufcon { inherit Stdio.Buffer;
+
#ifdef PG_DEBUGRACE
+
final bufcon `chain() {
+
return this;
+
}
+
#endif
+
private conxion realbuffer; protected void create(conxion _realbuffer) { realbuffer=_realbuffer; } final int `stashcount() { return realbuffer->stashcount; }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:173:
Thread.MutexKey lock=realbuffer->shortmux->lock(); if(portal) realbuffer->stashqueue->write(portal); realbuffer->stash->add(this); mode=mergemode(realbuffer,mode); if(!--realbuffer->stashcount) realbuffer->stashavail.signal(); lock=0; this->clear(); if(lock=realbuffer->nostash->trylock(1)) {
-
realbuffer->started=lock; lock=0;
+
#ifdef
PG_DEBUGRACE
+
conxsess sess = conxsess(
realbuffer
);
+
realbuffer
->started
=
lock;
+
lock
=
0;
+
sess->sendcmd(SENDOUT);
+
#else
+
realbuffer->started = lock;
+
lock = 0;
realbuffer->sendcmd(SENDOUT);
-
+
#endif
} }
-
+
}; class conxiin { inherit Stdio.Buffer:i; final Thread.Condition fillread; final Thread.Mutex fillreadmux; final int procmsg; private int didreadcb;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:247:
final multiset(function(void|mixed:void)) closecallbacks=(<>); final Thread.Mutex nostash; final Thread.MutexKey started; final Thread.Queue stashqueue; final Thread.Condition stashavail; final Stdio.Buffer stash; final int stashflushmode; final int 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) { 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
conxion|
bufcon start(void|int waitforreal) {
+
final
bufcon
|
conxsess
start(void|int waitforreal) {
Thread.MutexKey lock; if(lock=(waitforreal?nostash->lock:nostash->trylock)(1)) {
-
started=lock;
+
#ifdef
PG_DEBUGRACE
+
conxsess sess = conxsess(this);
+
#endif
+
started
=
lock;
lock=shortmux->lock(); if(stashcount) PT(stashavail.wait(lock)); add(stash); stash->clear(); foreach(stashqueue->try_read_array();;sql_result portal) queueup(portal); lock=0;
-
+
#ifdef PG_DEBUGRACE
+
return sess;
+
#else
return this;
-
+
#endif
} stashcount++; return bufcon(this); } private int write_cb() { Thread.MutexKey lock = shortmux->lock(); if (this) { // Guard against async destructs towrite -= output_to(socket, towrite); lock = 0;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:441:
} private string _sprintf(int type, void|mapping flags) { string res=UNDEFINED; switch(type) { case 'O': int fd=-1; if(socket) catch(fd=socket->query_fd()); res=predef::sprintf("conxion fd: %d input queue: %d/%d "
-
"queued portals: %d output queue: %d/%d\n",
+
"queued portals: %d output queue: %d/%d\n"
+
"started: %d\n"
,
fd,sizeof(i),i->_size_object(),
-
qportals->size(),sizeof(this),_size_object());
+
qportals->size(),sizeof(this),_size_object()
,
+
!!started
);
break; } return res; } protected void create(object pgsqlsess,Thread.Queue _qportals,int nossl) { o::create(); qportals = _qportals; synctransact = 1; socket=Stdio.File();
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:465:
shortmux=Thread.Mutex(); nostash=Thread.Mutex(); closenext = 0; stashavail=Thread.Condition(); stashqueue=Thread.Queue(); stash=Stdio.Buffer(); Thread.Thread(connectloop,pgsqlsess,nossl); } };
+
#ifdef PG_DEBUGRACE
+
class conxsess {
+
final conxion chain;
+
+
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) {
+
chain->sendcmd(mode, portal);
+
chain = 0;
+
}
+
+
void destroy() {
+
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]. //! //! @seealso //! @[Sql.sql_result], @[Sql.pgsql], @[Sql.Sql], @[Sql.pgsql()->big_query()] class sql_result { private object pgsqlsess; private int eoffound; private conxion c;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:882:
pgsqlsess->_waittocommit++; PD("Commit waiting for portals to finish\n"); catch(PT(pgsqlsess->_readyforcommit->wait(lock))); pgsqlsess->_waittocommit--; } } lock=0; PD("Bind portal %O statement %O\n",_portalname,_preparedname); _fetchlimit=pgsqlsess->_fetchlimit; _openportal();
-
conxion
bindbuffer=c->start();
+
conxsess
bindbuffer
=
c->start();
_unnamedstatementkey=0;
-
bindbuffer->add_int8('B')->add_hstring(plugbuffer,4,4);
+
CHAIN(
bindbuffer
)
->add_int8('B')->add_hstring(plugbuffer,
4,
4);
if(!_tprepared && sizeof(_preparedname))
-
closestatement(bindbuffer,_preparedname);
+
closestatement(
CHAIN(
bindbuffer
)
,
_preparedname);
_sendexecute(_fetchlimit && !(cachealways[_query] || sizeof(_query)>=MINPREPARELENGTH && execfetchlimit->match(_query)) && _fetchlimit,bindbuffer); } } else lock=0; }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:928:
switch(_state) { case COPYINPROGRESS: case BOUND: --pgsqlsess->_portalsinflight; } _state=CLOSED; lock=0; releaseconditions(); }
-
final int _closeportal(
bufcon
plugbuffer
) {
+
final int _closeportal(
conxsess
cs
) {
+
object plugbuffer = CHAIN(cs);
int retval=KEEP; PD("%O Try Closeportal %d\n",_portalname,_state); Thread.MutexKey lock=closemux->lock(); _fetchlimit=0; // disables further Executes switch(_state) { case PORTALINIT: _unnamedstatementkey=0; _state=CLOSING; break; case COPYINPROGRESS:
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1011:
_ddescribe->broadcast(); lock=0; } } final void _releasesession(void|string statusccomplete) { c->closecallbacks-=(<destroy>); if(statusccomplete && !statuscmdcomplete) statuscmdcomplete=statusccomplete; inflight=0;
-
catch
{
-
conxion
plugbuffer=c->start()
;
+
conxsess
plugbuffer;
+
if
(!catch(plugbuffer
=
c->start()
))
plugbuffer->sendcmd(_closeportal(plugbuffer));
-
};
+
_state=CLOSED; datarows->write(1); // Signal EOF releaseconditions(); } protected void destroy() { catch { // inside destructors, exceptions don't work _releasesession(); }; }
-
final void _sendexecute(int fetchlimit,void|bufcon plugbuffer) {
+
final void _sendexecute(int fetchlimit,void|bufcon
|conxsess
plugbuffer) {
int flushmode; PD("Execute portal %O fetchlimit %d\n",_portalname,fetchlimit); if(!plugbuffer) plugbuffer=c->start(1);
-
plugbuffer->add_int8('E')->add_hstring(({_portalname,0}),4,8)
+
CHAIN(
plugbuffer
)
->add_int8('E')->add_hstring(({_portalname,0}),
4,
8)
->add_int32(fetchlimit); if(!fetchlimit) flushmode=_closeportal(plugbuffer)==SYNCSEND?SYNCSEND:FLUSHSEND; else inflight+=fetchlimit, flushmode=FLUSHSEND; plugbuffer->sendcmd(flushmode,this); } //! @returns //! One result row at a time.
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1109:
//! The COPY FROM STDIN sequence needs to be completed by either //! explicitly or implicitly destroying the result object, or by passing no //! argument to this method. //! //! @seealso //! @[fetch_row()], @[eof()] /*semi*/final void send_row(void|string|array(string) copydata) { trydelayederror(); if(copydata) { PD("CopyData\n");
-
c->start()->add_int8('d')->add_hstring(copydata,4,4)->sendcmd(SENDOUT);
+
object 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, array(mixed) args) { int|array datarow; for(;;) { array cid=callout(gottimeout,timeout);