diff --git a/lib/modules/Sql.pmod/pgsql.pike b/lib/modules/Sql.pmod/pgsql.pike index 95918febe446cfcd91d73ecf0f4ad828dc965fbf..78ec03ad230980281567dac2e1e0693700f271a0 100644 --- a/lib/modules/Sql.pmod/pgsql.pike +++ b/lib/modules/Sql.pmod/pgsql.pike @@ -55,6 +55,8 @@ #define ERROR(X ...) predef::error(X) +int _alltext; +int _booltext; int _nextportal; int _closesent; int _fetchlimit=FETCHLIMIT; @@ -168,6 +170,14 @@ 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 boolresults_as_text. //! @value "client_encoding" //! Character encoding for the client side, it defaults to use //! database encoding, e.g.: "SQL_ASCII" @@ -197,6 +207,8 @@ 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) @@ -729,6 +741,8 @@ 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 ? a=allocate(cols,UNDEFINED); msglen-=2+4*cols; foreach(a;int i;) { @@ -739,8 +753,11 @@ final int _decodemsg(void|state waitforstate) { switch(datarowdesc[i]->type) { default:value=_c.getstring(collen); break; - case CHAROID: + case CHAROID:value=_c.getbyte(); + break; case BOOLOID:value=_c.getbyte(); + if(btext) + value=value?"t":"f"; break; case INT8OID:value=_c.getint64(); break; @@ -751,6 +768,8 @@ final int _decodemsg(void|state waitforstate) { case OIDOID: case INT4OID:value=_c.getint32(); } + if(atext&&!stringp(value)) + value=(string)value; a[i]=value; } else if(!collen) @@ -951,7 +970,9 @@ private void reconnect(void|int force) { plugbuf+=({"user\0",user,"\0"}); if(database) plugbuf+=({"database\0",database,"\0"}); - foreach(options-(<"use_ssl","force_ssl">);string name;mixed value) + foreach(options-(<"use_ssl","force_ssl","bool_results_as_text", + "all_results_as_text">); + string name;mixed value) plugbuf+=({name,"\0",(string)value,"\0"}); plugbuf+=({"\0"}); int len=4; diff --git a/lib/modules/Sql.pmod/postgres.pike b/lib/modules/Sql.pmod/postgres.pike index 6d90e6b7a9e4ef67de14ba8aa528f3c0d84fbdf2..4455a5a4c3854bc9255c6c93d8ebd680a5a28f39 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.36 2008/08/01 12:09:38 srb Exp $ + * $Id: postgres.pike,v 1.37 2008/08/21 03:14:03 srb Exp $ * */ @@ -459,4 +459,18 @@ 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 ff3d016b917c83cfc6b8acf54ae748fabd18b102..9d640f2d0d22167ff9cd84345927a6595e45a1b2 100644 --- a/src/modules/_PGsql/PGsql.cmod +++ b/src/modules/_PGsql/PGsql.cmod @@ -1,5 +1,5 @@ /* -*- c -*- - * $Id: PGsql.cmod,v 1.24 2008/08/21 03:13:46 srb Exp $ + * $Id: PGsql.cmod,v 1.25 2008/08/21 03:14:04 srb Exp $ * * PGsql, accelerator functions for Sql.pgsql for Pike. * @@ -290,6 +290,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; struct svalue*bytesreceived; struct array*datarowdesc; struct object*portal,*pgsqlsess; @@ -324,6 +325,14 @@ outofmem: Pike_fatal("Out of memory\n"); 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(); @@ -352,9 +361,21 @@ outofmem: Pike_fatal("Out of memory\n"); switch(svp->u.integer) { default:push_string(low_getstring(collen)); break; - case CHAROID: - case BOOLOID:push_int(low_getbyte()); + case CHAROID:push_int(low_getbyte()); + break; + case BOOLOID: { + int val=low_getbyte(); + if(booltext) { + struct pike_string*s; + s = MK_STRING("f"); + if(val) + s = MK_STRING("t"); + ref_push_string(s); + } + else + push_int(val); break; + } case FLOAT4OID: { char*tb=xalloc(collen+1); char*p=tb; @@ -399,6 +420,8 @@ simple: push_int(nextword); case OIDOID: case INT4OID:push_int(low_getint32()); } + if(alltext && Pike_sp[-1].type != PIKE_T_STRING) + o_cast_to_string(); } else if(!collen) push_empty_string();