![]() |
Xataface 2.0
Xataface Application Framework
|
00001 <?php 00002 import('Dataface/Table.php'); 00003 00030 class Dataface_Table_builder { 00031 00035 var $table; 00036 00040 var $name; 00041 00042 var $fields=array(); 00043 00044 function Dataface_Table_builder($name){ 00045 $app =& Dataface_Application::getInstance(); 00046 $this->name = $name; 00047 if ( mysql_num_rows(mysql_query('show tables like \''.addslashes($name).'\'', $app->db())) > 0 ){ 00048 $this->table =& Dataface_Table::loadTable($name); 00049 } 00050 00051 } 00052 00053 function createPrimaryKey(){ 00054 foreach ($this->fields as $field){ 00055 if ( strtolower($field['Key']) == 'pri' ){ 00056 return; 00057 } 00058 } 00059 $this->fields['id'] = Dataface_Table::_newSchema('int(11)','id',$this->name); 00060 $this->fields['id']['Key'] = 'PRI'; 00061 $this->fields['id']['Extra'] = 'auto_increment'; 00062 00063 00064 } 00065 00069 function &keys(){ 00070 if ( isset( $this->table ) ){ 00071 $keys =& $this->table->keys(); 00072 } else { 00073 $keys = array(); 00074 foreach ( array_keys($this->fields) as $key ){ 00075 if ( strtolower($this->fields[$key]['Key']) == 'pri' ){ 00076 $keys[$key] =& $this->fields[$key]; 00077 } 00078 } 00079 } 00080 return $keys; 00081 } 00082 00086 function save(){ 00087 if ( isset($this->table) ) return $this->update(); 00088 return $this->create(); 00089 } 00090 00091 00099 function create(){ 00100 $app =& Dataface_Application::getInstance(); 00101 $this->createPrimaryKey(); 00102 $sql = 'create table `'.addslashes($this->name).'` ( 00103 '; 00104 foreach ($this->fields as $field){ 00105 $sql .= '`'.addslashes($field['Field']).'` '.addslashes($field['Type']).' '.addslashes($field['Extra']); 00106 //if ( $field['Extra'] ) $sql .= ' '.$field['Extra']; 00107 if ( !$field['Null'] ) $sql .= ' NOT NULL'; 00108 if ( $field['Default'] ) $sql .= ' DEFAULT \''.addslashes($field['Default']).'\''; 00109 $sql .= ', 00110 '; 00111 00112 } 00113 00114 $sql .= ' PRIMARY KEY (`'.implode('`,`',array_keys($this->keys())).'`) 00115 )'; 00116 00117 $res = mysql_query($sql, $app->db()); 00118 if ( !$res ) return PEAR::raiseError(mysql_error($app->db())); 00119 00120 $res = $this->writeConfigFiles(); 00121 if ( PEAR::isError($res) ) return $res; 00122 00123 $this->table =& Dataface_Table::loadTable($this->name); 00124 return true; 00125 00126 } 00127 00132 function update(){ 00133 $app =& Dataface_Application::getInstance(); 00134 $res = mysql_query("show columns from `".str_replace('`','\\`',$this->table->tablename)."`", $app->db()); 00135 $existing_fields = array(); 00136 while ( $row = mysql_fetch_assoc($res) ){ 00137 $existing_fields[$row['Field']] = $row; 00138 } 00139 00140 // add new / modify existing fields 00141 foreach ( $this->table->fields() as $field ){ 00142 if ( !isset($existing_fields[$field['Field']]) ){ 00143 // the field does not exist yet.. let's add it 00144 $res = $this->addFieldToDB($field); 00145 if ( PEAR::isError($res) ) return $res; 00146 } else if ( $this->compareFields($field, $existing_fields[$field['Field']]) !== 0 ){ 00147 $res = $this->alterFieldInDB($field, $existing_fields[$field['Field']]); 00148 if ( PEAR::isError($res) ) return $res; 00149 } 00150 } 00151 00152 // remove fields that are no longer there 00153 $table_fields =& $this->table->fields(); 00154 foreach ( $existing_fields as $field ){ 00155 if ( !isset($table_fields[$field['Field']]) ){ 00156 $res = $this->removeFieldFromDB($field); 00157 if ( PEAR::isError($res) ) return $res; 00158 } 00159 } 00160 00161 // now we can write the config files 00162 $res = $this->writeConfigFiles(); 00163 if ( PEAR::isError($res) ) return $res; 00164 } 00165 00172 function alterFieldInDB($field, $op='modify'){ 00173 $app =& Dataface_Application::getInstance(); 00174 $sql = 'alter table `'.str_replace('`','\\`',$this->table->tablename).'` '; 00175 if ( strtolower($field['Type']) == 'container') { 00176 $type = 'varchar(128)'; 00177 } else { 00178 $type = $field['Type']; 00179 } 00180 $sql .= ' '.$op.' column `'.str_replace('`','\\`',$field['Field']).'` '.$type.' '; 00181 if ( isset($field['Extra']) ) $sql .= ' '.$field['Extra']; 00182 if ( !isset($field['Null']) ) $sql .= ' NOT NULL'; 00183 if ( isset($field['Default']) ) $sql .= ' DEFAULT \''.$field['Default'].'\''; 00184 $res = mysql_query($sql, $app->db()); 00185 if ( !$res ){ 00186 return PEAR::raiseError("Unable to add field '$field[Field]': ".mysql_error($app->db())); 00187 } 00188 return true; 00189 } 00190 00195 function addFieldToDB($field){ 00196 return $this->alterFieldInDB($field, 'add'); 00197 } 00198 00199 00204 function removeFieldFromDB($field){ 00205 $app =& Dataface_Application::getInstance(); 00206 $res = mysql_query("alter table `".str_replace('`','\\`', $this->table->tablename)."` 00207 drop `".str_replace('`','\\`', $field['Field'])."`", $app->db()); 00208 if ( !$res ) return PEAR::raiseError("Failed to remove field '$field[Field]': ".mysql_error($app->db())); 00209 return true; 00210 } 00211 00212 00213 00219 function writeConfigFiles($params=array()){ 00220 if ( isset($params['fields']) ) $fields = $params['fields']; 00221 else if ( isset($this->table) ) $fields = $this->table->fields(); 00222 else $fields = $this->fields; 00223 00224 $path = DATAFACE_SITE_PATH.'/tables/'.$this->name; 00225 if ( !file_exists($path) ) mkdir($path,0777, true); 00226 $fieldsinipath = $path.'/fields.ini'; 00227 $fh = fopen($fieldsinipath,'w'); 00228 if ( !$fh ){ 00229 return PEAR::raiseError("Failed to open file '$fieldsinipath'"); 00230 } 00231 if ( flock($fh, LOCK_EX) ){ 00232 foreach ( $fields as $field ){ 00233 $flatfield = array(); 00234 $this->flattenConfigArray($field, $flatfield); 00235 fwrite($fh, '['.$field['name']."]\n"); 00236 foreach ( $flatfield as $key=>$value ){ 00237 if ( $key == 'name' ) continue; 00238 fwrite($fh, $key .'= "'.str_replace('"','\\"', $value).'"'."\n"); 00239 } 00240 fwrite($fh, "\n"); 00241 } 00242 flock($fh, LOCK_UN); 00243 } else { 00244 return PEAR::raiseError("Failed to lock file for writing: $fieldsinipath"); 00245 } 00246 00247 } 00248 00258 function flattenConfigArray($field, &$arr, $prefix=''){ 00259 00260 foreach ( $field as $key=>$value ){ 00261 $full_key = ( empty($prefix) ? $key : $prefix.':'.$key); 00262 if ( is_array($value) ){ 00263 $this->flattenConfigArray($value, $arr, $full_key); 00264 } else { 00265 $arr[$full_key] = $value; 00266 } 00267 } 00268 } 00269 00276 function compareFields($field1, $field2){ 00277 $indicators = array('Field','Type','Null','Default','Extra'); 00278 foreach ($indicators as $indicator){ 00279 if ( @$field1[$indicator] != @$field2[$indicator] ) return 1; 00280 00281 } 00282 return 0; 00283 } 00284 00288 function &fields(){ 00289 if ( isset($this->table) ) $fields =& $this->table->fields(); 00290 else $fields =& $this->fields; 00291 return $fields; 00292 } 00293 00305 function &addField($field){ 00306 if ( !isset($field['Field']) and !isset($field['name']) ){ 00307 $err = PEAR::raiseError("Attempt to add field that has no name."); 00308 return $err; 00309 } 00310 00311 if ( !isset($field['Field']) ) $field['Field'] = $field['name']; 00312 if ( !isset($field['name']) ) $field['name'] = $field['Field']; 00313 00314 $schema = Dataface_Table::_newSchema($field['Type'],$field['name'], $this->name); 00315 00316 00317 00318 $fields =& $this->fields(); 00319 $fields[$field['name']] =& $schema; 00320 00321 $conf = array(); 00322 $this->flattenConfigArray($field,$conf); 00323 foreach ( array_keys($conf) as $key){ 00324 $this->setParameter($field['name'], $key, $conf[$key]); 00325 } 00326 return $conf; 00327 } 00328 00329 function removeField($name){ 00330 $fields =& $this->fields(); 00331 00332 unset($fields[$name]); 00333 return true; 00334 } 00335 00336 00337 function &getField($name){ 00338 $fields =& $this->fields(); 00339 return $fields[$name]; 00340 } 00341 00342 function getParameter($fieldname, $paramname){ 00343 $fields =& $this->fields(); 00344 $field =& $fields[$fieldname]; 00345 $param =& $field; 00346 $path = explode(':', $paramname); 00347 foreach ( $path as $key ){ 00348 if ( !isset($param[$key]) ) return null; 00349 $temp =& $param[$key]; 00350 unset($param); 00351 $param =& $temp; 00352 unset($temp); 00353 } 00354 return $param; 00355 00356 } 00357 00358 function setParameter($fieldname, $paramname, $paramvalue){ 00359 $fields =& $this->fields(); 00360 $field =& $fields[$fieldname]; 00361 $param =& $field; 00362 $path = explode(':', $paramname); 00363 $last = end($path); 00364 reset($path); 00365 foreach ( $path as $key ){ 00366 if ( !isset($param[$key]) && $key != $last) $param[$key] = array(); 00367 if ( $key == $last ) { 00368 $param[$key] = $paramvalue; 00369 return true; 00370 } 00371 $temp =& $param[$key]; 00372 unset($param); 00373 $param =& $temp; 00374 unset($temp); 00375 } 00376 00377 trigger_error("Something went wrong settingn parameter $paramname to value $paramvalue on line ".__LINE__." of file ".__FILE__, E_USER_ERROR); 00378 00379 } 00380 00381 00382 00383 00384 00385 00386 00387 }