![]() |
Xataface 2.0
Xataface Application Framework
|
00001 <?php 00002 import('Dataface/Table.php'); 00003 00014 class Dataface_MetadataTool { 00015 00020 var $fieldDefs = null; 00021 00025 var $tablename = null; 00026 00031 var $columns = null; 00032 00037 var $keyColumns = null; 00038 00039 function Dataface_MetadataTool($tablename){ 00040 $this->tablename = $tablename; 00041 } 00042 00049 function isMetadataTable($tablename=null){ 00050 if ( !isset($tablename) ) $tablename = $this->tablename; 00051 return (strstr( $tablename, '__metadata') == '__metadata'); 00052 00053 } 00054 00061 function &getColumns($tablename=null, $usecache=true){ 00062 $app =& Dataface_Application::getInstance(); 00063 if (!isset($tablename) ) $tablename = $this->tablename; 00064 $md_tablename = $tablename.'__metadata'; 00065 if ( !isset($this->columns) || !$usecache ){ 00066 $this->columns = array(); 00067 $sql = "show columns from `".$md_tablename."`"; 00068 $res = mysql_query($sql, $app->db()); 00069 if ( !$res ) trigger_error(mysql_error($app->db()), E_USER_ERROR); 00070 if ( mysql_num_rows($res) == 0) trigger_error("No metadata table '{$md_tablename}' could be found.", E_USER_ERROR); 00071 00072 while ( $row = mysql_fetch_assoc($res) ){ 00073 $this->columns[$row['Field']] = $row; 00074 } 00075 @mysql_free_result($res); 00076 } 00077 return $this->columns; 00078 00079 } 00080 00088 function &getKeyColumns($tablename=null, $usecache=true){ 00089 if (!isset($tablename) ) $tablename = $this->tablename; 00090 $md_tablename = $tablename.'__metadata'; 00091 if ( !isset($this->keyColumns) || !$usecache ){ 00092 $this->keyColumns = array(); 00093 $cols = $this->getColumns($tablename, $usecache); 00094 foreach (array_keys($cols) as $col){ 00095 if ( strcasecmp($this->columns[$col]['Key'], 'PRI') === 0 ){ 00096 $this->keyColumns[$this->columns[$col]['Field']] =& $this->columns[$col]; 00097 } 00098 } 00099 } 00100 00101 return $this->keyColumns; 00102 00103 } 00104 00105 00106 00112 function loadMetadataFieldDefs($tablename=null){ 00113 if ( !isset($tablename) ) $tablename = $this->tablename; 00114 if ( !isset($this->fieldDefs) ){ 00115 00116 00117 import('Dataface/ConfigTool.php'); 00118 $configTool =& Dataface_ConfigTool::getInstance(); 00119 $this->fieldDefs = $configTool->loadConfig('metadata',$tablename); 00120 foreach (array_keys($this->fieldDefs) as $key ){ 00121 $field =& $this->fieldDefs[$key]; 00122 $field['name'] = '__'.$key; 00123 $field['Field'] = $field['name']; 00124 if ( !isset($field['Type']) ) $field['Type'] = 'varchar(64)'; 00125 $this->fieldDefs['__'.$key] =& $field; 00126 unset($this->fieldDefs[$key]); 00127 unset($field); 00128 } 00129 } 00130 00131 return $this->fieldDefs; 00132 00133 } 00134 00135 00143 function createMetadataTable($tablename=null){ 00144 if ( !isset($tablename) ) $tablename = $this->tablename; 00145 if ( Dataface_MetadataTool::isMetadataTable($tablename) ) return false; 00146 $app =& Dataface_Application::getInstance(); 00147 00148 $table =& Dataface_Table::loadTable($tablename); 00149 00150 if ( !Dataface_Table::tableExists($tablename.'__metadata', false) ){ 00151 $sql = "CREATE TABLE `{$tablename}__metadata` ( 00152 "; 00153 foreach ($table->keys() as $field ){ 00154 $type = (strtolower($field['Type']) != 'container' ? $field['Type'] : 'varchar(64)'); 00155 00156 $sql .= "`{$field['name']}` {$type} DEFAULT NULL, 00157 "; 00158 00159 } 00160 $metafields = $this->loadMetadataFieldDefs($tablename); 00161 foreach ($metafields as $fieldname=>$field){ 00162 if ( @$field['Default'] ) $default = " DEFAULT '{$field['Default']}'"; 00163 else $default = ''; 00164 $sql .= "`{$fieldname}` {$field['Type']}{$default},"; 00165 } 00166 00167 $keynames = array_keys($table->keys()); 00168 $sql .= "primary key (`".implode('`,`', $keynames)."`))"; 00169 $res = mysql_query($sql, $app->db()); 00170 if ( !$res ) trigger_error(mysql_error($res), E_USER_ERROR); 00171 return true; 00172 00173 } 00174 00175 return false; 00176 00177 00178 } 00179 00188 function refreshMetadataTable($tablename=null){ 00189 if ( !isset($tablename) ) $tablename = $this->tablename; 00190 if ( Dataface_MetadataTool::isMetadataTable($tablename) ) return false; 00191 $app =& Dataface_Application::getInstance(); 00192 $table =& Dataface_Table::loadTable($tablename); 00193 $md_tablename = $tablename.'__metadata'; 00194 if ( !Dataface_Table::tableExists($md_tablename, false) ){ 00195 if ( $this->createMetadataTable($tablename) ) return true; 00196 } 00197 $cols =& $this->getColumns($tablename, false); 00198 00199 00200 // First we have to go through all of the key fields of the subject table 00201 // and make sure that they appear in the metadata table. 00202 $updatePrimaryKey = false; 00203 foreach ($table->keys() as $field){ 00204 if ( !isset($cols[$field['Field']]) ){ 00205 $updatePrimaryKey=true; 00206 $default = ( @$field['Default'] ? " DEFAULT {$field['Default']}" : ''); 00207 $sql = "alter table `{$md_tablename}` add column `{$field['Field']}` {$field['Type']}{$default}"; 00208 $res = mysql_query($sql, $app->db()); 00209 if ( !$res ) trigger_error(mysql_error($app->db()), E_USER_ERROR); 00210 } 00211 } 00212 00213 $table_keys =& $table->keys(); 00214 00215 //Next we have to go through all of the key fields in the metadata table ane make sure that they 00216 // appear in the subject table primary keys. 00217 foreach ($this->getKeyColumns($tablename, false) as $field){ 00218 if ( !isset($table_keys[$field['Field']]) ){ 00219 $updatePrimaryKey = true; 00220 $sql = "alter table `{$md_tablename}` drop column `{$field['Field']}`"; 00221 $res = mysql_query($sql, $app->db()); 00222 if ( !$res ) trigger_error(mysql_error($app->db()), E_USER_ERROR); 00223 } 00224 } 00225 00226 // If the primary key needed to be updated, we will update it now. 00227 if ( $updatePrimaryKey ){ 00228 // The primary key needs to be updated 00229 $sql = "drop primary key"; 00230 @mysql_query($sql, $app->db()); 00231 $sql = "alter table `{$md_tablename}` add primary key (`".implode('`,`',array_keys($table->keys()))."`)"; 00232 $res = mysql_query($sql, $app->db()); 00233 if ( !$res ) trigger_error(mysql_error($app->db()), E_USER_ERROR); 00234 00235 } 00236 00237 // Now we need to make sure that all of the prescribed meta fields are 00238 // in the metadata field. 00239 00240 $fielddefs = $this->loadMetadataFieldDefs($tablename); 00241 $cols = $this->getColumns($tablename, false); 00242 00243 foreach ($fielddefs as $field){ 00244 if ( !isset($cols[$field['Field']]) ){ 00245 $default = (@$field['Default'] ? " DEFAULT {$field['Default']}": ''); 00246 $sql = "alter table `{$md_tablename}` add column `{$field['Field']}` {$field['Type']}{$default}"; 00247 $res = mysql_query($sql, $app->db()); 00248 if ( !$res ) trigger_error(mysql_error($app->db()), E_USER_ERROR); 00249 } 00250 } 00251 return true; 00252 00253 } 00254 }