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:5:
*/ #pike __REAL_VERSION__ #include "pgsql.h" #define FLUSH "H\0\0\0\4" //! Some pgsql utility functions
-
class PGassist {
+
class PGassist
+
{
int(-1..1) peek(int timeout)
{
}
-
int(
-1
..1)
peek(int timeout
) {
-
}
+
string read(
int
len,void|int
(
0
..1)
not_all
) { }
-
string read(
int
len,void
|
int
(
0..1
)
not_all
) {
-
}
+
int
write
(
string
|
array
(
string
)
data
) { }
-
int
write
(
string|array(string
)
data)
{
-
}
+
int
getchar
() { }
-
int
getchar
() {
-
}
+
int
close
() { }
-
int close() {
-
}
-
+
private final array(string) cmdbuf=({}); #ifdef USEPGsql inherit _PGsql.PGsql; #else object portal;
-
void setportal(void|object newportal)
{
-
portal=newportal;
+
void setportal(void|object newportal)
+
{
portal=newportal;
}
-
inline int(-1..1) bpeek(int timeout)
{
-
return peek(timeout);
+
inline int(-1..1) bpeek(int timeout)
+
{
return peek(timeout);
} int flushed=-1;
-
inline final int getbyte()
{
-
if(!flushed && !bpeek(0))
+
inline final int getbyte()
+
{
if(!flushed && !bpeek(0))
sendflush(); return getchar(); }
-
final string getstring(void|int len)
{
-
String.Buffer acc=String.Buffer();
-
if(!zero_type(len))
{
-
string res;
-
do
{
-
if(!flushed && !bpeek(0))
+
final string getstring(void|int len)
+
{
String.Buffer acc=String.Buffer();
+
if(!zero_type(len))
+
{
string res;
+
do
+
{
if(!flushed && !bpeek(0))
sendflush(); res=read(len,!flushed);
-
if(res)
{
-
if(!sizeof(res))
+
if(res)
+
{
if(!sizeof(res))
return acc->get(); acc->add(res); } } while(sizeof(acc)<len&&res); return sizeof(acc)?acc->get():res; } int c; while((c=getbyte())>0) acc->putchar(c); return acc->get(); }
-
inline final int getint16()
{
-
int s0=getbyte();
+
inline final int getint16()
+
{
int s0=getbyte();
int r=(s0&0x7f)<<8|getbyte(); return s0&0x80 ? r-(1<<15) : r ; }
-
inline final int getint32()
{
-
int r=getint16();
+
inline final int getint32()
+
{
int r=getint16();
r=r<<8|getbyte(); return r<<8|getbyte(); }
-
inline final int getint64()
{
-
int r=getint32();
+
inline final int getint64()
+
{
int r=getint32();
return r<<32|getint32()&0xffffffff; } #endif
-
inline final string plugbyte(int x)
{
-
return String.int2char(x&255);
+
inline final string plugbyte(int x)
+
{
return String.int2char(x&255);
}
-
inline final string plugint16(int x)
{
-
return sprintf("%c%c",x>>8&255,x&255);
+
inline final string plugint16(int x)
+
{
return sprintf("%c%c",x>>8&255,x&255);
}
-
inline final string plugint32(int x)
{
-
return sprintf("%c%c%c%c",x>>24&255,x>>16&255,x>>8&255,x&255);
+
inline final string plugint32(int x)
+
{
return sprintf("%c%c%c%c",x>>24&255,x>>16&255,x>>8&255,x&255);
}
-
inline final string plugint64(int x)
{
-
return sprintf("%c%c%c%c%c%c%c%c",x>>56&255,x>>48&255,x>>40&255,x>>32&255,
+
inline final string plugint64(int x)
+
{
return sprintf("%c%c%c%c%c%c%c%c",x>>56&255,x>>48&255,x>>40&255,x>>32&255,
x>>24&255,x>>16&255,x>>8&255,x&255); }
-
final void sendflush()
{
-
sendcmd(({}),1);
+
final void sendflush()
+
{
sendcmd(({}),1);
}
-
final void sendcmd(string|array(string) data,void|int flush)
{
-
if(arrayp(data))
+
final void sendcmd(string|array(string) data,void|int flush)
+
{
if(arrayp(data))
cmdbuf+=data; else cmdbuf+=({data});
-
switch(flush)
{
-
case 3:
+
switch(flush)
+
{
case 3:
cmdbuf+=({FLUSH}); flushed=1; break; default: flushed=0; break; case 1: cmdbuf+=({FLUSH}); PD("Flush\n"); case 2: flushed=1; { int i=write(cmdbuf);
-
if(portal && portal._pgsqlsess)
{
-
portal._pgsqlsess._packetssent++;
+
if(portal && portal._pgsqlsess)
+
{
portal._pgsqlsess._packetssent++;
portal._pgsqlsess._bytessent+=i; } } cmdbuf=({}); } }
-
final void sendterminate()
{
-
PD("Terminate\n");
+
final void sendterminate()
+
{
PD("Terminate\n");
sendcmd(({"X",plugint32(4)}),2); close(); }
-
void create() {
+
void create()
+
{
#ifdef USEPGsql ::create(); #endif } }
-
class PGconn
{
-
-
inherit PGassist:pg;
+
class PGconn
+
{ inherit PGassist:pg;
#ifdef UNBUFFEREDIO inherit Stdio.File:std;
-
inline int getchar()
{
-
return std::read(1)[0];
+
inline int getchar()
+
{
return std::read(1)[0];
} #else inherit Stdio.FILE:std;
-
inline int getchar()
{
-
return std::getchar();
+
inline int getchar()
+
{
return std::getchar();
} #endif
-
inline int(-1..1) peek(int timeout)
{
-
return std::peek(timeout);
+
inline int(-1..1) peek(int timeout)
+
{
return std::peek(timeout);
}
-
inline string read(int len,void|int(0..1) not_all)
{
-
return std::read(len,not_all);
+
inline string read(int len,void|int(0..1) not_all)
+
{
return std::read(len,not_all);
}
-
inline int write(string|array(string) data)
{
-
return std::write(data);
+
inline int write(string|array(string) data)
+
{
return std::write(data);
}
-
int close()
{
-
return std::close();
+
int close()
+
{
return std::close();
}
-
void create(Stdio.File stream,object t)
{
-
std::create();
+
void create(Stdio.File stream,object t)
+
{
std::create();
std::assign(stream); pg::create(); } } #if constant(SSL.sslfile)
-
class PGconnS
{
-
inherit SSL.sslfile:std;
+
class PGconnS
+
{ inherit SSL.sslfile:std;
inherit PGassist:pg; Stdio.File rawstream;
-
inline int(-1..1) peek(int timeout)
{
-
return rawstream.peek(timeout); // This is a kludge
+
inline int(-1..1) peek(int timeout)
+
{
return rawstream.peek(timeout); // This is a kludge
} // Actually SSL.sslfile should provide a peek() method
-
inline string read(int len,void|int(0..1) not_all)
{
-
return std::read(len,not_all);
+
inline string read(int len,void|int(0..1) not_all)
+
{
return std::read(len,not_all);
}
-
inline int write(string|array(string) data)
{
-
return std::write(data);
+
inline int write(string|array(string) data)
+
{
return std::write(data);
}
-
void create(Stdio.File stream, SSL.context ctx)
{
-
rawstream=stream;
+
void create(Stdio.File stream, SSL.context ctx)
+
{
rawstream=stream;
std::create(stream,ctx,1,1); pg::create(); } } #endif //! The result object returned by @[Sql.pgsql()->big_query()], except for //! the noted differences it behaves the same as @[Sql.sql_result]. //! //! @seealso
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:254:
string _statuscmdcomplete; array(array(mixed)) _datarows; array(mapping(string:mixed)) _datarowdesc=({}); array(int) _datatypeoid; #ifdef USEPGsql int _buffer; #endif private object fetchmutex;
-
protected string _sprintf(int type, void|mapping flags)
{
-
string res=UNDEFINED;
-
switch(type)
{
-
case 'O':
+
protected string _sprintf(int type, void|mapping flags)
+
{ string res=UNDEFINED;
+
switch(type)
+
{
case 'O':
res=sprintf("pgsql_result numrows: %d eof: %d querylock: %d" " inflight: %d\nportalname: %O datarows: %d\n" "query: %O\n" "laststatus: %s\n", numrows,eoffound,!!_qmtxkey,_inflight, _portalname,sizeof(_datarowdesc), query, _statuscmdcomplete||""); break; } return res; } void create(object pgsqlsess,string _query,int fetchlimit,
-
int portalbuffersize,int alltyped)
{
-
_pgsqlsess = pgsqlsess;
+
int portalbuffersize,int alltyped)
+
{ _pgsqlsess = pgsqlsess;
query = _query; _datarows = ({ }); numrows = UNDEFINED; fetchmutex = Thread.Mutex(); _fetchlimit=fetchlimit; _portalbuffersize=portalbuffersize; _alltext = !alltyped; steallock(); } //! Returns the command-complete status for this query. //! //! @seealso //! @[affected_rows()] //! //! @note //! This function is PostgreSQL-specific, and thus it is not available //! through the generic SQL-interface.
-
string status_command_complete()
{
-
return _statuscmdcomplete;
+
string status_command_complete()
+
{ return _statuscmdcomplete;
} //! Returns the number of affected rows by this query. //! //! @seealso //! @[status_command_complete()] //! //! @note //! This function is PostgreSQL-specific, and thus it is not available //! through the generic SQL-interface.
-
int affected_rows()
{
-
int rows;
+
int affected_rows()
+
{ int rows;
if(_statuscmdcomplete) sscanf(_statuscmdcomplete,"%*s %d",rows); return rows; } //! @seealso //! @[Sql.sql_result()->num_fields()]
-
int num_fields()
{
-
return sizeof(_datarowdesc);
+
int num_fields()
+
{ return sizeof(_datarowdesc);
} //! @seealso //! @[Sql.sql_result()->num_rows()]
-
int num_rows()
{
-
int numrows;
+
int num_rows()
+
{ int numrows;
sscanf(_statuscmdcomplete,"%*s %d",numrows); return numrows; } //! @seealso //! @[Sql.sql_result()->eof()]
-
int eof()
{
-
return eoffound;
+
int eof()
+
{ return eoffound;
} //! @seealso //! @[Sql.sql_result()->fetch_fields()]
-
array(mapping(string:mixed)) fetch_fields()
{
-
return _datarowdesc+({});
+
array(mapping(string:mixed)) fetch_fields()
+
{ return _datarowdesc+({});
}
-
private void releasesession()
{
-
if(_pgsqlsess)
{
-
if(copyinprogress)
{
-
PD("CopyDone\n");
+
private void releasesession()
+
{ if(_pgsqlsess)
+
{
if(copyinprogress)
+
{
PD("CopyDone\n");
_pgsqlsess._c.sendcmd("c\0\0\0\4",1); } _pgsqlsess.resync(2); } _qmtxkey=UNDEFINED; _pgsqlsess=UNDEFINED; }
-
void destroy()
{
-
catch
{
// inside destructors, exceptions don't work
-
releasesession();
+
void destroy()
+
{ catch
// inside destructors, exceptions don't work
+
{
releasesession();
}; }
-
inline private array(mixed) getdatarow()
{
-
array(mixed) datarow=_datarows[0];
+
inline private array(mixed) getdatarow()
+
{ array(mixed) datarow=_datarows[0];
_datarows=_datarows[1..]; return datarow; }
-
private void steallock()
{
+
private void steallock()
+
{
#ifndef NO_LOCKING PD("Going to steal oldportal %d\n",!!_pgsqlsess._c.portal); Thread.MutexKey stealmtxkey = _pgsqlsess._stealmutex.lock(); do
-
if(_qmtxkey = _pgsqlsess._querymutex.current_locking_key())
{
-
pgsql_result portalb;
-
if(portalb=_pgsqlsess._c.portal)
{
-
_pgsqlsess._nextportal++;
+
if(_qmtxkey = _pgsqlsess._querymutex.current_locking_key())
+
{
pgsql_result portalb;
+
if(portalb=_pgsqlsess._c.portal)
+
{
_pgsqlsess._nextportal++;
if(portalb->_interruptable) portalb->fetch_row(2);
-
else
{
-
PD("Waiting for the querymutex\n");
-
if((_qmtxkey=_pgsqlsess._querymutex.lock(2)))
{
-
if(copyinprogress)
+
else
+
{
PD("Waiting for the querymutex\n");
+
if((_qmtxkey=_pgsqlsess._querymutex.lock(2)))
+
{
if(copyinprogress)
error("COPY needs to be finished first\n"); error("Driver bug, please report, " "conflict while interleaving SQL-operations\n"); } PD("Got the querymutex\n"); } _pgsqlsess._nextportal--; } break; }
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:415:
//! array of strings to be processed by the COPY command; when sending //! the amount of data sent per call does not have to hit row or column //! boundaries. //! //! The COPY FROM STDIN sequence needs to be completed by either //! explicitly or implicitly destroying the result object, or by passing a //! zero argument to this method. //! //! @seealso //! @[eof()]
-
array(mixed) fetch_row(void|int|string|array(string) buffer)
{
+
array(mixed) fetch_row(void|int|string|array(string) buffer)
+
{
#ifndef NO_LOCKING Thread.MutexKey fetchmtxkey = fetchmutex.lock(); #endif if(!buffer && sizeof(_datarows)) return getdatarow();
-
if(copyinprogress)
{
-
fetchmtxkey = UNDEFINED;
-
if(stringp(buffer) || arrayp(buffer))
{
-
int totalsize=4;
+
if(copyinprogress)
+
{
fetchmtxkey = UNDEFINED;
+
if(stringp(buffer) || arrayp(buffer))
+
{
int totalsize=4;
if(arrayp(buffer)) foreach(buffer;;string value) totalsize+=sizeof(value); else totalsize+=sizeof(buffer),buffer=({buffer}); PD("CopyData\n"); _pgsqlsess._c.sendcmd( ({"d",_pgsqlsess._c.plugint32(totalsize)})+buffer,2); } else releasesession(); return UNDEFINED; } mixed err;
-
if(buffer!=2 && (err=delayederror))
{
-
delayederror=UNDEFINED;
+
if(buffer!=2 && (err=delayederror))
+
{
delayederror=UNDEFINED;
throw(err); }
-
err = catch
{
-
if(_portalname)
{
-
if(buffer!=2 && !_qmtxkey)
{
-
steallock();
+
err = catch
+
{
if(_portalname)
+
{
if(buffer!=2 && !_qmtxkey)
+
{
steallock();
if(_fetchlimit) _pgsqlsess._sendexecute(_fetchlimit); } while(_pgsqlsess._closesent) _pgsqlsess._decodemsg(); // Flush previous portal sequence
-
for(;;) {
+
for(;;)
+
{
#ifdef DEBUGMORE
-
PD("buffer: %d nextportal: %d lock: %d\n",
+
PD("buffer: %d nextportal: %d lock: %d\n",
buffer,_pgsqlsess._nextportal,!!_qmtxkey); #endif #ifdef USEPGsql _buffer=buffer; #endif
-
switch(_pgsqlsess._decodemsg())
{
-
case copyinresponse:
+
switch(_pgsqlsess._decodemsg())
+
{
case copyinresponse:
copyinprogress=1; return UNDEFINED; case dataready: _pgsqlsess._mstate=dataprocessed; _rowsreceived++;
-
switch(buffer)
{
-
case 0:
+
switch(buffer)
+
{
case 0:
case 1: if(_fetchlimit) _fetchlimit= min(_portalbuffersize/2*_rowsreceived/_bytesreceived || 1, _pgsqlsess._fetchlimit); }
-
switch(buffer)
{
-
case 2:
+
switch(buffer)
+
{
case 2:
case 3: continue; case 1: _interruptable=1; if(_pgsqlsess._nextportal) continue; #if STREAMEXECUTES if(_fetchlimit && _inflight<=_fetchlimit-1) _pgsqlsess._sendexecute(_fetchlimit); #endif return UNDEFINED; } #if STREAMEXECUTES if(_fetchlimit && _inflight<=_fetchlimit-1) _pgsqlsess._sendexecute(_fetchlimit); // Overlap Executes #endif return getdatarow(); case commandcomplete: _inflight=0; releasesession();
-
switch(buffer)
{
-
case 1:
+
switch(buffer)
+
{
case 1:
case 2: return UNDEFINED; case 3: if(sizeof(_datarows)) return getdatarow(); } break; case portalsuspended: if(_inflight) continue;
-
if(_pgsqlsess._nextportal)
{
-
switch(buffer)
{
-
case 1:
+
if(_pgsqlsess._nextportal)
+
{
switch(buffer)
+
{
case 1:
case 2: _qmtxkey = UNDEFINED; return UNDEFINED; case 3: _qmtxkey = UNDEFINED; return getdatarow(); } _fetchlimit=FETCHLIMITLONGRUN;
-
if(sizeof(_datarows))
{
-
_qmtxkey = UNDEFINED;
+
if(sizeof(_datarows))
+
{
_qmtxkey = UNDEFINED;
return getdatarow(); } buffer=3; } _pgsqlsess._sendexecute(_fetchlimit); default: continue; } break; }