0
0
Fork 0
easterhegg-2007-website/clsdb.php

669 lines
23 KiB
PHP

<?php
class clsdb
{
// class clsdb.php
// database abstraction layer, supports multiple databases
/*
usage:
- activatedb() will be called automatically each time you use runsql() (it will guarantee database availability)
- you may call deactivatedb() at the end of your work (e.g. at end of script)
- in normal operation use control constants in your main code and just call runsql() and similar functions
control variables:
mstrdbtype declares database type of constants DB_TYPE_*, e.g. "POSTGRESQL", "ODBC", "MYSQL" or others
each database type needs some more special variables:
POSTGRESQL:
- mstrdbhost, e.g. "localhost"
- mintdbport, e.g. 5432
- mstrdbname, e.g. "testdatabase"
- mstrdbuser, e.g. "testuser"
- mstrdbpass, e.g. "testpass"
ODBC:
- mstrdbname, e.g. "testdatabase"
- mstrdbuser, e.g. "testuser"
- mstrdbpass, e.g. "testpass"
property functions:
- [get/set]dbtype
- [get/set]dbhost
- [get/set]dbport
- [get/set]dbname
- [get/set]dbuser
- [get/set]dbpass
- [get]dbdefaultschemas
- [get]dbrowcount
- [get]dblastsql
- [get]dberror
methods:
- __constructor clsdb = initializes class instance
- initdb = initializes database
- activatedb = activates/opens database connection, will be called automatically
- deactivatedb = deactivates/closes database connection, will be done automatically at the end of the parent script
- changedbdefaultschemas = changes search list of default schemas in database
- runsql = executes SQL statement on given database connection
- getdbrow = fetches row on position intdbrow from mintdbresultid as associative array into strdbrow
- getdbfields = returns list of field names, field type and field length from mintdbresultid as associative arrays into strdbfields
- dbtimestamp = converts given timestamp into database format
*/
// class constants are always public and static and can be defined by: const constantname = constantvalue;
// refer to them from within or from outside the class by: classname::constantname
// e.g.: tstclass::tstconstant
const DB_TYPE_NONE = "";
const DB_TYPE_POSTGRESQL = "POSTGRESQL";
const DB_TYPE_ODBC = "ODBC";
const DB_TYPE_MYSQL = "MYSQL";
const DB_PORT_NONE = 0;
const DB_PORT_POSTGRESQL = 5432;
const DB_PORT_ODBC = 0;
const DB_PORT_MYSQL = 3306;
const DB_ROW_FIRST = 0;
const DB_ROW_NEXT = -1;
const DB_ROW_LAST = -2;
const DB_FIELD_NAME = 0;
const DB_FIELD_TYPE = 1;
const DB_FIELD_LEN = 2;
private $mstrdbtype;
private $mstrdbhost;
private $mintdbport;
private $mstrdbname;
private $mstrdbuser;
private $mstrdbpass;
private $mintdbconnid;
private $mintdbresultid;
private $mstrdbdefaultschemas;
private $mlngdbrowcount;
private $mstrdblastsql;
private $mstrdberror;
// **********************************************************************
function __construct ()
// class constructor, initializes class instance
{
// init class
$this->initdb();
}
// **********************************************************************
// public property functions
function setdbtype ( $strdbtype ) { $this->mstrdbtype = trim( $strdbtype ); }
function getdbtype () { return $this->mstrdbtype; }
function setdbhost ( $strdbhost ) { $this->mstrdbhost = trim( $strdbhost ); }
function getdbhost () { return $this->mstrdbhost; }
function setdbport ( $intdbport ) { $this->mintdbport = intval( $intdbport ); }
function getdbport () { return $this->mintdbport; }
function setdbname ( $strdbname ) { $this->mstrdbname = trim( $strdbname ); }
function getdbname () { return $this->mstrdbname; }
function setdbuser ( $strdbuser ) { $this->mstrdbuser = trim( $strdbuser ); }
function getdbuser () { return $this->mstrdbuser; }
function setdbpass ( $strdbpass ) { $this->mstrdbpass = $strdbpass; }
function getdbpass () { return $this->mstrdbpass; }
function getdbdefaultschemas () { return $this->mstrdbdefaultschemas; }
function getdbrowcount () { return $this->mlngdbrowcount; }
function getdblastsql () { return $this->mstrdblastsql; }
function getdberror () { return $this->mstrdberror; }
// **********************************************************************
function initdb()
// initdb = initializes database
{
$this->mstrdbtype = clsdb::DB_TYPE_NONE;
$this->mstrdbhost = 'localhost';
$this->mintdbport = clsdb::DB_PORT_NONE;
$this->mstrdbname = '';
$this->mstrdbuser = '';
$this->mstrdbpass = '';
$this->mstrdefaultschemas = '';
$this->mintdbconnid = 0;
$this->mintdbresultid = 0;
$this->mstrdblastsql = '';
$this->mlngdbrowcount = 0;
$this->mstrdberror = '';
}
// **********************************************************************
function activatedb ()
// activates/opens database connection, will be called automatically
// updates mintdbconnid and mstrdberror
// returns true if database had already been opened or has been opened successfully,
// otherwise returns false and sets mstrdberror
{
$bolretcode = true;
$this->mstrdberror = '';
if ( $this->mintdbconnid == 0 )
{
// database is dead or closed -> (re)open it
switch ( $this->mstrdbtype )
{
case clsdb::DB_TYPE_POSTGRESQL:
if ( $this->mintdbport == clsdb::DB_PORT_NONE ) { $this->mintdbport = clsdb::DB_PORT_POSTGRESQL; }
$this->mintdbconnid = pg_connect ("host=" . $this->mstrdbhost . " port=" . strval( $this->mintdbport ) . " dbname=" . $this->mstrdbname . " user=" . $this->mstrdbuser . " password=" . $this->mstrdbpass );
$this->mstrdberror = pg_last_error( $this->mintdbconnid );
break;
case clsdb::DB_TYPE_ODBC:
if ( $this->mintdbport == clsdb::DB_PORT_NONE ) { $this->mintdbport = clsdb::DB_PORT_ODBC; }
$this->mintdbconnid = odbc_connect ( $this->mstrdbname, $this->mstrdbuser, $this->mstrdbpass, SQL_CUR_USE_ODBC );
$this->mstrdberror = odbc_errormsg( $this->mintdbconnid );
break;
case clsdb::DB_TYPE_MYSQL:
if ( $this->mintdbport == clsdb::DB_PORT_NONE ) { $this->mintdbport = clsdb::DB_PORT_MYSQL; }
$this->mintdbconnid = mysql_connect ( $this->mstrdbhost . ':' . strval( $this->mintdbport ), $this->mstrdbuser, $this->mstrdbpass );
$this->mstrdberror = mysql_error( $this->mintdbconnid );
if ( $this->mintdbconnid != 0 )
{
if ( !mysql_select_db ( $this->mstrdbname, $this->mintdbconnid )) { $this->mintdbconnid = 0; }
$this->mstrdberror = mysql_error( $this->mintdbconnid );
}
break;
default:
// db type not supported!
$this->mintdbconnid = 0;
$this->mstrdberror = 'Sorry, database of type "' . $this->mstrdbtype . '" is not supported.';
break;
}
// set return code on success
$bolretcode = ( $this->mintdbconnid != 0 );
if ( $bolretcode and $this->mstrdefaultschemas != '' )
{
// reset default schemas of database
$bolretcode = changedbdefaultschemas( $this->mstrdefaultschemas );
}
}
return $bolretcode;
}
// **********************************************************************
function deactivatedb ()
// deactivates/closes database connection, will be done automatically at the end of the parent script
// updates mintdbconnid and mstrdberror
// returns true if database had already been closed or has been closed successfully,
// otherwise returns false and sets mstrdberror
{
$bolretcode = true;
$this->mstrdberror = '';
if ( $this->mintdbconnid != 0 )
{
// database is still opened -> close it
switch ( $this->mstrdbtype )
{
case clsdb::DB_TYPE_POSTGRESQL:
$bolretcode = pg_close ( $this->mintdbconnid );
$this->mstrdberror = pg_last_error( $this->mintdbconnid );
break;
case clsdb::DB_TYPE_ODBC:
$bolretcode = odbc_close ( $this->mintdbconnid );
$this->mstrdberror = odbc_errormsg( $this->mintdbconnid );
break;
case clsdb::DB_TYPE_MYSQL:
$bolretcode = mysql_close ( $this->mintdbconnid );
$this->mstrdberror = mysql_error( $this->mintdbconnid );
break;
default:
// db type not supported!
$bolretcode = false;
$this->mstrdberror = 'Sorry, database of type "' . $this->mstrdbtype . '" is not supported.';
break;
}
}
// init/clear database connection on success
if ( $bolretcode )
{
initdb();
}
return $bolretcode;
}
// **********************************************************************
function changedbdefaultschemas ( $strdbdefaultschemas )
// changes search list of default schemas in database
// expects comma separated list of schema names, but ignores empty list
// returns true if no schemas were given or default schemas have been updated
// and false if some error occured when updating
{
$bolretcode = true;
if ( $strdbdefaultschemas != '' )
{
// do not change to empty value
$bolretcode = false;
if ( $this->activatedb() )
{
// database is ok
// change default schemas
switch ( $this->mstrdbtype )
{
case clsdb::DB_TYPE_POSTGRESQL:
if ( $this->runsql( "set session search_path to " . $strdbdefaultschemas ))
{
$bolretcode = true;
}
else
{
$this->mstrdberror = pg_last_error( $this->mintdbconnid );
}
break;
case clsdb::DB_TYPE_ODBC:
$this->mstrdberror = 'Sorry, changing the default database schema generically is not supported on ODBC databases.';
break;
case clsdb::DB_TYPE_MYSQL:
$this->mstrdberror = 'Sorry, database schemas are not supported on MYSQL databases.';
break;
default:
// db type not supported!
$this->mstrdberror = 'Sorry, database of type "' . $this->mstrdbtype . '" is not supported.';
break;
}
}
else
{
// database is dead or closed ->
$this->mstrdberror = 'Sorry, database is currently not available.';
}
// remember current database default schemas
if ( $bolretcode )
{
$this->mstrdbdefaultschemas = $strdbdefaultschemas;
}
}
return $bolretcode;
}
// **********************************************************************
function runsql ( $strdbsql )
// executes SQL statement on given database connection
// updates mlngdbrowcount, mintdbresultid and mstrdberror
// returns true and sets mlngdbrowcount and mintdbresultid if SQL statement had been executed successfully,
// otherwise returns false and sets mstrdberror
{
$bolretcode = false;
$this->mlngdbrowcount = 0;
$this->mintdbresultid = 0;
$this->mstrdberror = '';
if ( $this->activatedb() )
{
// database is ok
switch ( $this->mstrdbtype )
{
case clsdb::DB_TYPE_POSTGRESQL:
$this->mintdbresultid = pg_query ( $this->mintdbconnid, $strdbsql );
$this->mstrdberror = pg_last_error( $this->mintdbconnid );
if ( $this->mintdbresultid != 0 )
{
if ( strtolower(substr( trim( $strdbsql ), 0, 6 ) == 'select' ) )
{
$this->mlngdbrowcount = pg_num_rows( $this->mintdbresultid );
}
else
{
$this->mlngdbrowcount = pg_affected_rows( $this->mintdbresultid );
}
$bolretcode = true;
}
break;
case clsdb::DB_TYPE_ODBC:
$this->mintdbresultid = odbc_exec ( $this->mintdbconnid, $strdbsql );
$this->mstrdberror = odbc_errormsg( $this->mintdbconnid );
if ( $this->mintdbresultid != 0 )
{
// Attention: odbc_num_rows may return wrong record count in SELECT-statements!
// to retrieve exact number of records in SELECT statements you should walk through the recordset
$this->mlngdbrowcount = odbc_num_rows( $this->mintdbresultid );
$bolretcode = true;
}
break;
case clsdb::DB_TYPE_MYSQL:
$this->mintdbresultid = mysql_query ( $strdbsql, $this->mintdbconnid );
$this->mstrdberror = mysql_error( $this->mintdbconnid );
if ( $this->mintdbresultid != 0 )
{
if ( strtolower(substr( trim( $strdbsql ), 0, 6 ) == 'select' ) )
{
$this->mlngdbrowcount = mysql_num_rows( $this->mintdbresultid );
}
else
{
$this->mlngdbrowcount = mysql_affected_rows( $this->mintdbconnid );
}
$bolretcode = true;
}
break;
default:
// db type not supported!
$bolretcode = false;
$this->mstrdberror = 'Sorry, database of type "' . $this->mstrdbtype . '" is not supported.';
break;
}
}
return $bolretcode;
}
// **********************************************************************
function getdbrow ( &$strdbrow, $intdbrow = clsdb::DB_ROW_NEXT )
// fetches row on position intdbrow from mintdbresultid as associative array into strdbrow
// position intdbrow may be DB_RESULT_NEXTROW to fetch the next row of mintdbresultid
// updates mstrdberror
// returns true and sets strdbrow if row has been fetched successfully,
// otherwise returns false and sets mstrdberror
{
$bolretcode = false;
$strdbrow = array();
$intindex = 0;
$this->mstrdberror = '';
if ( $this->mintdbresultid != 0 )
{
// resultset is ok
switch ( $this->mstrdbtype )
{
case clsdb::DB_TYPE_POSTGRESQL:
switch ( $intdbrow )
{
case clsdb::DB_ROW_FIRST:
$bolretcode = ( $strdbrow = pg_fetch_assoc( $this->mintdbresultid, 0 ));
break;
case clsdb::DB_ROW_NEXT:
$bolretcode = ( $strdbrow = pg_fetch_assoc( $this->mintdbresultid ));
break;
case clsdb::DB_ROW_LAST:
$bolretcode = ( $strdbrow = pg_fetch_assoc( $this->mintdbresultid, pg_num_rows( $this->mintdbresultid ) - 1 ));
break;
default:
// specific $intdbrow given -> use it directly, offer start at position 1
$bolretcode = ( $strdbrow = pg_fetch_assoc( $this->mintdbresultid, $intdbrow - 1 ));
break;
}
$this->mstrdberror = pg_result_error( $this->mintdbresultid );
if ( $bolretcode )
{
// cast special field types to common string values
$intindex = 0;
while ( $intindex < pg_num_fields( $this->mintdbresultid ))
{
if ( pg_field_type( $this->mintdbresultid, $intindex ) == 'bool' )
{
// boolean type of postgresql is "f" or "t"
// -> convert to "0" or "1"
switch ( $strdbrow[pg_field_name( $this->mintdbresultid, $intindex )] )
{
case 'f':
$strdbrow[pg_field_name( $this->mintdbresultid, $intindex )] = '0';
break;
case 't':
$strdbrow[pg_field_name( $this->mintdbresultid, $intindex )] = '1';
break;
}
}
$intindex++;
}
}
break;
case clsdb::DB_TYPE_ODBC:
switch ( $intdbrow )
{
case clsdb::DB_ROW_FIRST:
$bolretcode = ( $strdbrow = odbc_fetch_array( $this->mintdbresultid, 0 ));
break;
case clsdb::DB_ROW_NEXT:
$bolretcode = ( $strdbrow = odbc_fetch_array( $this->mintdbresultid ));
break;
case clsdb::DB_ROW_LAST:
// Attention: odbc_num_rows may return wrong record count in SELECT-statements!
// to retrieve exact number of records in SELECT statements you should walk through the recordset
$bolretcode = ( $strdbrow = odbc_fetch_array( $this->mintdbresultid, odbc_num_rows( $this->mintdbresultid ) - 1 ));
break;
default:
// specific $intdbrow given -> use it directly, offer start at position 1
$bolretcode = ( $strdbrow = odbc_fetch_array( $this->mintdbresultid, $intdbrow - 1));
break;
}
// ODBC does not support error messages on resultset level
if ( !$bolretcode )
{
$this->mstrdberror = 'Sorry, could not read result row on position ' . $intdbrow ;
}
break;
case clsdb::DB_TYPE_MYSQL:
switch ( $intdbrow )
{
case clsdb::DB_ROW_FIRST:
$bolretcode = mysql_data_seek( $this->mintdbresultid, 0 );
$this->mstrdberror = mysql_error( $this->mintdbconnid );
break;
case clsdb::DB_ROW_NEXT:
// just stay where the pointer is
$bolretcode = true;
break;
case clsdb::DB_ROW_LAST:
$bolretcode = mysql_data_seek( $this->mintdbresultid, mysql_num_rows( $this->mintdbresultid ) - 1 );
$this->mstrdberror = mysql_error( $this->mintdbconnid );
break;
default:
// specific $intdbrow given -> use it directly, offer start at position 1
$bolretcode = mysql_data_seek( $this->mintdbresultid, $intdbrow - 1 );
$this->mstrdberror = mysql_error( $this->mintdbconnid );
break;
}
if ( $bolretcode )
{
$bolretcode = ( $strdbrow = mysql_fetch_assoc( $this->mintdbresultid ));
$this->mstrdberror = mysql_error( $this->mintdbconnid );
}
break;
default:
// db type not supported!
$bolretcode = false;
$this->mstrdberror = 'Sorry, database of type "' . $this->mstrdbtype . '" is not supported.';
break;
}
}
else
{
$bolretcode = false;
$this->mstrdberror = 'Sorry, no data available to read.';
}
if ( $bolretcode )
{
// convert boolean string ('f', 't') manually to ('0', '1')
}
return $bolretcode;
}
// **********************************************************************
function getdbfields ( &$strdbfields )
// returns list of field names, field type and field length from mintdbresultid as associative arrays into strdbfields
// strdbfields will contain following partial arrays: DB_FIELD_NAME, DB_FIELD_TYPE, DB_FIELD_LEN
// use as following: $strdbfields[clsdb::DB_FIELD_*][$intdbfield or $strdbfieldname]
// example: $intdbfieldtype[$strdbfieldname] = $strdbfields[DB_FIELD_TYPE][$strdbfieldname]
// updates parameter strdbfields, mstrdberror
// returns true and sets strdbfields if field names have been retrieved successfully,
// otherwise returns false and sets mstrdberror
{
$bolretcode = false;
$intindex = 0;
$strfieldname = '';
$strdbfields = array (clsdb::DB_FIELD_NAME => array(),
clsdb::DB_FIELD_TYPE => array(),
clsdb::DB_FIELD_LEN => array());
$this->mstrdberror = '';
if ( $this->mintdbresultid != 0 )
{
// resultset is ok
//no errors expected at all
$bolretcode = true;
switch ( $this->mstrdbtype )
{
case clsdb::DB_TYPE_POSTGRESQL:
// field numeration in PostgreSQL starts with 0
$intindex = 0;
while ( $intindex < pg_num_fields( $this->mintdbresultid ))
{
array_push ( $strdbfields[clsdb::DB_FIELD_NAME], pg_field_name( $this->mintdbresultid, $intindex ));
array_push ( $strdbfields[clsdb::DB_FIELD_TYPE], pg_field_type( $this->mintdbresultid, $intindex ));
array_push ( $strdbfields[clsdb::DB_FIELD_LEN], pg_field_prtlen( $this->mintdbresultid, $intindex ));
$intindex++;
}
$this->mstrdberror = pg_result_error( $this->mintdbresultid );
break;
case clsdb::DB_TYPE_ODBC:
// field numeration in ODBC starts with 1
$intindex = 1;
while ( $intindex <= odbc_num_fields( $this->mintdbresultid ))
{
$strfieldname = odbc_field_name( $this->mintdbresultid, $intindex );
array_push ( $strdbfields[clsdb::DB_FIELD_NAME], $strfieldname );
array_push ( $strdbfields[clsdb::DB_FIELD_TYPE], odbc_field_type( $this->mintdbresultid, $intindex ));
array_push ( $strdbfields[clsdb::DB_FIELD_LEN], odbc_field_len( $this->mintdbresultid, $intindex ));
$intindex++;
}
// ODBC does not support error messages on resultset level
if ( !$bolretcode )
{
$this->mstrdberror = 'Sorry, could not read field names.';
}
break;
case clsdb::DB_TYPE_MYSQL:
// field numeration in MYSQL starts with 0
$intindex = 0;
while ( $intindex < mysql_num_fields( $this->mintdbresultid ))
{
array_push ( $strdbfields[clsdb::DB_FIELD_NAME], mysql_field_name( $this->mintdbresultid, $intindex ));
array_push ( $strdbfields[clsdb::DB_FIELD_TYPE], mysql_field_type( $this->mintdbresultid, $intindex ));
array_push ( $strdbfields[clsdb::DB_FIELD_LEN], mysql_field_len( $this->mintdbresultid, $intindex ));
$intindex++;
}
$this->mstrdberror = mysql_error( $this->mintdbconnid );
break;
default:
// db type not supported!
$bolretcode = false;
$this->mstrdberror = 'Sorry, database of type "' . $this->mstrdbtype . '" is not supported.';
break;
}
}
else
{
$bolretcode = false;
$this->mstrdberror = 'Sorry, no data available to read.';
}
return $bolretcode;
}
// **********************************************************************
function dbtimestamp( $vartimestamp )
// converts given timestamp into database format
{
$strretcode = '';
$inttimestamp = 0;
if ( is_numeric( $vartimestamp ) )
{
// UNIX timestamp assumed
$inttimestamp = $vartimestamp;
}
else
{
// time string assumed
$inttimestamp = strtotime( $vartimestamp );
}
// inttimestamp now contains UNIX timestamp
switch ( $this->mstrdbtype )
{
case clsdb::DB_TYPE_POSTGRESQL:
$strretcode = "TIMESTAMP '" . date( "Y-m-d H:i:s", $vartimestamp) . "'";
break;
case clsdb::DB_TYPE_ODBC:
$strretcode = "'" . date( "Y-m-d H:i:s", $vartimestamp) . "'";
break;
case clsdb::DB_TYPE_MYSQL:
$strretcode = "'" . date( "YmdHis", $vartimestamp ) . "'";
break;
default:
// db type not supported!
// -> return original string
$strretcode = $vartimestamp;
break;
}
return $strretcode;
}
}
?>