Thread: How to specify capitalization for column names in pg_fetch_object?

How to specify capitalization for column names in pg_fetch_object?

From
David McMath
Date:
Dear List,

I'm converting a PHP project from using Oracle to using Postgres.
Apparently, pg_fetch_object() wants to create an object with field names
lowercase by default.  In the Oracle analogue, they're uppercase.  So
all my code's "$obj->FIELD" references need to change to "$obj->field".

Is there any way to tell PHP or Postgres to change the default
capitalization?

In Perl, I'd use DBI and set FetchHashKeyName to "NAME_uc".  In PHP,
we're using "DB" (not MDB2) for the database connections, and I don't
see a similar-looking lever to pull on

Any advice is appreciated,

dave


Re: How to specify capitalization for column names in pg_fetch_object?

From
Andrew McMillan
Date:
On Mon, 2012-11-19 at 10:45 -0600, David McMath wrote:
> Dear List,
>
> I'm converting a PHP project from using Oracle to using Postgres.
> Apparently, pg_fetch_object() wants to create an object with field names
> lowercase by default.  In the Oracle analogue, they're uppercase.  So
> all my code's "$obj->FIELD" references need to change to "$obj->field".
>
> Is there any way to tell PHP or Postgres to change the default
> capitalization?

This has nothing to do with PHP, really, though obviously there can be
workarounds for this in connection libraries.  In PostgreSQL column
names are translated to lower case unless they are not enclosed in
double-quotes like "column_name".  In Oracle column names are translated
to upper case unless they are quoted.

So one answer would be to explicitly specify the case of the column and
to always refer to it in your SQL in double-quotes.


> In Perl, I'd use DBI and set FetchHashKeyName to "NAME_uc".  In PHP,
> we're using "DB" (not MDB2) for the database connections, and I don't
> see a similar-looking lever to pull on

You should probably use PDO, which has always seemed to be the closest
PHP comes to DBI, and look at using the "PDO_CASE_UPPER" flag on
connecting to the database.  This may do what you want.

Cheers,
                    Andrew.
--
------------------------------------------------------------------------
andrew (AT) morphoss (DOT) com                            +64(272)DEBIAN
              Does the turtle move for you?  www.kame.net
------------------------------------------------------------------------


Attachment

Re: How to specify capitalization for column names in pg_fetch_object?

From
David McMath
Date:
On 11/19/12 10:45 AM, David McMath wrote:
> Dear List,
>
> I'm converting a PHP project from using Oracle to using Postgres.
> Apparently, pg_fetch_object() wants to create an object with field
> names lowercase by default.  In the Oracle analogue, they're
> uppercase.  So all my code's "$obj->FIELD" references need to change
> to "$obj->field".
>
> Is there any way to tell PHP or Postgres to change the default
> capitalization?
>
> In Perl, I'd use DBI and set FetchHashKeyName to "NAME_uc".  In PHP,
> we're using "DB" (not MDB2) for the database connections, and I don't
> see a similar-looking lever to pull on
>
> Any advice is appreciated,
>
> dave
>
>
In case some future wanderer comes across the same problem, I'll post my
solution.  "Workaround" or "hack" might be a better term, but since my
problem is now gone I'll stick with "solution".

We have a central method for getting a database handle.  So I was able
to follow the example at


http://pear.php.net/manual/tr/package.database.db.db-common.setfetchmode.php#package.database.db.db-common.setfetchmode.example.object5

(aka "The Manual") to install a custom class in which DB results are
stored.  My class has a "__get" method that checks for properties in a
case-insensitive way.  I could have gone a different route and lowercase
(or uppercase) all fields during "__construct" but that's not what I did.

The class is "PG_data_object" below, and I added

     $db->setFetchMode( DB_FETCHMODE_OBJECT, 'PG_data_object' ) ;

toward the end of the function for fetching new handles.  This worked.
The downside is that it changed the default behavior of "fetchInto" from
DB_FETCHMODE_ORDERED to DB_FETCHMODE_OBJECT.  For me, that was a good
tradeoff; grep quickly showed me that in almost all calls to fetchInto
or fetchRow, we specified a fetchmode explicitly.  In those few where we
didn't it wasn't a hard trick to add in the explicit request for ORDERED
to get the old behavior back.  And now OBJECT is documented as our default.


Among my unsuccessful attempts, I also learned about the
"DB_PORTABILITY_LOWERCASE" option for DB::Connect.  It happens to do the
opposite of what I want, and there's no DB_PORTABILITY_UPPERCASE
available.  Also, the way it's implemented seems to suggest it only
works for DB_FETCHMODE_ASSOC (but I could well be reading that wrong,
and I didn't push too hard to figure it out).  We don't use ASSOC in our
code, but for good measure I added

     DB_PORTABILITY_ALL ^ DB_PORTABILITY_LOWERCASE

as the portability option to Connect.  It's not really that helpful,
because it only kicks in when Postgres hands me uppercase (which it's
not seeming to do), but it seems worth mentioning.


I did look at PDO as the "right" way to get everything I want.  If
someone had given that advice a few years back, I'd have been in much
better shape.  But the syntax is just too alien to our current codebase,
so here I am.


dave

--

class PG_data_object {
   private $row_data ;
   function __construct($data) {
     $this->row_data = $data ;
   }
   function __get($variable) {
     if( isset( $this->row_data[strtolower($variable)] ) ) {
       return $this->row_data[strtolower($variable)] ;
     }
     else if( isset( $this->row_data[strtoupper($variable)] ) ) {
       return $this->row_data[strtoupper($variable)] ;
     }
     else if( isset( $this->row_data[$variable] ) ) {
       return $this->row_data[$variable] ;
     }
     else {
       trigger_error( sprintf( 'Undefined property PG_data_object::$%s',
$variable ) ) ;
     }
   }
}