Xataface  2.0alpha2
Xataface Application Framework
 All Data Structures Namespaces Files Functions Variables Groups Pages
builder.php
Go to the documentation of this file.
1 <?php
2 import('Dataface/Table.php');
3 
31 
35  var $table;
36 
40  var $name;
41 
42  var $fields=array();
43 
46  $this->name = $name;
47  if ( mysql_num_rows(mysql_query('show tables like \''.addslashes($name).'\'', $app->db())) > 0 ){
48  $this->table =& Dataface_Table::loadTable($name);
49  }
50 
51  }
52 
53  function createPrimaryKey(){
54  foreach ($this->fields as $field){
55  if ( strtolower($field['Key']) == 'pri' ){
56  return;
57  }
58  }
59  $this->fields['id'] = Dataface_Table::_newSchema('int(11)','id',$this->name);
60  $this->fields['id']['Key'] = 'PRI';
61  $this->fields['id']['Extra'] = 'auto_increment';
62 
63 
64  }
65 
69  function &keys(){
70  if ( isset( $this->table ) ){
71  $keys =& $this->table->keys();
72  } else {
73  $keys = array();
74  foreach ( array_keys($this->fields) as $key ){
75  if ( strtolower($this->fields[$key]['Key']) == 'pri' ){
76  $keys[$key] =& $this->fields[$key];
77  }
78  }
79  }
80  return $keys;
81  }
82 
86  function save(){
87  if ( isset($this->table) ) return $this->update();
88  return $this->create();
89  }
90 
91 
99  function create(){
101  $this->createPrimaryKey();
102  $sql = 'create table `'.addslashes($this->name).'` (
103  ';
104  foreach ($this->fields as $field){
105  $sql .= '`'.addslashes($field['Field']).'` '.addslashes($field['Type']).' '.addslashes($field['Extra']);
106  //if ( $field['Extra'] ) $sql .= ' '.$field['Extra'];
107  if ( !$field['Null'] ) $sql .= ' NOT NULL';
108  if ( $field['Default'] ) $sql .= ' DEFAULT \''.addslashes($field['Default']).'\'';
109  $sql .= ',
110  ';
111 
112  }
113 
114  $sql .= ' PRIMARY KEY (`'.implode('`,`',array_keys($this->keys())).'`)
115  )';
116 
117  $res = mysql_query($sql, $app->db());
118  if ( !$res ) return PEAR::raiseError(mysql_error($app->db()));
119 
120  $res = $this->writeConfigFiles();
121  if ( PEAR::isError($res) ) return $res;
122 
123  $this->table =& Dataface_Table::loadTable($this->name);
124  return true;
125 
126  }
127 
132  function update(){
134  $res = mysql_query("show columns from `".str_replace('`','\\`',$this->table->tablename)."`", $app->db());
135  $existing_fields = array();
136  while ( $row = mysql_fetch_assoc($res) ){
137  $existing_fields[$row['Field']] = $row;
138  }
139 
140  // add new / modify existing fields
141  foreach ( $this->table->fields() as $field ){
142  if ( !isset($existing_fields[$field['Field']]) ){
143  // the field does not exist yet.. let's add it
144  $res = $this->addFieldToDB($field);
145  if ( PEAR::isError($res) ) return $res;
146  } else if ( $this->compareFields($field, $existing_fields[$field['Field']]) !== 0 ){
147  $res = $this->alterFieldInDB($field, $existing_fields[$field['Field']]);
148  if ( PEAR::isError($res) ) return $res;
149  }
150  }
151 
152  // remove fields that are no longer there
153  $table_fields =& $this->table->fields();
154  foreach ( $existing_fields as $field ){
155  if ( !isset($table_fields[$field['Field']]) ){
156  $res = $this->removeFieldFromDB($field);
157  if ( PEAR::isError($res) ) return $res;
158  }
159  }
160 
161  // now we can write the config files
162  $res = $this->writeConfigFiles();
163  if ( PEAR::isError($res) ) return $res;
164  }
165 
172  function alterFieldInDB($field, $op='modify'){
174  $sql = 'alter table `'.str_replace('`','\\`',$this->table->tablename).'` ';
175  if ( strtolower($field['Type']) == 'container') {
176  $type = 'varchar(128)';
177  } else {
178  $type = $field['Type'];
179  }
180  $sql .= ' '.$op.' column `'.str_replace('`','\\`',$field['Field']).'` '.$type.' ';
181  if ( isset($field['Extra']) ) $sql .= ' '.$field['Extra'];
182  if ( !isset($field['Null']) ) $sql .= ' NOT NULL';
183  if ( isset($field['Default']) ) $sql .= ' DEFAULT \''.$field['Default'].'\'';
184  $res = mysql_query($sql, $app->db());
185  if ( !$res ){
186  return PEAR::raiseError("Unable to add field '$field[Field]': ".mysql_error($app->db()));
187  }
188  return true;
189  }
190 
195  function addFieldToDB($field){
196  return $this->alterFieldInDB($field, 'add');
197  }
198 
199 
206  $res = mysql_query("alter table `".str_replace('`','\\`', $this->table->tablename)."`
207  drop `".str_replace('`','\\`', $field['Field'])."`", $app->db());
208  if ( !$res ) return PEAR::raiseError("Failed to remove field '$field[Field]': ".mysql_error($app->db()));
209  return true;
210  }
211 
212 
213 
219  function writeConfigFiles($params=array()){
220  if ( isset($params['fields']) ) $fields = $params['fields'];
221  else if ( isset($this->table) ) $fields = $this->table->fields();
222  else $fields = $this->fields;
223 
224  $path = DATAFACE_SITE_PATH.'/tables/'.$this->name;
225  if ( !file_exists($path) ) mkdir($path,0777, true);
226  $fieldsinipath = $path.'/fields.ini';
227  $fh = fopen($fieldsinipath,'w');
228  if ( !$fh ){
229  return PEAR::raiseError("Failed to open file '$fieldsinipath'");
230  }
231  if ( flock($fh, LOCK_EX) ){
232  foreach ( $fields as $field ){
233  $flatfield = array();
234  $this->flattenConfigArray($field, $flatfield);
235  fwrite($fh, '['.$field['name']."]\n");
236  foreach ( $flatfield as $key=>$value ){
237  if ( $key == 'name' ) continue;
238  fwrite($fh, $key .'= "'.str_replace('"','\\"', $value).'"'."\n");
239  }
240  fwrite($fh, "\n");
241  }
242  flock($fh, LOCK_UN);
243  } else {
244  return PEAR::raiseError("Failed to lock file for writing: $fieldsinipath");
245  }
246 
247  }
248 
258  function flattenConfigArray($field, &$arr, $prefix=''){
259 
260  foreach ( $field as $key=>$value ){
261  $full_key = ( empty($prefix) ? $key : $prefix.':'.$key);
262  if ( is_array($value) ){
263  $this->flattenConfigArray($value, $arr, $full_key);
264  } else {
265  $arr[$full_key] = $value;
266  }
267  }
268  }
269 
276  function compareFields($field1, $field2){
277  $indicators = array('Field','Type','Null','Default','Extra');
278  foreach ($indicators as $indicator){
279  if ( @$field1[$indicator] != @$field2[$indicator] ) return 1;
280 
281  }
282  return 0;
283  }
284 
288  function &fields(){
289  if ( isset($this->table) ) $fields =& $this->table->fields();
290  else $fields =& $this->fields;
291  return $fields;
292  }
293 
305  function &addField($field){
306  if ( !isset($field['Field']) and !isset($field['name']) ){
307  $err = PEAR::raiseError("Attempt to add field that has no name.");
308  return $err;
309  }
310 
311  if ( !isset($field['Field']) ) $field['Field'] = $field['name'];
312  if ( !isset($field['name']) ) $field['name'] = $field['Field'];
313 
314  $schema = Dataface_Table::_newSchema($field['Type'],$field['name'], $this->name);
315 
316 
317 
318  $fields =& $this->fields();
319  $fields[$field['name']] =& $schema;
320 
321  $conf = array();
322  $this->flattenConfigArray($field,$conf);
323  foreach ( array_keys($conf) as $key){
324  $this->setParameter($field['name'], $key, $conf[$key]);
325  }
326  return $conf;
327  }
328 
329  function removeField($name){
330  $fields =& $this->fields();
331 
332  unset($fields[$name]);
333  return true;
334  }
335 
336 
337  function &getField($name){
338  $fields =& $this->fields();
339  return $fields[$name];
340  }
341 
342  function getParameter($fieldname, $paramname){
343  $fields =& $this->fields();
345  $param =& $field;
346  $path = explode(':', $paramname);
347  foreach ( $path as $key ){
348  if ( !isset($param[$key]) ) return null;
349  $temp =& $param[$key];
350  unset($param);
351  $param =& $temp;
352  unset($temp);
353  }
354  return $param;
355 
356  }
357 
358  function setParameter($fieldname, $paramname, $paramvalue){
359  $fields =& $this->fields();
361  $param =& $field;
362  $path = explode(':', $paramname);
363  $last = end($path);
364  reset($path);
365  foreach ( $path as $key ){
366  if ( !isset($param[$key]) && $key != $last) $param[$key] = array();
367  if ( $key == $last ) {
368  $param[$key] = $paramvalue;
369  return true;
370  }
371  $temp =& $param[$key];
372  unset($param);
373  $param =& $temp;
374  unset($temp);
375  }
376 
377  trigger_error("Something went wrong settingn parameter $paramname to value $paramvalue on line ".__LINE__." of file ".__FILE__, E_USER_ERROR);
378 
379  }
380 
381 
382 
383 
384 
385 
386 
387 }