Xataface 2.0
Xataface Application Framework
Dataface/Table/builder.php
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Enumerations