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:49:
final void throwdelayederror(object parent) { if(mixed err=parent._delayederror) { parent._delayederror=UNDEFINED; if(stringp(err)) err=({err,backtrace()[..<2]}); throw(err); } } protected sctype mergemode(PGassist realbuffer,sctype mode) {
-
switch
(realbuffer->stashflushmode)
{
-
case sendout:
-
if(mode!
=
flushsend) {
-
mode
=sendout
;
-
break
;
+
if
(
mode>
realbuffer->stashflushmode)
+
realbuffer->stashflushmode
=mode;
+
return
realbuffer->stashflushmode
;
}
-
case flushsend:
-
mode=flushsend;
-
}
-
return realbuffer->stashflushmode=mode;
-
}
+
//! Some pgsql utility functions class PGplugbuffer { inherit Stdio.Buffer; protected PGassist realbuffer; final void create(PGassist _realbuffer) { realbuffer=_realbuffer;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:86:
error("pgsql.PGplugbuffer not allowed here\n"); #endif return this; } final void sendcmd(void|sctype mode,void|object portal) { Thread.MutexKey lock=realbuffer->stashupdate->lock(); if(portal) realbuffer->stashqueue->write(portal);
+
if(mode==flushlogsend)
+
mode=flushsend, realbuffer->stashqueue->write(1);
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; realbuffer->sendcmd(sendout); }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:120:
final function(:void) gottimeout; final int timeout; Thread.Mutex nostash; Thread.MutexKey started; Thread.Mutex stashupdate; Thread.Queue stashqueue; Thread.Condition stashavail; Stdio.Buffer stash; int stashflushmode; int stashcount;
+
int synctransact;
#ifdef PG_DEBUG int queueoutidx; int queueinidx; #endif
-
+
inline void queueup(pgsql_result portal) {
+
qportals->write(portal); portal->_synctransact=synctransact;
+
PD(">%O %d %d Queue portal %d bytes\n",portal._portalname,++queueoutidx,
+
synctransact,sizeof(this));
+
}
+
final PGassist|PGplugbuffer start(void|int waitforreal) { Thread.MutexKey lock; if(lock=(waitforreal?nostash->lock:nostash->trylock)(1)) { started=lock; lock=stashupdate->lock();
-
if(stashcount)
{
+
if(stashcount)
stashavail.wait(lock); add(stash); stash->clear();
-
foreach(stashqueue->try_read_array();;pgsql_result
qp
)
{
-
qportals->write
(
qp);
-
PD(">%O %d Queue
portal
%d bytes\n",qp._portalname,++queueoutidx,
-
sizeof(this
)
)
;
-
}
-
}
+
foreach(stashqueue->try_read_array();;pgsql_result
portal
)
+
queueup
(portal);
lock=0; return this; } stashcount++; return PGplugbuffer(this); } protected final bool range_error(int howmuch) { if(!howmuch) return false;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:191:
inline final string read(int w) { return i::read(w); } inline final object read_buffer(int w) { return i::read_buffer(w); } inline final int read_sint(int w) { return i::read_sint(w); } inline final int read_int8() { return i::read_int8(); } inline final int read_int16() { return i::read_int16(); } inline final int read_int32() { return i::read_int32(); } inline final string read_cstring() { return i::read_cstring(); } final void sendcmd(void|sctype mode,void|pgsql_result portal) {
-
if(portal) {
-
qportals->write(
portal
);
-
PD(">%O %d Queue
portal
%d bytes\n",portal._portalname,
++queueoutidx,
-
sizeof(this));
+
if(portal)
+
queueup(portal);
+
if(mode==flushlogsend)
{
+
mode=flushsend;
qportals->write(
synctransact++
);
+
PD(">%O %d Queue
simplequery
%d bytes\n",portal._portalname,
+
++queueoutidx,
sizeof(this));
} if(started) { Thread.MutexKey lock=stashupdate->lock(); if(sizeof(stash)) { add(stash); stash->clear();
-
foreach(stashqueue->try_read_array();;pgsql_result
qp
)
{
-
qportals->write
(
qp);
-
PD(">%O %d Queue
portal
%d bytes\n",qp._portalname,++queueoutidx,
-
sizeof(this
)
)
;
+
foreach(stashqueue->try_read_array();;pgsql_result
portal
)
+
queueup
(portal);
}
-
}
+
mode=mergemode(this,mode); stashflushmode=keep; lock=0; }
-
+
outer:
+
do {
switch(mode) {
-
+
default:
+
break outer;
+
case syncsend:
+
PD(">Sync %d %d Queue\n",synctransact,++queueoutidx);
+
qportals->write(synctransact++); add(PGSYNC);
+
break;
case flushsend:
-
add(PGFLUSH);
+
PD("Flush\n");
-
case sendout:
-
if(
towrite+
=sizeof(this)) {
+
add(PGFLUSH);
+
case sendout:
;
+
}
+
if(
towrite
=sizeof(this)) {
PD(">Sendcmd %O\n",((string)this)[..towrite-1]); towrite-=output_to(socket,towrite); }
-
}
+
}
while(0);
started=0; } final void sendterminate() { destruct(condition); // Delayed close() after flushing the output buffer } final int close() { return socket->close(); }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:281:
socket->set_nonblocking(read_cb,write_cb,0); Thread.Thread(pgsqlsess->_processloop,this); return; }; pgsqlsess->_connectfail(err); } void create(object pgsqlsess,Thread.Queue _qportals,int nossl) { i::create(); o::create(); qportals = _qportals;
+
synctransact = 1;
condition=Thread.Condition(); mux=Thread.Mutex(); gottimeout=sendcmd; // Preset it with a NOP timeout=128; // Just a reasonable amount socket=Stdio.File(); nostash=Thread.Mutex(); stashupdate=Thread.Mutex(); stashqueue=Thread.Queue(); stashavail=Thread.Condition(); stash=Stdio.Buffer();
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:318:
int _fetchlimit; int _alltext; int _forcetext; string _portalname; int _bytesreceived; int _rowsreceived; int _inflight; int _portalbuffersize;
+
int _synctransact;
Thread.MutexKey _unnamedportalkey,_unnamedstatementkey; protected Thread.Mutex closemux; array _params; string _statuscmdcomplete; string _query; Thread.Queue _datarows; array(mapping(string:mixed)) _datarowdesc=({}); int _oldpbpos; object _plugbuffer; string _preparedname;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:434:
} void _openportal() { _pgsqlsess->_portalsinflight++; Thread.MutexKey lock=closemux->lock(); _state=bound; lock=0; _statuscmdcomplete=UNDEFINED; }
-
int
_closeportal(PGplugbuffer plugbuffer) {
-
int
retval=
0
;
+
sctype
_closeportal(
void|
PGplugbuffer plugbuffer) {
+
sctype
retval=
keep
;
PD("%O Try Closeportal %d\n",_portalname,_state); Thread.MutexKey lock=closemux->lock(); _fetchlimit=0; // disables further Executes switch(_state) { case copyinprogress:
-
+
if(plugbuffer) {
PD("CopyDone\n"); plugbuffer->add("c\0\0\0\4");
-
+
}
case bound: _state=closed; lock=0; PD("Close portal %O\n",_portalname); if(sizeof(_portalname)) {
-
+
if(plugbuffer) {
plugbuffer->add_int8('C')->add_hstring(({'P',_portalname,0}),4,4);
-
retval=
1
;
+
retval=
flushsend
;
+
}
} else _unnamedportalkey=0;
-
if(!--_pgsqlsess->_portalsinflight) {
-
PD("Sync\n");
-
plugbuffer
->
add(PGSYNC)
;
+
if(!--_pgsqlsess->_portalsinflight
&& plugbuffer
) {
+
_pgsqlsess
->
_readyforquerycount++
;
_pgsqlsess->_pportalcount=0;
-
retval=
2
;
+
retval=
syncsend
;
} } lock=0; return retval; } final void _processdataready(int gfetchlimit) { _rowsreceived++; if(_rowsreceived==1) PD("<%O _fetchlimit %d=min(%d||1,%d), _inflight %d\n",_portalname, _fetchlimit,(_portalbuffersize>>1)*_rowsreceived/_bytesreceived, gfetchlimit,_inflight); if(_fetchlimit) { _fetchlimit= min((_portalbuffersize>>1)*_rowsreceived/_bytesreceived||1,gfetchlimit);
-
#if STREAMEXECUTES
+
Thread.MutexKey lock=closemux->lock(); if(_fetchlimit && _inflight<=_fetchlimit-1) _sendexecute(_fetchlimit);
-
#ifdef PG_DEBUG
+
else if(!_fetchlimit) PD("<%O _fetchlimit %d, _inflight %d, skip execute\n", _portalname,_fetchlimit,_inflight);
-
#endif
+
lock=0;
-
#endif
+
} } void _releasesession() { _inflight=0; _datarows->write(1); object plugbuffer=c->start(1); plugbuffer->sendcmd(_closeportal(plugbuffer)); _pgsqlsess=UNDEFINED; }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:507:
}; } final void _sendexecute(int fetchlimit,void|PGplugbuffer 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,4,8+1) ->add_int8(0)->add_int32(fetchlimit);
-
if(!fetchlimit)
{
-
_closeportal(plugbuffer)
;
-
flushmode
=
sendout
;
-
}
else
+
if(!fetchlimit)
+
flushmode=
_closeportal(plugbuffer)=
=syncsend?syncsend:flushsend
;
+
else
_inflight+=fetchlimit, flushmode=flushsend; plugbuffer->sendcmd(flushmode,this); } //! @returns //! One result row at a time. //! //! When using COPY FROM STDOUT, this method returns one row at a time //! as a single string containing the entire row. //! //! @seealso //! @[eof()], @[send_row()] array(mixed) fetch_row() { int|array datarow; if(arrayp(datarow=_datarows->try_read())) return datarow; if(!datarow && !eoffound
-
&& (
-
#ifdef PG_DEBUG
-
PD("%O Block for datarow\n",_portalname),
-
#endif
+
&& (PD("%O Block for datarow\n",_portalname),
arrayp(datarow=_datarows->read()))) return datarow; trydelayederror(); eoffound=1; return 0; } //! @returns //! Multiple result rows at a time (at least one). //!