00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00107
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
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 ?>