diff --git a/CHANGES b/CHANGES index f8617f2a66f06e9fe8502aa33d4f06dc15219db1..855d0df9c14b3af094f541d77300147cbb09f73b 100644 --- a/CHANGES +++ b/CHANGES @@ -730,8 +730,8 @@ o Sql It implements a superset of the existing Postgres driver. Current features: no library dependencies (no libpq), native binding support, streaming support, NOTIFY/LISTEN support (fully eventdriven, - no polling), binary support for integer, float and string datatypes, - compatibility options to support old return-everything-as-text mode, + no polling), binary support for integer, float and string datatypes + through big_typed_query(), COPY FROM/TO STDIN/STDOUT support, multiple simultaneous streaming queries on the same connection (i.e. multiple PostgreSQL-portal- support), automatic precompilation and caching of often-used diff --git a/lib/modules/Sql.pmod/pgsql.pike b/lib/modules/Sql.pmod/pgsql.pike index 833f92f3dbf633562d3704b1dc8d27b29b92a129..648974f02c3cd730f2f492d0c13c4ac8eb17bfd1 100644 --- a/lib/modules/Sql.pmod/pgsql.pike +++ b/lib/modules/Sql.pmod/pgsql.pike @@ -55,8 +55,6 @@ #define ERROR(X ...) predef::error(X) -int _alltext; -int _booltext; int _nextportal; int _closesent; int _fetchlimit=FETCHLIMIT; @@ -170,14 +168,6 @@ protected string _sprintf(int type, void|mapping flags) { //! @value "force_ssl" //! If the database supports and allows SSL connections, the session //! will be SSL encrypted, if not, the connection will abort -//! @value "bool_results_as_text" -//! Make boolean values retrieved from the database backward compatible -//! with the old Postgres driver which returned all values as text. -//! When off, boolean values are represented by 0 and 1, when set, -//! boolean values are represented by "f" and "t". -//! @value "all_results_as_text" -//! Make all values backward compatible with the old Postgres driver -//! which returned all values as text. Implies bool_results_as_text. //! @value "client_encoding" //! Character encoding for the client side, it defaults to use //! database encoding, e.g.: "SQL_ASCII" @@ -207,8 +197,6 @@ protected void create(void|string _host, void|string _database, String.secure(pass); user = _user; database = _database; host = _host || PGSQL_DEFAULT_HOST; options = _options || ([]); - _alltext = !!options->all_results_as_text; - _booltext = _alltext || !!options->bool_results_as_text; if(search(host,":")>=0 && sscanf(_host,"%s:%d",host,port)!=2) ERROR("Error in parsing the hostname argument\n"); if(!port) @@ -745,8 +733,7 @@ final int _decodemsg(void|state waitforstate) { _c.portal->_bytesreceived+=msglen; datarowdesc=_c.portal->_datarowdesc; int cols=_c.getint16(); - int atext = _alltext; // cache locally for speed ? - int btext = _booltext; // cache locally for speed ? + int atext = _c.portal->_alltext; // cache locally for speed a=allocate(cols,UNDEFINED); msglen-=2+4*cols; foreach(a;int i;) { @@ -760,12 +747,15 @@ final int _decodemsg(void|state waitforstate) { case CHAROID:value=_c.getbyte(); break; case BOOLOID:value=_c.getbyte(); - if(btext) + if(atext) value=value?"t":"f"; break; case INT8OID:value=_c.getint64(); break; - case FLOAT4OID:value=(float)_c.getstring(collen); + case FLOAT4OID: + value=_c.getstring(collen); + if(!atext) + value=(float)value; break; case INT2OID:value=_c.getint16(); break; @@ -1001,8 +991,7 @@ private int reconnect(void|int force) { plugbuf+=({"user\0",user,"\0"}); if(database) plugbuf+=({"database\0",database,"\0"}); - foreach(options-(<"use_ssl","force_ssl","bool_results_as_text", - "all_results_as_text">); + foreach(options-(<"use_ssl","force_ssl">); string name;mixed value) plugbuf+=({name,"\0",(string)value,"\0"}); plugbuf+=({"\0"}); @@ -1466,7 +1455,8 @@ final string status_commit() { //! //! @seealso //! @[Sql.Sql], @[Sql.sql_result], @[Sql.pgsql_util.pgsql_result] -object big_query(string q,void|mapping(string|int:mixed) bindings) { +object big_query(string q,void|mapping(string|int:mixed) bindings, + void|int _alltyped) { string preparedname=""; string portalname=""; int forcecache=-1; @@ -1549,7 +1539,7 @@ object big_query(string q,void|mapping(string|int:mixed) bindings) { } // pgsql_result autoassigns to portal else tp=UNDEFINED; - .pgsql_util.pgsql_result(this,q,_fetchlimit,portalbuffersize); + .pgsql_util.pgsql_result(this,q,_fetchlimit,portalbuffersize,_alltyped); if(unnamedportalinuse) portalname=PORTALPREFIX+(string)pportalcount++; else @@ -1705,3 +1695,12 @@ object big_query(string q,void|mapping(string|int:mixed) bindings) { object streaming_query(string q,void|mapping(string|int:mixed) bindings) { return big_query(q,bindings); } + +//! This function returns an object that allows streaming and typed +//! results. +//! +//! @seealso +//! @[big_query], @[Sql.Sql], @[Sql.sql_result] +object big_typed_query(string q,void|mapping(string|int:mixed) bindings) { + return big_query(q,bindings,1); +} diff --git a/lib/modules/Sql.pmod/pgsql_util.pmod b/lib/modules/Sql.pmod/pgsql_util.pmod index 71fd17f539063ba2f9415d02d30f09e8b9675286..10bc4b3e4e5c0252b35f409564c62c9dc09529c0 100644 --- a/lib/modules/Sql.pmod/pgsql_util.pmod +++ b/lib/modules/Sql.pmod/pgsql_util.pmod @@ -230,6 +230,7 @@ private int eoffound; private mixed delayederror; private int copyinprogress; int _fetchlimit; +int _alltext; #ifdef NO_LOCKING int _qmtxkey; @@ -273,13 +274,14 @@ protected string _sprintf(int type, void|mapping flags) { } void create(object pgsqlsess,string _query,int fetchlimit, - int portalbuffersize) { + int portalbuffersize,int alltyped) { _pgsqlsess = pgsqlsess; query = _query; _datarows = ({ }); numrows = UNDEFINED; fetchmutex = Thread.Mutex(); _fetchlimit=fetchlimit; _portalbuffersize=portalbuffersize; + _alltext = !alltyped; steallock(); } diff --git a/lib/modules/Sql.pmod/postgres.pike b/lib/modules/Sql.pmod/postgres.pike index 4455a5a4c3854bc9255c6c93d8ebd680a5a28f39..5a10a8b7fdce13ace2e3c30cac5a95f339d86fe9 100644 --- a/lib/modules/Sql.pmod/postgres.pike +++ b/lib/modules/Sql.pmod/postgres.pike @@ -1,7 +1,7 @@ /* * This is part of the Postgres module for Pike. * - * $Id: postgres.pike,v 1.37 2008/08/21 03:14:03 srb Exp $ + * $Id: postgres.pike,v 1.38 2008/08/25 12:04:53 srb Exp $ * */ @@ -459,18 +459,4 @@ int|object streaming_query(object|string q, //! @seealso //! @[Sql.pgsql], @[Sql.Sql] inherit Sql.pgsql; - -protected void create(void|string _host, void|string _db, - void|string _user, void|string _pass, void|mapping(string:mixed) _options) { - string pass; - pass = _pass; _pass = "CENSORED"; - if(pass) - String.secure(pass); - if(!_options) - _options = ([]); - - _options->bool_results_as_text=1; - - ::create(_host, _db, _user, pass, _options); -} #endif /* constant(Postgres.postgres) */ diff --git a/src/modules/_PGsql/PGsql.cmod b/src/modules/_PGsql/PGsql.cmod index 2141bafc9bc0546d30eb5a999805307c091c8ab6..6bfc8330c373e85ad7ad038d64c1956a02341ab1 100644 --- a/src/modules/_PGsql/PGsql.cmod +++ b/src/modules/_PGsql/PGsql.cmod @@ -1,5 +1,5 @@ /* -*- c -*- - * $Id: PGsql.cmod,v 1.26 2008/08/21 03:17:53 srb Exp $ + * $Id: PGsql.cmod,v 1.27 2008/08/25 12:04:53 srb Exp $ * * PGsql, accelerator functions for Sql.pgsql for Pike. * @@ -291,7 +291,7 @@ outofmem: Pike_fatal("Out of memory\n"); long totalrecvd=0, recvdbstats=0; int nrows=0, buffer=0; int rowsreceived,inflight,fetchlimit,parentfetchlimit,portalbuffersize; - int booltext, alltext; + int alltext; struct svalue*bytesreceived; struct array*datarowdesc; struct object*portal,*pgsqlsess; @@ -320,20 +320,16 @@ outofmem: Pike_fatal("Out of memory\n"); f_arrow(2); portalbuffersize=Pike_sp[-1].u.integer; pop_stack(); + ref_push_object(portal); ref_push_string(MK_STRING("_alltext")); + f_arrow(2); alltext=Pike_sp[-1].u.integer; + pop_stack(); + ref_push_object(portal); ref_push_string(MK_STRING("_buffer")); f_arrow(2); if(Pike_sp[-1].type == PIKE_T_INT) buffer=Pike_sp[-1].u.integer; pop_stack(); - ref_push_object(pgsqlsess); ref_push_string(MK_STRING("_booltext")); - f_arrow(2); booltext=Pike_sp[-1].u.integer; - pop_stack(); - - ref_push_object(pgsqlsess); ref_push_string(MK_STRING("_alltext")); - f_arrow(2); alltext=Pike_sp[-1].u.integer; - pop_stack(); - ref_push_object(pgsqlsess); ref_push_string(MK_STRING("_fetchlimit")); f_arrow(2); parentfetchlimit=Pike_sp[-1].u.integer; pop_stack(); @@ -366,7 +362,7 @@ outofmem: Pike_fatal("Out of memory\n"); break; case BOOLOID: { int val=low_getbyte(); - if(booltext) { + if(alltext) { struct pike_string*s; s = MK_STRING("f"); if(val) @@ -377,15 +373,18 @@ outofmem: Pike_fatal("Out of memory\n"); push_int(val); break; } - case FLOAT4OID: { - char*tb=xalloc(collen+1); - char*p=tb; - do - *p++=low_getbyte(); - while(--collen); - *p=0; push_float(atof(tb)); xfree(tb); + case FLOAT4OID: + if(alltext) + push_string(low_getstring(collen)); + else { + char*tb=xalloc(collen+1); + char*p=tb; + do + *p++=low_getbyte(); + while(--collen); + *p=0; push_float(atof(tb)); xfree(tb); + } break; - } case INT2OID:push_int(low_getint16()); break; case INT8OID: {