PgSQL.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2004-2007 by Konstantin V. Arkhipov                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 /* $Id: PgSQL.class.php 4687 2007-12-09 18:57:18Z voxus $ */
00012 
00020     final class PgSQL extends DB
00021     {
00025         public static function getDialect()
00026         {
00027             return PostgresDialect::me();
00028         }
00029         
00033         public function connect()
00034         {
00035             $conn =
00036                 "host={$this->hostname} user={$this->username}"
00037                 .($this->password ? " password={$this->password}" : null)
00038                 .($this->basename ? " dbname={$this->basename}" : null)
00039                 .($this->port ? " port={$this->port}" : null);
00040 
00041             if ($this->persistent)
00042                 $this->link = pg_pconnect($conn);
00043             else
00044                 $this->link = pg_connect($conn);
00045 
00046             if (!$this->link)
00047                 throw new DatabaseException(
00048                     'can not connect to PostgreSQL server: '.pg_errormessage()
00049                 );
00050             
00051             if ($this->encoding)
00052                 $this->setDbEncoding();
00053             
00054             pg_set_error_verbosity($this->link, PGSQL_ERRORS_VERBOSE);
00055 
00056             return $this;
00057         }
00058         
00062         public function disconnect()
00063         {
00064             if ($this->isConnected())
00065                 pg_close($this->link);
00066 
00067             return $this;
00068         }
00069         
00070         public function isConnected()
00071         {
00072             return is_resource($this->link);
00073         }
00074         
00079         public function obtainSequence($sequence)
00080         {
00081             $res = $this->queryRaw("select nextval('{$sequence}') as seq");
00082             $row = pg_fetch_assoc($res);
00083             pg_free_result($res);
00084             return $row['seq'];
00085         }
00086         
00090         public function setDbEncoding()
00091         {
00092             pg_set_client_encoding($this->link, $this->encoding);
00093             
00094             return $this;
00095         }
00096         
00101         public function queryRaw($queryString)
00102         {
00103             try {
00104                 return pg_query($this->link, $queryString);
00105             } catch (BaseException $e) {
00106                 // manual parsing, since pg_send_query() and
00107                 // pg_get_result() is too slow in our case
00108                 list($error, ) = explode("\n", pg_errormessage($this->link));
00109                 $code = substr($error, 8, 5);
00110                 
00111                 if ($code == PostgresError::UNIQUE_VIOLATION)
00112                     $e = 'DuplicateObjectException';
00113                 else
00114                     $e = 'DatabaseException';
00115                     
00116                 throw new $e($error.' - '.$queryString);
00117             }
00118         }
00119 
00124         public function queryCount(Query $query)
00125         {
00126             return pg_affected_rows($this->queryNull($query));
00127         }
00128         
00129         public function queryRow(Query $query)
00130         {
00131             $res = $this->query($query);
00132             
00133             if ($this->checkSingle($res)) {
00134                 $ret = pg_fetch_assoc($res);
00135                 pg_free_result($res);
00136                 return $ret;
00137             } else
00138                 return null;
00139         }
00140         
00141         public function queryColumn(Query $query)
00142         {
00143             $res = $this->query($query);
00144             
00145             if ($res) {
00146                 $array = array();
00147 
00148                 while ($row = pg_fetch_row($res))
00149                     $array[] = $row[0];
00150 
00151                 pg_free_result($res);
00152                 return $array;
00153             } else
00154                 return null;
00155         }
00156         
00157         public function querySet(Query $query)
00158         {
00159             $res = $this->query($query);
00160             
00161             if ($res) {
00162                 $array = array();
00163 
00164                 while ($row = pg_fetch_assoc($res))
00165                     $array[] = $row;
00166 
00167                 pg_free_result($res);
00168                 return $array;
00169             } else
00170                 return null;
00171         }
00172         
00173         public function hasSequences()
00174         {
00175             return true;
00176         }
00177         
00182         public function getTableInfo($table)
00183         {
00184             static $types = array(
00185                 'time'          => DataType::TIME,
00186                 'date'          => DataType::DATE,
00187                 'timestamp'     => DataType::TIMESTAMP,
00188                 
00189                 'bool'          => DataType::BOOLEAN,
00190                 
00191                 'int2'          => DataType::SMALLINT,
00192                 'int4'          => DataType::INTEGER,
00193                 'int8'          => DataType::BIGINT,
00194                 'numeric'       => DataType::NUMERIC,
00195                 
00196                 'float4'        => DataType::REAL,
00197                 'float8'        => DataType::DOUBLE,
00198                 
00199                 'varchar'       => DataType::VARCHAR,
00200                 'bpchar'        => DataType::CHAR,
00201                 'text'          => DataType::TEXT,
00202                 
00203                 // unhandled types, not ours anyway
00204                 'tsvector'      => null,
00205                 'inet'          => null
00206             );
00207             
00208             try {
00209                 $res = pg_meta_data($this->link, $table);
00210             } catch (BaseException $e) {
00211                 throw new ObjectNotFoundException(
00212                     "unknown table '{$table}'"
00213                 );
00214             }
00215             
00216             $table = new DBTable($table);
00217             
00218             foreach ($res as $name => $info) {
00219                 
00220                 Assert::isTrue(
00221                     array_key_exists($info['type'], $types),
00222                     
00223                     'unknown type "'
00224                     .$types[$info['type']]
00225                     .'" found in column "'.$name.'"'
00226                 );
00227                 
00228                 if (empty($types[$info['type']]))
00229                     continue;
00230                 
00231                 $column =
00232                     new DBColumn(
00233                         DataType::create($types[$info['type']])->
00234                         setNull(!$info['not null']),
00235                         
00236                         $name
00237                     );
00238                 
00239                 $table->addColumn($column);
00240             }
00241             
00242             return $table;
00243         }
00244         
00245         private function checkSingle($result)
00246         {
00247             if (pg_num_rows($result) > 1)
00248                 throw new TooManyRowsException(
00249                     'query returned too many rows (we need only one)'
00250                 );
00251             
00252             return $result;
00253         }
00254     }
00255 ?>

Generated on Sun Dec 9 21:56:23 2007 for onPHP by  doxygen 1.5.4