package !== null ) { throw new Exception( 'trying to call setPackage() twice' ); } $this->package = $package; } public function query( $query , $prepare = false ) { if ( ! $this->connection ) { $this->connect( ); } if ( ! array_key_exists( $query , $this->queries ) || ( $prepare && ! $this->queries[ $query ]->prepared( ) ) ) { $this->queries[ $query ] = new DBQuery( $this->connection , $query , $prepare ); } return $this->queries[ $query ]; } public function commit( ) { if ( ! $this->connection ) { return; } if ( ! @pg_query( 'COMMIT' ) ) { throw new DatabaseError( 'COMMIT: ' . pg_last_error( ) ); } exit( 0 ); } public function connect( ) { $host = $this->package->config( 'db/host' , 'localhost' ); $port = $this->package->config( 'db/port' ); $name = $this->package->config( 'db/name' , null , true ); $user = $this->package->config( 'db/user' ); $pass = $this->package->config( 'db/password' ); $cString = array( ); $cString[] = "host=$host"; if ( $port !== null ) { $cString[] = "port=$port"; } $cString[] = "dbname=$name"; if ( $user !== null ) { $cString[] = "user=$user"; } if ( $pass !== null ) { $cString[] = "password=$pass"; } $this->connection = pg_connect( join( ' ' , $cString ) ); if ( ! $this->connection ) { throw new DatabaseError( 'connection failed' ); } if ( ! @pg_query( $this->connection , 'BEGIN TRANSACTION' ) ) { throw new DatabaseError( 'BEGIN TRANSACTION: ' . pg_last_error( ) ); } } } final class DBQuery { private static $lastStatementID = 0; private $connection; private $query; private $statement; public function __construct( $connection , $query , $prepare = false ) { $this->connection = $connection; $this->query = $query; if ( $prepare ) { $this->statement = 'prep_stmt_' . ( ++ DBQuery::$lastStatementID ); if ( ! pg_prepare( $connection , $this->statement , $query ) ) { throw new Exception( "unable to prepare statement '$query': " . pg_last_error( ) ); } } else { $this->statement = null; } } public function __destruct( ) { if ( $this->statement !== null ) { if ( ! pg_query( 'DEALLOCATE ' . $this->statement ) ) { throw new Exception( "unable to deallocate statement: " . pg_last_error( ) ); } } } public function execute( ) { $arguments = func_get_args( ); $result = array( ); if ( $this->statement !== null ) { $pgResult = pg_execute( $this->connection , $this->statement , $arguments ); } else { $pgResult = pg_query_params( $this->connection , $this->query , $arguments ); } if ( ! $pgResult ) { throw new Exception( "query \"{$this->query}\" failed: " . pg_last_error( ) ); } while ( $row = pg_fetch_object( $pgResult ) ) { array_push( $result , $row ); } pg_free_result( $pgResult ); return $result; } public function prepared( ) { return ( $this->statement !== null ); } }