Location: PHPKode > projects > OpenRat CMS > openrat/db/db.class.php
<?php
//
// +----------------------------------------------------------------------+
// | PHP version 4.0                                                      |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2001 The PHP Group                                |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license,      |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | hide@address.com so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Authors: Stig Bakken <hide@address.com>                                   |
// |          Jan Dankert <hide@address.com>                           |
// +----------------------------------------------------------------------+
//

// This is the database abstraction layer. This class was inspired by the
// PHP-Pear-DB package. Thanks to its developers.

/**
 * Darstellung einer Datenbank-Verbindung.
 * F�r die echten DB-Aufrufe werden die entsprechenden
 * Methoden des passenden Clients aufgerufen.
 * 
 * Diese Klasse stammt urspruenglich aus dem PHP-Pear-DB-Projekt und unterliegt
 * daher auch der PHP-licence.
 * 
 * @author Jan Dankert
 * @package openrat.database
 */
class DB
{
	/**
	 * Datenbank-Id.
	 *
	 * @var String
	 */
	var $id;
	
	/**
	 * Konfiguration der Datenbank-Verbindung
	 *
	 * @var Array
	 */
	var $conf;
	
	/**
	 * Kennzeichen, ob die Datenbank verf�gbar ist.
	 *
	 * @var Boolean
	 */
	var $available;
	
	/**
	 * Enth�lt eine Fehlermeldung (sofern verf�gbar).
	 *
	 * @var String
	 */
	var $error;

	/**
	 * Client.
	 * Enth�lt ein Objekt der Klasse db_<type>.
	 *
	 * @var Object
	 */
	var $client;
	
	/**
	 * Schalter, ob eine Transaktion begonnen wurde.
	 * @var boolean
	 */
	var $transactionInProgress = false;
	

	/**
	 * Kontruktor.
	 * Erwartet die Datenbank-Konfiguration als Parameter.
	 *
	 * @param Array Konfiguration der Verbindung
	 * @return Status 'true' wenn Verbindung erfolgreich aufgebaut.
	 */
	function DB( $conf )
	{
		$this->available = false;
		$this->conf      = $conf;
		
		$this->connect();
		
		return $this->available;
	}
	

	/**
	 * Verbindung zur Datenbank aufbauen.
	 *
	 * @return Status
	 */
	function connect()
	{
		// Ausfuehren des Systemkommandos vor Verbindungsaufbau
		if	( !empty($this->conf['cmd']))
		{
			$ausgabe = array();
			$rc      = false;

			Logger::debug("Database command executing: ".$this->conf['cmd']);
			exec( $this->conf['cmd'],$ausgabe,$rc );
			
			foreach( $ausgabe as $zeile )
				Logger::debug("Database command output: ".$zeile);
			
			if	( $rc != 0 )
			{
				$this->error     = 'Command failed: '.implode("",$ausgabe);
				$this->available = false; 
				return false;
			}
		}
		
		$type = $this->conf['type'];
		$classname = 'db_'.$type;
		
		if	( ! class_exists($classname) )
		{
			$this->error     = 'Database type "'.$type.'" is not available';
			$this->available = false;
			return false;
		}
		
		// Client instanziieren
		$this->client = & new $classname;

		$ok = $this->client->connect( $this->conf );
		
		if	( ! $ok )
		{
			$this->error     = 'Cannot connect to database: '.$this->client->error;
			$this->available = false;
			return false; 
		}

				
		// SQL nach Verbindungsaufbau ausfuehren.
		if	( isset($this->conf['connection_sql']) &&  ! empty($this->conf['connection_sql']) )
		{
			$cmd = $this->conf['connection_sql'];
			$ok = $this->client->query($cmd);
			
			if	( ! $ok )
			{
				$this->error     = $this->client->error;
				$this->available = false;
				return false; 
			}
		}
		
		$this->available = true;
		return true;
	}


	/**
	 * Ausfuehren einer Datenbankanfrage.
	 *
	 * @param SQL-Objekt
	 * @return Object (Result)
	 */
	function query( $query )
	{
		if ( !is_object($query) )
			die('SQL-Query must be an object');
			
		// Vorbereitete Datenbankabfrage ("Prepared Statement")
		if	( isset($this->conf['prepare']) && $this->conf['prepare'] )
		{
			$this->client->clear();
			
			// Statement an die Datenbank schicken
			$this->client->prepare( $query->raw,$query->param );
			
			// Einzelne Parameter an die Anfrage binden
			foreach ($query->param as $name=>$unused)
				$this->client->bind($name,$query->data[$name]);
			
			// Ausf�hren...
			$result = $this->client->query($query);
			
			if	( $result === FALSE )
			{
				$this->error = $this->client->error;
				
				Logger::warn('Database error: '.$this->error);
				Http::serverError('Database Error',$this->error);
			}
					
			return $result;
		}
		else
		{
			// Es handelt sich um eine nicht-vorbereitete Anfrage. Das gesamte
			// SQL wird durch die SQL-Klasse erzeugt, dort werden auch die Parameter
			// in die Abfrage gesetzt.
			
			$escape_function = method_exists($this->client,'escape')?$this->client->escape():'addslashes';
			$flatQuery = $query->getQuery( $escape_function );
			
			Logger::trace('DB query on DB '.$this->id."\n".$query->raw);
	
			$result = $this->client->query($flatQuery);
			
			if	( $result === FALSE )
			{
				$this->error = $this->client->error;
				
				if	( true )
				{
					Logger::warn('Database error: '.$this->error);
					Http::serverError('Database Error',$this->error);
				}
			}
	
			if	( isset($this->conf['autocommit']) && @$this->conf['autocommit'])
				if	( method_exists($this->client,'commit') )
					$this->client->commit();
			
			return $result;
		}
	}


