Public Member Functions | |
__construct (DatabaseInfo $database, $name, $version, $intOID) | |
Protected Member Functions | |
initColumns () | |
Load the columns for this table. | |
initForeignKeys () | |
Load foreign keys for this table. | |
initIndexes () | |
Load indexes for this table. | |
initPrimaryKey () | |
Loads the primary keys for this table. | |
Private Member Functions | |
processLengthScale ($intTypmod, $strName) | |
processDomain ($strDomain) | |
Private Attributes | |
$version | |
$oid |
Definition at line 40 of file PgSQLTableInfo.php.
PgSQLTableInfo::__construct | ( | DatabaseInfo $ | database, | |
$ | name, | |||
$ | version, | |||
$ | intOID | |||
) |
string | $table The table name. | |
string | $database The database name. | |
resource | $dblink The db connection resource. |
Definition at line 59 of file PgSQLTableInfo.php.
References TableInfo::$name, and $version.
00059 { 00060 parent::__construct ($database, $name); 00061 $this->version = $version; 00062 $this->oid = $intOID; 00063 } // function __construct(DatabaseInfo $database, $name) {
PgSQLTableInfo::initColumns | ( | ) | [protected] |
Load the columns for this table.
Reimplemented from TableInfo.
Definition at line 66 of file PgSQLTableInfo.php.
References TableInfo::$name, $result, PgSQLTypes::getType(), processDomain(), and processLengthScale().
Referenced by initIndexes(), and initPrimaryKey().
00066 { 00067 // Include dependencies 00068 include_once ('creole/metadata/ColumnInfo.php'); 00069 include_once ('creole/drivers/pgsql/PgSQLTypes.php'); 00070 00071 // Get the columns, types, etc. 00072 // Based on code from pgAdmin3 (http://www.pgadmin.org/) 00073 $result = pg_query ($this->conn->getResource(), sprintf ("SELECT 00074 att.attname, 00075 att.atttypmod, 00076 att.atthasdef, 00077 att.attnotnull, 00078 def.adsrc, 00079 CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray, 00080 CASE 00081 WHEN ty.typname = 'bpchar' 00082 THEN 'char' 00083 WHEN ty.typname = '_bpchar' 00084 THEN '_char' 00085 ELSE 00086 ty.typname 00087 END AS typname, 00088 ty.typtype 00089 FROM pg_attribute att 00090 JOIN pg_type ty ON ty.oid=att.atttypid 00091 LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum 00092 WHERE att.attrelid = %d AND att.attnum > 0 00093 AND att.attisdropped IS FALSE 00094 ORDER BY att.attnum", $this->oid)); 00095 00096 if (!$result) { 00097 throw new SQLException("Could not list fields for table: " . $this->name, pg_last_error($this->conn->getResource())); 00098 } 00099 while($row = pg_fetch_assoc($result)) { 00100 00101 $size = null; 00102 $precision = null; 00103 $scale = null; 00104 00105 // Check to ensure that this column isn't an array data type 00106 if (((int) $row['isarray']) === 1) 00107 { 00108 throw new SQLException (sprintf ("Array datatypes are not currently supported [%s.%s]", $this->name, $row['attname'])); 00109 } // if (((int) $row['isarray']) === 1) 00110 $name = $row['attname']; 00111 // If they type is a domain, Process it 00112 if (strtolower ($row['typtype']) == 'd') 00113 { 00114 $arrDomain = $this->processDomain ($row['typname']); 00115 $type = $arrDomain['type']; 00116 $size = $arrDomain['length']; 00117 $precision = $size; 00118 $scale = $arrDomain['scale']; 00119 $boolHasDefault = (strlen (trim ($row['atthasdef'])) > 0) ? $row['atthasdef'] : $arrDomain['hasdefault']; 00120 $default = (strlen (trim ($row['adsrc'])) > 0) ? $row['adsrc'] : $arrDomain['default']; 00121 $is_nullable = (strlen (trim ($row['attnotnull'])) > 0) ? $row['attnotnull'] : $arrDomain['notnull']; 00122 $is_nullable = (($is_nullable == 't') ? false : true); 00123 } // if (strtolower ($row['typtype']) == 'd') 00124 else 00125 { 00126 $type = $row['typname']; 00127 $arrLengthPrecision = $this->processLengthScale ($row['atttypmod'], $type); 00128 $size = $arrLengthPrecision['length']; 00129 $precision = $size; 00130 $scale = $arrLengthPrecision['scale']; 00131 $boolHasDefault = $row['atthasdef']; 00132 $default = $row['adsrc']; 00133 $is_nullable = (($row['attnotnull'] == 't') ? false : true); 00134 } // else (strtolower ($row['typtype']) == 'd') 00135 00136 $autoincrement = null; 00137 00138 // if column has a default 00139 if (($boolHasDefault == 't') && (strlen (trim ($default)) > 0)) 00140 { 00141 if (!preg_match('/^nextval\(/', $default)) 00142 { 00143 $strDefault= preg_replace ('/::[\W\D]*/', '', $default); 00144 $default = str_replace ("'", '', $strDefault); 00145 } // if (!preg_match('/^nextval\(/', $row['atthasdef'])) 00146 else 00147 { 00148 $autoincrement = true; 00149 $default = null; 00150 } // else 00151 } // if (($boolHasDefault == 't') && (strlen (trim ($default)) > 0)) 00152 else 00153 { 00154 $default = null; 00155 } // else (($boolHasDefault == 't') && (strlen (trim ($default)) > 0)) 00156 00157 $this->columns[$name] = new ColumnInfo($this, $name, PgSQLTypes::getType($type), $type, $size, $precision, $scale, $is_nullable, $default, $autoincrement); 00158 } 00159 00160 $this->colsLoaded = true; 00161 } // protected function initColumns ()
PgSQLTableInfo::initForeignKeys | ( | ) | [protected] |
Load foreign keys for this table.
Reimplemented from TableInfo.
Definition at line 243 of file PgSQLTableInfo.php.
References TableInfo::$name, $result, ForeignKeyInfo::CASCADE, ForeignKeyInfo::NONE, ForeignKeyInfo::RESTRICT, ForeignKeyInfo::SETDEFAULT, and ForeignKeyInfo::SETNULL.
00244 { 00245 include_once 'creole/metadata/ForeignKeyInfo.php'; 00246 00247 $result = pg_query ($this->conn->getResource(), sprintf ("SELECT 00248 conname, 00249 confupdtype, 00250 confdeltype, 00251 cl.relname as fktab, 00252 a2.attname as fkcol, 00253 cr.relname as reftab, 00254 a1.attname as refcol 00255 FROM pg_constraint ct 00256 JOIN pg_class cl ON cl.oid=conrelid 00257 JOIN pg_class cr ON cr.oid=confrelid 00258 LEFT JOIN pg_catalog.pg_attribute a1 ON a1.attrelid = ct.confrelid 00259 LEFT JOIN pg_catalog.pg_attribute a2 ON a2.attrelid = ct.conrelid 00260 WHERE 00261 contype='f' 00262 AND conrelid = %d 00263 AND a2.attnum = ct.conkey[1] 00264 AND a1.attnum = ct.confkey[1] 00265 ORDER BY conname", $this->oid)); 00266 if (!$result) { 00267 throw new SQLException("Could not list foreign keys for table: " . $this->name, pg_last_error($this->conn->getResource())); 00268 } 00269 00270 while($row = pg_fetch_assoc($result)) { 00271 $name = $row['conname']; 00272 $local_table = $row['fktab']; 00273 $local_column = $row['fkcol']; 00274 $foreign_table = $row['reftab']; 00275 $foreign_column = $row['refcol']; 00276 00277 // On Update 00278 switch ($row['confupdtype']) { 00279 case 'c': 00280 $onupdate = ForeignKeyInfo::CASCADE; break; 00281 case 'd': 00282 $onupdate = ForeignKeyInfo::SETDEFAULT; break; 00283 case 'n': 00284 $onupdate = ForeignKeyInfo::SETNULL; break; 00285 case 'r': 00286 $onupdate = ForeignKeyInfo::RESTRICT; break; 00287 default: 00288 case 'a': 00289 //NOACTION is the postgresql default 00290 $onupdate = ForeignKeyInfo::NONE; break; 00291 } 00292 // On Delete 00293 switch ($row['confdeltype']) { 00294 case 'c': 00295 $ondelete = ForeignKeyInfo::CASCADE; break; 00296 case 'd': 00297 $ondelete = ForeignKeyInfo::SETDEFAULT; break; 00298 case 'n': 00299 $ondelete = ForeignKeyInfo::SETNULL; break; 00300 case 'r': 00301 $ondelete = ForeignKeyInfo::RESTRICT; break; 00302 default: 00303 case 'a': 00304 //NOACTION is the postgresql default 00305 $ondelete = ForeignKeyInfo::NONE; break; 00306 } 00307 00308 00309 $foreignTable = $this->database->getTable($foreign_table); 00310 $foreignColumn = $foreignTable->getColumn($foreign_column); 00311 00312 $localTable = $this->database->getTable($local_table); 00313 $localColumn = $localTable->getColumn($local_column); 00314 00315 if (!isset($this->foreignKeys[$name])) { 00316 $this->foreignKeys[$name] = new ForeignKeyInfo($name); 00317 } 00318 $this->foreignKeys[$name]->addReference($localColumn, $foreignColumn, $ondelete, $onupdate); 00319 } 00320 00321 $this->fksLoaded = true; 00322 }
PgSQLTableInfo::initIndexes | ( | ) | [protected] |
Load indexes for this table.
Reimplemented from TableInfo.
Definition at line 325 of file PgSQLTableInfo.php.
References TableInfo::$name, $result, TableInfo::indexesLoaded(), and initColumns().
00326 { 00327 include_once 'creole/metadata/IndexInfo.php'; 00328 00329 // columns have to be loaded first 00330 if (!$this->colsLoaded) $this->initColumns(); 00331 00332 $result = pg_query ($this->conn->getResource(), sprintf ("SELECT 00333 DISTINCT ON(cls.relname) 00334 cls.relname as idxname, 00335 indkey, 00336 indisunique 00337 FROM pg_index idx 00338 JOIN pg_class cls ON cls.oid=indexrelid 00339 WHERE indrelid = %d AND NOT indisprimary 00340 ORDER BY cls.relname", $this->oid)); 00341 00342 00343 if (!$result) { 00344 throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource())); 00345 } 00346 00347 while($row = pg_fetch_assoc($result)) { 00348 $name = $row["idxname"]; 00349 $unique = ($row["indisunique"] == 't') ? true : false; 00350 if (!isset($this->indexes[$name])) { 00351 $this->indexes[$name] = new IndexInfo($name, $unique); 00352 } 00353 $arrColumns = explode (' ', $row['indkey']); 00354 foreach ($arrColumns as $intColNum) 00355 { 00356 $result2 = pg_query ($this->conn->getResource(), sprintf ("SELECT a.attname 00357 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid 00358 WHERE c.oid = '%s' AND a.attnum = %d AND NOT a.attisdropped 00359 ORDER BY a.attnum", $this->oid, $intColNum)); 00360 if (!$result2) 00361 { 00362 throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource())); 00363 } 00364 $row2 = pg_fetch_assoc($result2); 00365 $this->indexes[$name]->addColumn($this->columns[ $row2['attname'] ]); 00366 } // foreach ($arrColumns as $intColNum) 00367 } 00368 00369 $this->indexesLoaded = true; 00370 }
PgSQLTableInfo::initPrimaryKey | ( | ) | [protected] |
Loads the primary keys for this table.
Reimplemented from TableInfo.
Definition at line 373 of file PgSQLTableInfo.php.
References $result, and initColumns().
00373 { 00374 00375 include_once 'creole/metadata/PrimaryKeyInfo.php'; 00376 00377 00378 // columns have to be loaded first 00379 if (!$this->colsLoaded) $this->initColumns(); 00380 00381 // Primary Keys 00382 00383 $result = pg_query($this->conn->getResource(), sprintf ("SELECT 00384 DISTINCT ON(cls.relname) 00385 cls.relname as idxname, 00386 indkey, 00387 indisunique 00388 FROM pg_index idx 00389 JOIN pg_class cls ON cls.oid=indexrelid 00390 WHERE indrelid = %s AND indisprimary 00391 ORDER BY cls.relname", $this->oid)); 00392 if (!$result) { 00393 throw new SQLException("Could not list primary keys for table: " . $this->name, pg_last_error($this->conn->getResource())); 00394 } 00395 00396 // Loop through the returned results, grouping the same key_name together 00397 // adding each column for that key. 00398 00399 while($row = pg_fetch_assoc($result)) { 00400 $arrColumns = explode (' ', $row['indkey']); 00401 foreach ($arrColumns as $intColNum) 00402 { 00403 $result2 = pg_query ($this->conn->getResource(), sprintf ("SELECT a.attname 00404 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid 00405 WHERE c.oid = '%s' AND a.attnum = %d AND NOT a.attisdropped 00406 ORDER BY a.attnum", $this->oid, $intColNum)); 00407 if (!$result2) 00408 { 00409 throw new SQLException("Could not list indexes keys for table: " . $this->name, pg_last_error($this->conn->getResource())); 00410 } 00411 $row2 = pg_fetch_assoc($result2); 00412 if (!isset($this->primaryKey)) { 00413 $this->primaryKey = new PrimaryKeyInfo($row2['attname']); 00414 } 00415 $this->primaryKey->addColumn($this->columns[ $row2['attname'] ]); 00416 } // foreach ($arrColumns as $intColNum) 00417 } 00418 $this->pkLoaded = true; 00419 }
PgSQLTableInfo::processDomain | ( | $ | strDomain | ) | [private] |
Definition at line 200 of file PgSQLTableInfo.php.
References $result, and processLengthScale().
Referenced by initColumns().
00201 { 00202 if (strlen (trim ($strDomain)) < 1) 00203 { 00204 throw new SQLException ("Invalid domain name [" . $strDomain . "]"); 00205 } // if (strlen (trim ($strDomain)) < 1) 00206 $result = pg_query ($this->conn->getResource(), sprintf ("SELECT 00207 d.typname as domname, 00208 b.typname as basetype, 00209 d.typlen, 00210 d.typtypmod, 00211 d.typnotnull, 00212 d.typdefault 00213 FROM pg_type d 00214 INNER JOIN pg_type b ON b.oid = CASE WHEN d.typndims > 0 then d.typelem ELSE d.typbasetype END 00215 WHERE 00216 d.typtype = 'd' 00217 AND d.typname = '%s' 00218 ORDER BY d.typname", $strDomain)); 00219 00220 if (!$result) { 00221 throw new SQLException("Query for domain [" . $strDomain . "] failed.", pg_last_error($this->conn->getResource())); 00222 } 00223 00224 $row = pg_fetch_assoc ($result); 00225 if (!$row) 00226 { 00227 throw new SQLException ("Domain [" . $strDomain . "] not found."); 00228 } // if (!$row) 00229 $arrDomain = array (); 00230 $arrDomain['type'] = $row['basetype']; 00231 $arrLengthPrecision = $this->processLengthScale ($row['typtypmod'], $row['basetype']); 00232 $arrDomain['length'] = $arrLengthPrecision['length']; 00233 $arrDomain['scale'] = $arrLengthPrecision['scale']; 00234 $arrDomain['notnull'] = $row['typnotnull']; 00235 $arrDomain['default'] = $row['typdefault']; 00236 $arrDomain['hasdefault'] = (strlen (trim ($row['typdefault'])) > 0) ? 't' : 'f'; 00237 00238 pg_free_result ($result); 00239 return $arrDomain; 00240 } // private function processDomain ($strDomain)
PgSQLTableInfo::processLengthScale | ( | $ | intTypmod, | |
$ | strName | |||
) | [private] |
Definition at line 163 of file PgSQLTableInfo.php.
References PgSQLTypes::getNativeType(), CreoleTypes::NUMERIC, CreoleTypes::TIME, and CreoleTypes::TIMESTAMP.
Referenced by initColumns(), and processDomain().
00164 { 00165 // Define the return array 00166 $arrRetVal = array ('length'=>null, 'scale'=>null); 00167 00168 // Some datatypes don't have a Typmod 00169 if ($intTypmod == -1) 00170 { 00171 return $arrRetVal; 00172 } // if ($intTypmod == -1) 00173 00174 // Numeric Datatype? 00175 if ($strName == PgSQLTypes::getNativeType (CreoleTypes::NUMERIC)) 00176 { 00177 $intLen = ($intTypmod - 4) >> 16; 00178 $intPrec = ($intTypmod - 4) & 0xffff; 00179 $intLen = sprintf ("%ld", $intLen); 00180 if ($intPrec) 00181 { 00182 $intPrec = sprintf ("%ld", $intPrec); 00183 } // if ($intPrec) 00184 $arrRetVal['length'] = $intLen; 00185 $arrRetVal['scale'] = $intPrec; 00186 } // if ($strName == PgSQLTypes::getNativeType (CreoleTypes::NUMERIC)) 00187 elseif ($strName == PgSQLTypes::getNativeType (CreoleTypes::TIME) || $strName == 'timetz' 00188 || $strName == PgSQLTypes::getNativeType (CreoleTypes::TIMESTAMP) || $strName == 'timestamptz' 00189 || $strName == 'interval' || $strName == 'bit') 00190 { 00191 $arrRetVal['length'] = sprintf ("%ld", $intTypmod); 00192 } // elseif (TIME, TIMESTAMP, INTERVAL, BIT) 00193 else 00194 { 00195 $arrRetVal['length'] = sprintf ("%ld", ($intTypmod - 4)); 00196 } // else 00197 return $arrRetVal; 00198 } // private function processLengthScale ($intTypmod, $strName)
PgSQLTableInfo::$oid [private] |
Definition at line 52 of file PgSQLTableInfo.php.
PgSQLTableInfo::$version [private] |