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:408:
//! @seealso //! @[Sql.sql_result], @[Sql.pgsql], @[Sql.Sql], @[Sql.pgsql()->big_query()] class sql_result { private object pgsqlsess; private int eoffound; private conxion c; final mixed _delayederror; final int _state; final int _fetchlimit;
-
final
int
_
alltext;
+
private
int alltext;
final int _forcetext; final string _portalname; private int rowsreceived; private int inflight; private int portalbuffersize; private Stdio.Buffer prepbuffer; private Thread.Condition prepbufferready; private Thread.Mutex prepbuffermux; private Thread.Mutex closemux; private Thread.Queue datarows;
-
+
private array(mapping(string:mixed)) datarowdesc;
private string statuscmdcomplete;
-
final
int
_
bytesreceived;
+
private
int bytesreceived;
final int _synctransact; final Thread.Condition _ddescribe; final Thread.Mutex _ddescribemux; final Thread.MutexKey _unnamedportalkey,_unnamedstatementkey; final array _params; final string _query;
-
final array(mapping(string:mixed)) _datarowdesc;
+
final string _preparedname; final mapping(string:mixed) _tprepared; private string _sprintf(int type, void|mapping flags) { string res=UNDEFINED; switch(type) { case 'O': res=sprintf("sql_result state: %d numrows: %d eof: %d inflight: %d\n" "query: %O\n" "portalname: %O datarows: %d" " laststatus: %s\n", _state,rowsreceived,eoffound,inflight, _query,
-
_portalname,
_
datarowdesc&&sizeof(
_
datarowdesc),
+
_portalname,datarowdesc&&sizeof(datarowdesc),
statuscmdcomplete||(_unnamedstatementkey?"*parsing*":"")); break; } return res; } protected void create(object _pgsqlsess,conxion _c,string query, int _portalbuffersize,int alltyped,array params,int forcetext) { pgsqlsess = _pgsqlsess; c = _c; _query = query; datarows = Thread.Queue(); _ddescribe=Thread.Condition(); _ddescribemux=Thread.Mutex(); closemux=Thread.Mutex(); prepbufferready=Thread.Condition(); prepbuffermux=Thread.Mutex(); portalbuffersize=_portalbuffersize;
-
_
alltext = !alltyped;
+
alltext = !alltyped;
_params = params; _forcetext = forcetext; _state = PORTALINIT; } //! Returns the command-complete status for this query. //! //! @seealso //! @[affected_rows()] //!
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:495:
//! @note //! This function is PostgreSQL-specific, and thus it is not available //! through the generic SQL-interface. int affected_rows() { int rows; if(statuscmdcomplete) sscanf(statuscmdcomplete,"%*s %d",rows); return rows; }
+
final void _storetiming() {
+
if(_tprepared) {
+
_tprepared.trun=gethrtime()-_tprepared.trunstart;
+
m_delete(_tprepared,"trunstart");
+
_tprepared = UNDEFINED;
+
}
+
}
+
private void waitfordescribe() { Thread.MutexKey lock=_ddescribemux->lock();
-
if(!
_
datarowdesc)
+
if(!datarowdesc)
_ddescribe->wait(lock); lock=0; } //! @seealso //! @[Sql.sql_result()->num_fields()] int num_fields() {
-
if(!
_
datarowdesc)
+
if(!datarowdesc)
waitfordescribe(); trydelayederror();
-
return sizeof(
_
datarowdesc);
+
return sizeof(datarowdesc);
} //! @seealso //! @[Sql.sql_result()->num_rows()] int num_rows() { trydelayederror(); return rowsreceived; } private inline void trydelayederror() {
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:533:
//! @seealso //! @[Sql.sql_result()->eof()] int eof() { trydelayederror(); return eoffound; } //! @seealso //! @[Sql.sql_result()->fetch_fields()] array(mapping(string:mixed)) fetch_fields() {
-
if(!
_
datarowdesc)
+
if(!datarowdesc)
waitfordescribe(); trydelayederror();
-
return
_
datarowdesc+({});
+
return datarowdesc+({});
}
-
final void _setrowdesc(array(mapping(string:mixed))
datarowdesc
) {
+
#ifdef
PG_DEBUG
+
final
int
+
#else
+
final
void
+
#endif
+
_
decodedata(int msglen,string cenc) {
+
_storetiming();
+
string serror;
+
bytesreceived+=msglen;
+
int cols=c->read_int16();
+
array a=allocate(cols,!alltext&&Val.null);
+
#ifdef PG_DEBUG
+
msglen-=2+4*cols;
+
#endif
+
foreach(datarowdesc;int i;mapping m) {
+
int collen=c->read_sint(4);
+
if(collen>0) {
+
#ifdef PG_DEBUG
+
msglen-=collen;
+
#endif
+
mixed value;
+
switch(int typ=m.type) {
+
case FLOAT4OID:
+
#if SIZEOF_FLOAT>=8
+
case FLOAT8OID:
+
#endif
+
if(!alltext) {
+
value=(float)c->read(collen);
+
break;
+
}
+
default:value=c->read(collen);
+
break;
+
case CHAROID:
+
value=alltext?c->read(1):c->read_int8();
+
break;
+
case BOOLOID:value=c->read_int8();
+
switch(value) {
+
case 'f':value=0;
+
break;
+
case 't':value=1;
+
}
+
if(alltext)
+
value=value?"t":"f";
+
break;
+
case TEXTOID:
+
case BPCHAROID:
+
case VARCHAROID:
+
value=c->read(collen);
+
if(cenc==UTF8CHARSET && catch(value=utf8_to_string(value))
+
&& !serror)
+
serror=SERROR("%O contains non-%s characters\n",
+
value,UTF8CHARSET);
+
break;
+
case INT8OID:case INT2OID:
+
case OIDOID:case INT4OID:
+
if(_forcetext) {
+
value=c->read(collen);
+
if(!alltext)
+
value=(int)value;
+
} else {
+
switch(typ) {
+
case INT8OID:value=c->read_sint(8);
+
break;
+
case INT2OID:value=c->read_sint(2);
+
break;
+
case OIDOID:
+
case INT4OID:value=c->read_sint(4);
+
}
+
if(alltext)
+
value=(string)value;
+
}
+
}
+
a[i]=value;
+
} else if(!collen)
+
a[i]="";
+
}
+
_processdataready(a);
+
if(serror)
+
error(serror);
+
#ifdef PG_DEBUG
+
return msglen;
+
#endif
+
}
+
+
final void _
setrowdesc(array(mapping(string:mixed))
drowdesc
) {
Thread.MutexKey lock=_ddescribemux->lock();
-
_
datarowdesc=
datarowdesc
;
+
datarowdesc=
drowdesc
;
_ddescribe->broadcast(); lock=0; } final void _preparebind(array dtoid) { array(string|int) paramValues=_params?_params[2]:({}); if(sizeof(dtoid)!=sizeof(paramValues)) SUSERERROR("Invalid number of bindings, expected %d, got %d\n", sizeof(dtoid),sizeof(paramValues)); #ifdef PG_DEBUGMORE
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:709:
if(!prepbuffer) catch(prepbufferready->wait(lock)); plugbuffer=prepbuffer; prepbuffer=0; // Free memory when plugbuffer leaves scope } if(!prepbufferready || _state==CLOSED) lock=_unnamedstatementkey=0; else { destruct(prepbufferready); // Make sure we do this exactly once lock=0;
-
plugbuffer->add_int16(sizeof(
_
datarowdesc));
-
if(sizeof(
_
datarowdesc))
-
foreach(
_
datarowdesc;;mapping col)
+
plugbuffer->add_int16(sizeof(datarowdesc));
+
if(sizeof(datarowdesc))
+
foreach(datarowdesc;;mapping col)
plugbuffer->add_int16(oidformat(col.type)); else if(commitprefix->match(_query)) { lock=pgsqlsess->_commitmux->lock(); if(pgsqlsess->_portalsinflight) { pgsqlsess->_waittocommit++; PD("Commit waiting for portals to finish\n"); pgsqlsess->_readyforcommit->wait(lock); pgsqlsess->_waittocommit--; } lock=0;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:805:
} else if(!alreadyfilled) pgsqlsess->_readyforquerycount++, retval=SYNCSEND; pgsqlsess->_pportalcount=0; } lockc=0; } lock=0; return retval; }
-
final void _processdataready(array datarow) {
+
final void _processdataready(array datarow
,void|int msglen
) {
+
bytesreceived+=msglen;
inflight--; datarows->write(datarow);
-
rowsreceived++;
-
if(
rowsreceived
==1)
+
if(
++rowsreceived
==1)
PD("<%O _fetchlimit %d=min(%d||1,%d), inflight %d\n",_portalname,
-
_fetchlimit,(portalbuffersize>>1)*rowsreceived/
_
bytesreceived,
+
_fetchlimit,(portalbuffersize>>1)*rowsreceived/bytesreceived,
pgsqlsess._fetchlimit,inflight); if(_fetchlimit) { _fetchlimit=
-
min((portalbuffersize>>1)*rowsreceived/
_
bytesreceived||1,
+
min((portalbuffersize>>1)*rowsreceived/bytesreceived||1,
pgsqlsess._fetchlimit); Thread.MutexKey lock=closemux->lock(); if(_fetchlimit && inflight<=_fetchlimit-1) _sendexecute(_fetchlimit); else if(!_fetchlimit) PD("<%O _fetchlimit %d, inflight %d, skip execute\n", _portalname,_fetchlimit,inflight); lock=0; } } private void releaseconditions() { pgsqlsess=0; Thread.MutexKey lock; if(prepbufferready) { Thread.MutexKey lock=prepbuffermux->lock(); catch(prepbufferready->signal()); }
-
if(!
_
datarowdesc) {
+
if(!datarowdesc) {
lock=_ddescribemux->lock();
-
_
datarowdesc=({});
+
datarowdesc=({});
_ddescribe->broadcast(); } lock=0; } final void _releasesession(void|string statusccomplete) { if(statusccomplete && !statuscmdcomplete) statuscmdcomplete=statusccomplete; inflight=0; datarows->write(1); // Signal EOF