	/**
	 * Ermittelt genau 1 Datenbankergebnis aus einer SQL-Anfrage.
	 * Falls es mehrere Treffer gibt, wird die 1. Spalte aus der 1. Zeile genommen.
	 *
	 * @param String $query
	 * @return String
	 */
	function &getOne( $query )
	{
		$none = '';
		$result = $this->query($query);
		
		$row = $this->client->fetchRow( $result,0 );
		$this->client->freeResult($result);

		if	( ! is_array($row) )
			return $none;

		$keys = array_keys($row);
		
		return $row[ $keys[0] ];
	}


	/**
	 * Ermittelt eine Zeile aus der Datenbank.
	 *
	 * @param String $query
	 * @return Array
	 */
	function &getRow( $query )
	{
		$result = $this->query($query);
		
		if	( $result === FALSE )
		{
			$this->error = $this->client->error;
			
			Logger::warn('Database error: '.$this->error);
			Http::serverError('Database Error',$this->error);
		}

		$row = $this->client->fetchRow( $result,0 );
		$this->client->freeResult($result);

		if	( ! is_array($row) )
			$row = array();

		return $row;
	}


	/**
	 * Ermittelt eine (die 1.) Spalte aus dem Datenbankergebnis.
	 *
	 * @param String $query
	 * @return Array
	 */
	function &getCol( $query )
	{
		$result = $this->query($query);

		$i = 0;
		$col = array();
		while( $row = $this->client->fetchRow( $result,$i++ ) )
		{
			if	( empty($row) )
				break;
				
			$keys = array_keys($row);
			$col[] = $row[ $keys[0] ];
		}
			
		$this->client->freeResult($result);
		
		return $col;
	}


	/**
	 * Ermittelt ein assoziatives Array aus der Datenbank.
	 *
	 * @param String $query
	 * @param Boolean $force_array
	 * @return Array
	 */
	function &getAssoc( $query, $force_array = false )
	{
		$results = array();
		$result = $this->query($query);

		$i = 0;
		
		while( $row = $this->client->fetchRow( $result,$i++ ) )
		{
			if	( empty($row) )
				break;
				
			if	( count($row) > 2 || $force_array )
			{
				$row = $res->fetchRow($i);

				$keys = array_keys($row);
				$key1 = $keys[0];

				unset( $row[$key1] );
				$results[ $row[$key1] ] = $row;
			}
			else
			{
				$keys = array_keys($row);
				$key1 = $keys[0];
				$key2 = $keys[1];

				$results[ $row[$key1] ] = $row[$key2];
			}
		}

		$this->client->freeResult( $result );

		return $results;
	}


	/**
	 * Ermittelt alle Datenbankergebniszeilen.
	 *
	 * @param String $query
	 * @return Array
	 */
	function &getAll( $query )
	{
		$result = $this->query( $query );

		$results = array();
		$i = 0;

		while( $row = $this->client->fetchRow( $result,$i++ ) )
		{
			$results[] = $row;
		}

		$this->client->freeResult( $result );
		
		return $results;
	}
	
	
	/**
	 * Startet eine Transaktion.
	 */
	function start()
	{
		if	( @$this->conf['transaction'])
			if	( method_exists($this->client,'start') )
			{
				$this->transactionInProgress = true;
				$this->client->start();
			}
	}
	
	
	/**
	 * Beendet und best�tigt eine Transaktion.
	 */
	function commit()
	{
		if	( @$this->conf['transaction'])
			if	( method_exists($this->client,'commit') )
				if	( $this->transactionInProgress )
				{
					$this->client->commit();
					$this->transactionInProgress = false;
				}
	}
	
	/**
	 * Setzt eine Transaktion zur�ck.
	 */
	function rollback()
	{
		if	( @$this->conf['transaction'])
			if	( method_exists($this->client,'rollback') )
				if	( $this->transactionInProgress )
				{
					$this->client->rollback();
					$this->transactionInProgress = false;
				}
	}
	
}


?>
Return current item: OpenRat CMS