00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 require_once 'creole/metadata/TableInfo.php';
00023
00031 class MySQLTableInfo extends TableInfo {
00032
00034 protected function initColumns()
00035 {
00036 include_once 'creole/metadata/ColumnInfo.php';
00037 include_once 'creole/drivers/mysql/MySQLTypes.php';
00038
00039 if (!@mysql_select_db($this->dbname, $this->conn->getResource())) {
00040 throw new SQLException('No database selected');
00041 }
00042
00043
00044
00045
00046
00047
00048
00049 $res = mysql_query("SHOW COLUMNS FROM `" . $this->name . "`", $this->conn->getResource());
00050
00051 $defaults = array();
00052 $nativeTypes = array();
00053 $precisions = array();
00054
00055 while($row = mysql_fetch_assoc($res)) {
00056 $name = $row['Field'];
00057 $is_nullable = ($row['Null'] == 'YES');
00058 $is_auto_increment = (strpos($row['Extra'], 'auto_increment') !== false);
00059 $size = null;
00060 $precision = null;
00061 $scale = null;
00062
00063 if (preg_match('/^(\w+)[\(]?([\d,]*)[\)]?( |$)/', $row['Type'], $matches)) {
00064
00065 $nativeType = $matches[1];
00066 if ($matches[2]) {
00067 if ( ($cpos = strpos($matches[2], ',')) !== false) {
00068 $size = (int) substr($matches[2], 0, $cpos);
00069 $precision = $size;
00070 $scale = (int) substr($matches[2], $cpos + 1);
00071 } else {
00072 $size = (int) $matches[2];
00073 }
00074 }
00075 } elseif (preg_match('/^(\w+)\(/', $row['Type'], $matches)) {
00076 $nativeType = $matches[1];
00077 } else {
00078 $nativeType = $row['Type'];
00079 }
00080
00081 $default = preg_match('~blob|text~', $nativeType) ? null : $row['Default'];
00082 $this->columns[$name] = new ColumnInfo($this,
00083 $name,
00084 MySQLTypes::getType($nativeType),
00085 $nativeType,
00086 $size,
00087 $precision,
00088 $scale,
00089 $is_nullable,
00090 $default,
00091 $is_auto_increment,
00092 $row);
00093 }
00094
00095 $this->colsLoaded = true;
00096 }
00097
00099 protected function initPrimaryKey()
00100 {
00101 include_once 'creole/metadata/PrimaryKeyInfo.php';
00102
00103
00104 if (!$this->colsLoaded) $this->initColumns();
00105
00106 if (!@mysql_select_db($this->dbname, $this->conn->getResource())) {
00107 throw new SQLException('No database selected');
00108 }
00109
00110
00111 $res = mysql_query("SHOW KEYS FROM `" . $this->name . "`", $this->conn->getResource());
00112
00113
00114
00115
00116 while($row = mysql_fetch_assoc($res)) {
00117
00118 if ($row['Key_name'] !== 'PRIMARY') {
00119 continue;
00120 }
00121 $name = $row["Column_name"];
00122 if (!isset($this->primaryKey)) {
00123 $this->primaryKey = new PrimaryKeyInfo($name, $row);
00124 }
00125 $this->primaryKey->addColumn($this->columns[$name]);
00126 }
00127
00128 $this->pkLoaded = true;
00129 }
00130
00132 protected function initIndexes() {
00133
00134 include_once 'creole/metadata/IndexInfo.php';
00135
00136
00137 if (!$this->colsLoaded) $this->initColumns();
00138
00139 if (!@mysql_select_db($this->dbname, $this->conn->getResource())) {
00140 throw new SQLException('No database selected');
00141 }
00142
00143
00144 $res = mysql_query("SHOW INDEX FROM `" . $this->name . "`", $this->conn->getResource());
00145
00146
00147
00148
00149 while($row = mysql_fetch_assoc($res)) {
00150 $colName = $row["Column_name"];
00151 $name = $row["Key_name"];
00152
00153 if($name == "PRIMARY") {
00154 continue;
00155 }
00156
00157 if (!isset($this->indexes[$name])) {
00158 $isUnique = ($row["Non_unique"] == 0);
00159 $this->indexes[$name] = new IndexInfo($name, $isUnique, $row);
00160 }
00161 $this->indexes[$name]->addColumn($this->columns[$colName]);
00162 }
00163
00164 $this->indexesLoaded = true;
00165 }
00166
00171 protected function initForeignKeys() {
00172
00173
00174 $res = mysql_query("SELECT VERSION()");
00175 $row = mysql_fetch_row($res);
00176
00177
00178
00179 if ($row[0] < '3.23.44') {
00180 $this->fksLoaded = true;
00181 return;
00182 }
00183
00184 include_once 'creole/metadata/ForeignKeyInfo.php';
00185
00186
00187 if (!$this->colsLoaded) $this->initColumns();
00188 if (!@mysql_select_db($this->dbname, $this->conn->getResource())) {
00189 throw new SQLException('No database selected');
00190 }
00191
00192 $res = mysql_query("SHOW CREATE TABLE `" . $this->name . "`", $this->conn->getResource());
00193 $row = mysql_fetch_row($res);
00194
00195
00196 $regEx = '/FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)(.*)/';
00197 if (preg_match_all($regEx,$row[1],$matches)) {
00198 $tmpArray = array_keys($matches[0]);
00199 foreach ($tmpArray as $curKey) {
00200 $name = $matches[1][$curKey];
00201 $ftbl = $matches[2][$curKey];
00202 $fcol = $matches[3][$curKey];
00203 $fkey = $matches[4][$curKey];
00204 if (!isset($this->foreignKeys[$name])) {
00205 $this->foreignKeys[$name] = new ForeignKeyInfo($name);
00206 if ($this->database->hasTable($ftbl)) {
00207 $foreignTable = $this->database->getTable($ftbl);
00208 } else {
00209 $foreignTable = new MySQLTableInfo($this->database, $ftbl);
00210 $this->database->addTable($foreignTable);
00211 }
00212 if ($foreignTable->hasColumn($fcol)) {
00213 $foreignCol = $foreignTable->getColumn($fcol);
00214 } else {
00215 $foreignCol = new ColumnInfo($foreignTable, $fcol);
00216 $foreignTable->addColumn($foreignCol);
00217 }
00218
00219
00220 $fkactions = array(
00221 'ON DELETE' => ForeignKeyInfo::RESTRICT,
00222 'ON UPDATE' => ForeignKeyInfo::RESTRICT,
00223 );
00224
00225 if ($fkey) {
00226
00227 foreach (array_keys($fkactions) as $fkaction) {
00228 $result = NULL;
00229 preg_match('/' . $fkaction . ' (' . ForeignKeyInfo::CASCADE . '|' . ForeignKeyInfo::SETNULL . ')/', $fkey, $result);
00230 if ($result && is_array($result) && isset($result[1])) {
00231 $fkactions[$fkaction] = $result[1];
00232 }
00233 }
00234 }
00235
00236 $this->foreignKeys[$name]->addReference($this->columns[$name], $foreignCol, $fkactions['ON DELETE'], $fkactions['ON UPDATE']);
00237 }
00238 }
00239 }
00240 $this->fksLoaded = true;
00241
00242 }
00243
00244 protected function initVendorSpecificInfo()
00245 {
00246 $res = mysql_query("SHOW TABLE STATUS LIKE '" . $this->name . "'", $this->conn->getResource());
00247 $this->vendorSpecificInfo = mysql_fetch_assoc($res);
00248
00249 $this->vendorLoaded = true;
00250 }
00251
00252 }