ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
ae952f | 2014-11-10 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | |
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
ae952f | 2014-11-10 | Stephen R. van den Berg | |
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | #pike __REAL_VERSION__
|
5691e4 | 2014-11-10 | Stephen R. van den Berg | | #require constant(Thread.Thread)
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
#include "pgsql.h"
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | final Pike.Backend local_backend = Pike.SmallBackend();
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private Thread.Mutex backendmux = Thread.Mutex();
private int clientsregistered;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | final multiset cachealways=(<"BEGIN","begin","END","end","COMMIT","commit">);
final Regexp createprefix
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | =Regexp("^[ \t\f\r\n]*[Cc][Rr][Ee][Aa][Tt][Ee][ \t\f\r\n]");
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private Regexp dontcacheprefix
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | =Regexp("^[ \t\f\r\n]*([Ff][Ee][Tt][Cc][Hh]|[Cc][Oo][Pp][Yy])[ \t\f\r\n]");
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | private Regexp commitprefix=Regexp(
"^[ \t\f\r\n]*([Cc][Oo][Mm][Mm][Ii][Tt]|[Ee][Nn][Dd])([ \t\f\r\n;]|$)");
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private Regexp execfetchlimit
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | =Regexp("^[ \t\f\r\n]*(([Uu][Pp][Dd][Aa]|[Dd][Ee][Ll][Ee])[Tt][Ee]|\
[Ii][Nn][Ss][Ee][Rr][Tt])[ \t\f\r\n]|\
[ \t\f\r\n][Ll][Ii][Mm][Ii][Tt][ \t\f\r\n]+[12][; \t\f\r\n]*$");
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | final void closestatement(bufcon|conxion plugbuffer,string oldprep) {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | if(oldprep) {
PD("Close statement %s\n",oldprep);
plugbuffer->add_int8('C')->add_hstring(({'S',oldprep,0}),4,4);
}
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private void run_local_backend() {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | Thread.MutexKey lock;
int looponce;
do {
looponce=0;
if(lock=backendmux->trylock()) {
PD("Starting local backend\n");
while(clientsregistered)
local_backend(4096.0);
PD("Terminating local backend\n");
lock=0;
looponce=clientsregistered;
}
} while(looponce);
}
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | final void register_backend() {
if(!clientsregistered++)
Thread.Thread(run_local_backend);
}
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | final void unregister_backend() {
--clientsregistered;
}
|
4741cd | 2008-07-31 | Stephen R. van den Berg | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | final void throwdelayederror(object parent) {
if(mixed err=parent._delayederror) {
parent._delayederror=UNDEFINED;
if(stringp(err))
err=({err,backtrace()[..<2]});
throw(err);
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | final int oidformat(int oid) {
switch(oid) {
case BOOLOID:
case BYTEAOID:
case CHAROID:
case INT8OID:
case INT2OID:
case INT4OID:
case TEXTOID:
case OIDOID:
case XMLOID:
case MACADDROID:
case BPCHAROID:
case VARCHAROID:
case CTIDOID:
case UUIDOID:
return 1;
}
return 0;
}
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | private int mergemode(conxion realbuffer,int mode) {
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | if(mode>realbuffer->stashflushmode)
realbuffer->stashflushmode=mode;
return realbuffer->stashflushmode;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private inline mixed callout(function(mixed ...:void) f,
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | float|int delay,mixed ... args) {
return local_backend->call_out(f,delay,@args);
}
|
ae952f | 2014-11-10 | Stephen R. van den Berg | |
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | class bufcon {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | inherit Stdio.Buffer;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | private conxion realbuffer;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | protected void create(conxion _realbuffer) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | realbuffer=_realbuffer;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
d43282 | 2008-07-31 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | final bufcon start(void|int waitforreal) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | realbuffer->stashcount++;
#ifdef PG_DEBUG
if(waitforreal)
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | error("pgsql.bufcon not allowed here\n");
|
d43282 | 2008-07-31 | Stephen R. van den Berg | | #endif
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return this;
}
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | final void sendcmd(int mode,void|sql_result portal) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | Thread.MutexKey lock=realbuffer->stashupdate->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;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | realbuffer->sendcmd(SENDOUT);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
d43282 | 2008-07-31 | Stephen R. van den Berg | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | class conxion {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | inherit Stdio.Buffer:i;
inherit Stdio.Buffer:o;
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private Thread.Condition fillread;
private Thread.Mutex fillreadmux;
private Thread.Queue qportals;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | final Stdio.File socket;
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private object pgsqlsess;
private int towrite;
|
3bf511 | 2014-11-17 | Stephen R. van den Berg | | private Thread.Mutex towritemux;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
final function(:void) gottimeout;
final int timeout;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final Thread.Mutex nostash;
final Thread.MutexKey started;
final Thread.Mutex stashupdate;
final Thread.Queue stashqueue;
final Thread.Condition stashavail;
final Stdio.Buffer stash;
final int stashflushmode;
final int stashcount;
final int synctransact;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final int queueoutidx;
|
f0522e | 2014-11-13 | Stephen R. van den Berg | | final int queueinidx=-1;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | #endif
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | private inline void queueup(sql_result portal) {
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | qportals->write(portal); portal->_synctransact=synctransact;
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | PD("%d>%O %d %d Queue portal %d bytes\n",socket->query_fd(),
portal._portalname,++queueoutidx,synctransact,sizeof(this));
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | }
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | final conxion|bufcon start(void|int waitforreal) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | Thread.MutexKey lock;
if(lock=(waitforreal?nostash->lock:nostash->trylock)(1)) {
started=lock;
lock=stashupdate->lock();
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | if(stashcount)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | stashavail.wait(lock);
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | add(stash); stash->clear();
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | foreach(stashqueue->try_read_array();;sql_result portal)
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | queueup(portal);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | lock=0;
return this;
}
stashcount++;
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | return bufcon(this);
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
4c327c | 2014-11-10 | Stephen R. van den Berg | | protected bool range_error(int howmuch) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | if(!howmuch)
return false;
#ifdef PG_DEBUG
if(howmuch<0)
error("Out of range %d\n",howmuch);
#endif
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | if(fillread) {
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | array cid=callout(gottimeout,timeout);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | Thread.MutexKey lock=fillreadmux->lock();
fillread.wait(lock);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | lock=0;
local_backend->remove_call_out(cid);
} else
throw(MAGICTERMINATE);
return true;
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private int read_cb(mixed id,mixed b) {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | Thread.MutexKey lock=fillreadmux->lock();
if(fillread)
fillread.signal();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | lock=0;
return 0;
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private int write_cb() {
|
3bf511 | 2014-11-17 | Stephen R. van den Berg | | Thread.MutexKey lock=towritemux->lock();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | towrite-=output_to(socket,towrite);
|
3bf511 | 2014-11-17 | Stephen R. van den Berg | | lock=0;
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | if(!fillread && !sizeof(this)) {
PD("%d>Close socket delayed\n",socket->query_fd());
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | socket->close();
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return 0;
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | final inline int consume(int w) { return i::consume(w); }
final inline int unread(int w) { return i::unread(w); }
final inline string read(int w) { return i::read(w); }
final inline object read_buffer(int w) { return i::read_buffer(w); }
final inline int read_sint(int w) { return i::read_sint(w); }
final inline int read_int8() { return i::read_int8(); }
final inline int read_int16() { return i::read_int16(); }
final inline int read_int32() { return i::read_int32(); }
final inline string read_cstring() { return i::read_cstring(); }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | final void sendcmd(void|int mode,void|sql_result portal) {
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | if(portal)
queueup(portal);
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | nosync:
do {
switch(mode) {
default:
break nosync;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case SYNCSEND:
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | PD("%d>Sync %d %d Queue\n",
socket->query_fd(),synctransact,++queueoutidx);
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | add(PGSYNC);
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | mode=SENDOUT;
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | break;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case FLUSHLOGSEND:
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | PD("%d>%O %d Queue simplequery %d bytes\n",
socket->query_fd(),portal._portalname,++queueoutidx,sizeof(this));
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | mode=FLUSHSEND;
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | }
qportals->write(synctransact++);
} while(0);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | if(started) {
Thread.MutexKey lock=stashupdate->lock();
if(sizeof(stash)) {
add(stash); stash->clear();
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | foreach(stashqueue->try_read_array();;sql_result portal)
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | queueup(portal);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
mode=mergemode(this,mode);
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | stashflushmode=KEEP;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | lock=0;
}
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | catch {
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | outer:
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | do {
switch(mode) {
default:
break outer;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case FLUSHSEND:
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | PD("Flush\n");
add(PGFLUSH);
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case SENDOUT:;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | }
|
3bf511 | 2014-11-17 | Stephen R. van den Berg | | Thread.MutexKey lock=towritemux->lock();
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | if(towrite=sizeof(this)) {
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | PD("%d>Sendcmd %O\n",socket->query_fd(),((string)this)[..towrite-1]);
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | towrite-=output_to(socket,towrite);
}
|
3bf511 | 2014-11-17 | Stephen R. van den Berg | | lock=0;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | } while(0);
started=0;
return;
};
|
d88e73 | 2014-11-14 | Stephen R. van den Berg | | if(pgsqlsess)
pgsqlsess->_connectfail();
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | final void sendterminate() {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | destruct(fillread);
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | final int close() {
|
d88e73 | 2014-11-14 | Stephen R. van den Berg | | destruct(nostash);
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | PD("%d>Close socket\n",socket->query_fd());
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return socket->close();
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
838482 | 2014-11-12 | Stephen R. van den Berg | | protected void destroy() {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | catch(close());
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | pgsqlsess=0;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final void connectloop(int nossl) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | mixed err=catch {
for(;;clear()) {
socket->connect(pgsqlsess._host,pgsqlsess._port);
|
fc7f09 | 2014-06-01 | Martin Nilsson | | #if constant(SSL.File)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | if(!nossl && !pgsqlsess->nossl
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | && (pgsqlsess._options.use_ssl || pgsqlsess._options.force_ssl)) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | PD("SSLRequest\n");
start()->add_int32(8)->add_int32(PG_PROTOCOL(1234,5679))
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | ->sendcmd(SENDOUT);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | switch(read_int8()) {
case 'S':
object fcon=SSL.File(socket,SSL.Context());
if(fcon->connect()) {
socket=fcon;
break;
}
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | default:PD("%d>Close socket\n",socket->query_fd());
socket->close();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | pgsqlsess.nossl=1;
continue;
case 'N':
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | if(pgsqlsess._options.force_ssl)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | error("Encryption not supported on connection to %s:%d\n",
pgsqlsess.host,pgsqlsess.port);
}
}
#else
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | if(pgsqlsess._options.force_ssl)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | error("Encryption library missing,"
" cannot establish connection to %s:%d\n",
pgsqlsess.host,pgsqlsess.port);
#endif
break;
}
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | if(!socket->is_open())
error(strerror(socket->errno()));
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | socket->set_backend(local_backend);
socket->set_buffer_mode(i::this,0);
socket->set_nonblocking(read_cb,write_cb,0);
Thread.Thread(pgsqlsess->_processloop,this);
return;
};
|
d88e73 | 2014-11-14 | Stephen R. van den Berg | | if(pgsqlsess)
pgsqlsess->_connectfail(err);
|
480874 | 2014-11-14 | Stephen R. van den Berg | | }
private string _sprintf(int type, void|mapping flags) {
string res=UNDEFINED;
switch(type) {
case 'O':
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | res=predef::sprintf("conxion fd: %d input queue: %d/%d "
|
480874 | 2014-11-14 | Stephen R. van den Berg | | "queued portals: %d output queue: %d/%d\n",
socket&&socket->query_fd(),
sizeof(i::this),i::_size_object(),
qportals->size(),sizeof(this),_size_object());
break;
}
return res;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | protected void create(object _pgsqlsess,Thread.Queue _qportals,int nossl) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | i::create(); o::create();
qportals = _qportals;
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | synctransact = 1;
|
3bf511 | 2014-11-17 | Stephen R. van den Berg | | towritemux=Thread.Mutex();
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | fillread=Thread.Condition();
fillreadmux=Thread.Mutex();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | gottimeout=sendcmd;
timeout=128;
socket=Stdio.File();
nostash=Thread.Mutex();
stashupdate=Thread.Mutex();
stashqueue=Thread.Queue();
stashavail=Thread.Condition();
stash=Stdio.Buffer();
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | pgsqlsess=_pgsqlsess;
Thread.Thread(connectloop,nossl);
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
}
|
f4c9d6 | 2009-02-15 | Stephen R. van den Berg | |
|
041296 | 2009-01-19 | Stephen R. van den Berg | |
|
f4c9d6 | 2009-02-15 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | class sql_result {
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private object pgsqlsess;
private int eoffound;
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | private conxion c;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final mixed _delayederror;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | final int _state;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final int _fetchlimit;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | private int alltext;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final int _forcetext;
final string _portalname;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | 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;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | private array(mapping(string:mixed)) datarowdesc;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | private string statuscmdcomplete;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | private int bytesreceived;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final int _synctransact;
final Thread.Condition _ddescribe;
final Thread.Mutex _ddescribemux;
final Thread.MutexKey _unnamedportalkey,_unnamedstatementkey;
final array _params;
final string _query;
final string _preparedname;
final mapping(string:mixed) _tprepared;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private string _sprintf(int type, void|mapping flags) {
|
11b13b | 2014-08-16 | Martin Nilsson | | string res=UNDEFINED;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | switch(type) {
case 'O':
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | res=sprintf("sql_result state: %d numrows: %d eof: %d inflight: %d\n"
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | "query: %O\n"
|
1a0238 | 2014-11-18 | Stephen R. van den Berg | | "fd: %O portalname: %O datarows: %d"
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | " laststatus: %s\n",
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | _state,rowsreceived,eoffound,inflight,
|
1a0238 | 2014-11-18 | Stephen R. van den Berg | | _query,c?->socket?->query_fd(),
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | _portalname,datarowdesc&&sizeof(datarowdesc),
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | statuscmdcomplete||(_unnamedstatementkey?"*parsing*":""));
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | break;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
return res;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | protected void create(object _pgsqlsess,conxion _c,string query,
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | int _portalbuffersize,int alltyped,array params,int forcetext) {
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | pgsqlsess = _pgsqlsess;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | c = _c;
|
11b13b | 2014-08-16 | Martin Nilsson | | _query = query;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | datarows = Thread.Queue();
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | _ddescribe=Thread.Condition();
_ddescribemux=Thread.Mutex();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | closemux=Thread.Mutex();
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | prepbufferready=Thread.Condition();
prepbuffermux=Thread.Mutex();
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | portalbuffersize=_portalbuffersize;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | alltext = !alltyped;
|
11b13b | 2014-08-16 | Martin Nilsson | | _params = params;
_forcetext = forcetext;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | _state = PORTALINIT;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | string status_command_complete() {
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | return statuscmdcomplete;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | int affected_rows() {
|
11b13b | 2014-08-16 | Martin Nilsson | | int rows;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | if(statuscmdcomplete)
sscanf(statuscmdcomplete,"%*s %d",rows);
|
11b13b | 2014-08-16 | Martin Nilsson | | return rows;
}
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | final void _storetiming() {
if(_tprepared) {
_tprepared.trun=gethrtime()-_tprepared.trunstart;
m_delete(_tprepared,"trunstart");
_tprepared = UNDEFINED;
}
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private void waitfordescribe() {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | Thread.MutexKey lock=_ddescribemux->lock();
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | if(!datarowdesc)
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | _ddescribe->wait(lock);
lock=0;
}
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | int num_fields() {
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | if(!datarowdesc)
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | waitfordescribe();
trydelayederror();
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | return sizeof(datarowdesc);
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | int num_rows() {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | trydelayederror();
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | return rowsreceived;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private inline void trydelayederror() {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | if(_delayederror)
throwdelayederror(this);
}
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | int eof() {
trydelayederror();
|
11b13b | 2014-08-16 | Martin Nilsson | | return eoffound;
}
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | array(mapping(string:mixed)) fetch_fields() {
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | if(!datarowdesc)
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | waitfordescribe();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | trydelayederror();
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | return 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
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | final void _setrowdesc(array(mapping(string:mixed)) drowdesc) {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | Thread.MutexKey lock=_ddescribemux->lock();
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | datarowdesc=drowdesc;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | _ddescribe->broadcast();
lock=0;
}
|
075c54 | 2014-11-03 | Stephen R. van den Berg | | final void _preparebind(array dtoid) {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | 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
PD("ParamValues to bind: %O\n",paramValues);
#endif
|
91d654 | 2014-11-10 | Stephen R. van den Berg | | Stdio.Buffer plugbuffer=Stdio.Buffer();
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | plugbuffer->add(_portalname=
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | (_unnamedportalkey=pgsqlsess._unnamedportalmux->trylock(1))
? "" : PORTALPREFIX+int2hex(pgsqlsess._pportalcount++) )->add_int8(0)
|
678c51 | 2014-11-18 | Stephen R. van den Berg | | ->add(_preparedname)->add_int8(0)->add_int16(sizeof(dtoid));
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | foreach(dtoid;;int textbin)
plugbuffer->add_int16(oidformat(textbin));
|
678c51 | 2014-11-18 | Stephen R. van den Berg | | plugbuffer->add_int16(sizeof(dtoid));
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | string cenc=pgsqlsess._runtimeparameter[CLIENT_ENCODING];
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | foreach(paramValues;int i;mixed value) {
|
5ccc2e | 2014-11-09 | Stephen R. van den Berg | | if(undefinedp(value) || objectp(value)&&value->is_val_null)
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | plugbuffer->add_int32(-1);
else if(stringp(value) && !sizeof(value)) {
int k=0;
switch(dtoid[i]) {
default:
k=-1;
case BYTEAOID:
case TEXTOID:
case XMLOID:
case BPCHAROID:
case VARCHAROID:;
}
plugbuffer->add_int32(k);
} else
switch(dtoid[i]) {
case TEXTOID:
case BPCHAROID:
case VARCHAROID: {
if(!value) {
plugbuffer->add_int32(-1);
break;
}
value=(string)value;
switch(cenc) {
case UTF8CHARSET:
value=string_to_utf8(value);
break;
default:
if(String.width(value)>8) {
SUSERERROR("Don't know how to convert %O to %s encoding\n",
value,cenc);
value="";
}
}
plugbuffer->add_hstring(value,4);
break;
}
default: {
if(!value) {
plugbuffer->add_int32(-1);
break;
}
value=(string)value;
if(String.width(value)>8)
if(dtoid[i]==BYTEAOID)
value=string_to_utf8(value);
else {
SUSERERROR("Wide string %O not supported for type OID %d\n",
value,dtoid[i]);
value="";
}
plugbuffer->add_hstring(value,4);
break;
}
case BOOLOID:plugbuffer->add_int32(1);
do {
int tval;
if(stringp(value))
tval=value[0];
else if(!intp(value)) {
value=!!value;
break;
} else
tval=value;
switch(tval) {
case 'o':case 'O':
catch {
tval=value[1];
value=tval=='n'||tval=='N';
};
break;
default:
value=1;
break;
case 0:case '0':case 'f':case 'F':case 'n':case 'N':
value=0;
break;
}
} while(0);
plugbuffer->add_int8(value);
break;
case CHAROID:
if(intp(value))
plugbuffer->add_hstring(value,4);
else {
value=(string)value;
switch(sizeof(value)) {
default:
SUSERERROR(
"\"char\" types must be 1 byte wide, got %O\n",value);
case 0:
plugbuffer->add_int32(-1);
break;
case 1:
plugbuffer->add_hstring(value[0],4);
}
}
break;
case INT8OID:
plugbuffer->add_int32(8)->add_int((int)value,8);
break;
case OIDOID:
case INT4OID:
plugbuffer->add_int32(4)->add_int32((int)value);
break;
case INT2OID:
plugbuffer->add_int32(2)->add_int16((int)value);
break;
}
}
if(_tprepared)
if(_tprepared.datarowdesc)
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | gotdatarowdesc(plugbuffer);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | else if(dontcacheprefix->match(_query))
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | m_delete(pgsqlsess->_prepareds,_query),_tprepared=0;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | if(prepbufferready) {
|
dd5ac2 | 2014-11-17 | Stephen R. van den Berg | | Thread.MutexKey lock=prepbuffermux->lock();
|
56cd39 | 2014-11-17 | Stephen R. van den Berg | | prepbuffer=plugbuffer;
|
dd5ac2 | 2014-11-17 | Stephen R. van den Berg | | catch(prepbufferready->signal());
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | lock=0;
}
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
final void _processrowdesc(array(mapping(string:mixed)) datarowdesc) {
_setrowdesc(datarowdesc);
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | if(_tprepared)
_tprepared.datarowdesc=datarowdesc;
if(prepbufferready)
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | Thread.Thread(gotdatarowdesc);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | private void gotdatarowdesc(void|Stdio.Buffer plugbuffer) {
|
dd5ac2 | 2014-11-17 | Stephen R. van den Berg | | Thread.MutexKey lock=prepbuffermux->lock();
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | if(!plugbuffer) {
if(!prepbuffer)
catch(prepbufferready->wait(lock));
plugbuffer=prepbuffer;
prepbuffer=0;
}
if(!prepbufferready || _state==CLOSED)
lock=_unnamedstatementkey=0;
else {
destruct(prepbufferready);
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | lock=0;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | plugbuffer->add_int16(sizeof(datarowdesc));
if(sizeof(datarowdesc))
foreach(datarowdesc;;mapping col)
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | 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;
}
PD("Bind portal %O statement %O\n",_portalname,_preparedname);
_fetchlimit=pgsqlsess->_fetchlimit;
_openportal();
conxion bindbuffer=c->start(1);
_unnamedstatementkey=0;
bindbuffer->add_int8('B')->add_hstring(plugbuffer,4,4);
|
678c51 | 2014-11-18 | Stephen R. van den Berg | | if(!_tprepared && sizeof(_preparedname))
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | closestatement(bindbuffer,_preparedname);
_sendexecute(pgsqlsess->_fetchlimit
&& !(cachealways[_query]
|| sizeof(_query)>=MINPREPARELENGTH &&
execfetchlimit->match(_query))
&& FETCHLIMITLONGRUN,bindbuffer);
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | }
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
final void _openportal() {
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | pgsqlsess->_portalsinflight++;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | Thread.MutexKey lock=closemux->lock();
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | _state=BOUND;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | lock=0;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | statuscmdcomplete=UNDEFINED;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | final void _purgeportal() {
|
04f130 | 2014-11-14 | Stephen R. van den Berg | | _unnamedportalkey=_unnamedstatementkey=0;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | Thread.MutexKey lock=closemux->lock();
_fetchlimit=0;
switch(_state) {
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case COPYINPROGRESS:
case BOUND:
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | datarows->write(1);
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | --pgsqlsess->_portalsinflight;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | _state=CLOSED;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | lock=0;
|
04f130 | 2014-11-14 | Stephen R. van den Berg | | releaseconditions();
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | final int _closeportal(bufcon plugbuffer) {
int retval=KEEP;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | PD("%O Try Closeportal %d\n",_portalname,_state);
Thread.MutexKey lock=closemux->lock();
_fetchlimit=0;
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | int alreadyfilled=sizeof(plugbuffer);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | switch(_state) {
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case PORTALINIT:
|
04f130 | 2014-11-14 | Stephen R. van den Berg | | _unnamedstatementkey=0;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | _state=CLOSED;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | break;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case COPYINPROGRESS:
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | PD("CopyDone\n");
plugbuffer->add("c\0\0\0\4");
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case BOUND:
_state=CLOSED;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | lock=0;
PD("Close portal %O\n",_portalname);
if(sizeof(_portalname)) {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | plugbuffer->add_int8('C')->add_hstring(({'P',_portalname,0}),4,4);
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | retval=FLUSHSEND;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | } else
_unnamedportalkey=0;
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | Thread.MutexKey lockc=pgsqlsess->_commitmux->lock();
if(!--pgsqlsess->_portalsinflight) {
if(pgsqlsess->_waittocommit) {
PD("Signal no portals in flight\n");
pgsqlsess->_readyforcommit->signal();
lockc=0;
} else if(!alreadyfilled)
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | pgsqlsess->_readyforquerycount++, retval=SYNCSEND;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | pgsqlsess->_pportalcount=0;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
1412f3 | 2014-11-13 | Stephen R. van den Berg | | lockc=0;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
lock=0;
return retval;
}
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | final void _processdataready(array datarow,void|int msglen) {
bytesreceived+=msglen;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | inflight--;
datarows->write(datarow);
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | if(++rowsreceived==1)
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | PD("<%O _fetchlimit %d=min(%d||1,%d), inflight %d\n",_portalname,
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | _fetchlimit,(portalbuffersize>>1)*rowsreceived/bytesreceived,
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | pgsqlsess._fetchlimit,inflight);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | if(_fetchlimit) {
_fetchlimit=
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | min((portalbuffersize>>1)*rowsreceived/bytesreceived||1,
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | pgsqlsess._fetchlimit);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | Thread.MutexKey lock=closemux->lock();
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | if(_fetchlimit && inflight<=_fetchlimit-1)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | _sendexecute(_fetchlimit);
else if(!_fetchlimit)
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | PD("<%O _fetchlimit %d, inflight %d, skip execute\n",
_portalname,_fetchlimit,inflight);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | lock=0;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
04f130 | 2014-11-14 | Stephen R. van den Berg | | private void releaseconditions() {
pgsqlsess=0;
|
f0522e | 2014-11-13 | Stephen R. van den Berg | | Thread.MutexKey lock;
|
dd5ac2 | 2014-11-17 | Stephen R. van den Berg | | if(prepbufferready) {
|
f0522e | 2014-11-13 | Stephen R. van den Berg | | Thread.MutexKey lock=prepbuffermux->lock();
|
dd5ac2 | 2014-11-17 | Stephen R. van den Berg | | catch(prepbufferready->signal());
|
f0522e | 2014-11-13 | Stephen R. van den Berg | | }
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | if(!datarowdesc) {
|
f0522e | 2014-11-13 | Stephen R. van den Berg | | lock=_ddescribemux->lock();
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | datarowdesc=({});
|
56cd39 | 2014-11-17 | Stephen R. van den Berg | | _ddescribe->broadcast();
|
f0522e | 2014-11-13 | Stephen R. van den Berg | | }
lock=0;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | final void _releasesession(void|string statusccomplete) {
if(statusccomplete && !statuscmdcomplete)
statuscmdcomplete=statusccomplete;
inflight=0;
datarows->write(1);
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | conxion plugbuffer=c->start(1);
|
04f130 | 2014-11-14 | Stephen R. van den Berg | | plugbuffer->sendcmd(_closeportal(plugbuffer));
releaseconditions();
}
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | protected void destroy() {
catch {
_releasesession();
|
11b13b | 2014-08-16 | Martin Nilsson | | };
}
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | final void _sendexecute(int fetchlimit,void|bufcon plugbuffer) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | 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);
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | if(!fetchlimit)
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | flushmode=_closeportal(plugbuffer)==SYNCSEND?SYNCSEND:FLUSHSEND;
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | else
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | inflight+=fetchlimit, flushmode=FLUSHSEND;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | plugbuffer->sendcmd(flushmode,this);
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
array(mixed) fetch_row() {
int|array datarow;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | if(arrayp(datarow=datarows->try_read()))
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return datarow;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | if(!eoffound) {
if(!datarow
&& (PD("%O Block for datarow\n",_portalname),
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | arrayp(datarow=datarows->read())))
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | return datarow;
eoffound=1;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | datarows->write(1);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | trydelayederror();
return 0;
}
array(array(mixed)) fetch_row_array() {
if(eoffound)
return 0;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | array(array|int) datarow=datarows->try_read_array();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | if(!datarow)
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | datarow=datarows->read_array();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | if(arrayp(datarow[-1]))
return datarow;
trydelayederror();
eoffound=1;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | datarows->write(1);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return (datarow=datarow[..<1]);
}
|
ae952f | 2014-11-10 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
void send_row(void|string|array(string) copydata) {
trydelayederror();
if(copydata) {
PD("CopyData\n");
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | c->start()->add_int8('d')->add_hstring(copydata,4,4)->sendcmd(SENDOUT);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | } else
_releasesession();
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private void run_result_cb(
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | function(sql_result, array(mixed), mixed ...:void) callback,
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | array(mixed) args) {
int|array datarow;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | while(arrayp(datarow=datarows->read_array()))
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | callout(callback, 0, this, datarow, @args);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | trydelayederror();
eoffound=1;
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | callout(callback, 0, this, 0, @args);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
void set_result_callback(
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | function(sql_result, array(mixed), mixed ...:void) callback,
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | mixed ... args) {
if(callback)
Thread.Thread(run_result_cb,callback,args);
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private void run_result_array_cb(
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | function(sql_result, array(array(mixed)), mixed ...:void) callback,
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | array(mixed) args) {
array(array|int) datarow;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | while((datarow=datarows->read_array()) && arrayp(datarow[-1]))
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | callout(callback, 0, this, datarow, @args);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | trydelayederror();
eoffound=1;
if(sizeof(datarow)>1)
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | callout(callback, 0, this, datarow=datarow[..<1], @args);
callout(callback, 0, this, 0, @args);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
void set_result_array_callback(
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | function(sql_result, array(array(mixed)), mixed ...:void) callback,
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | mixed ... args) {
if(callback)
Thread.Thread(run_result_array_cb,callback,args);
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|