e174556df33c5000ca1a712d8cb952c6ea36bb39
[project/data.git] / data_ui / data_ui.admin.inc
1 <?php
2 // $Id$
3 /**
4 * @file
5 * Admin UI functions.
6 */
7
8 /**
9 * Overview over all tables.
10 */
11 function data_ui_overview() {
12 $tables = data_get_all_tables();
13 $rows = array();
14 foreach ($tables as $table) {
15 // Build operations depending on configuration status.
16 $operations = array();
17 if ($table->get('export_type') == EXPORT_IN_CODE) {
18 $status = t('Default');
19 $operations[] = l(t('Override'), 'admin/content/data/edit/'. $table->get('name'));
20 }
21 else if ($table->get('export_type') == (EXPORT_IN_CODE | EXPORT_IN_DATABASE)) {
22 $status = t('Overridden');
23 $operations[] = l(t('Edit'), 'admin/content/data/edit/'. $table->get('name'));
24 $operations[] = l(t('Revert'), 'admin/content/data/revert/'. $table->get('name'));
25 }
26 else {
27 $status = t('Normal');
28 $operations[] = l(t('Edit'), 'admin/content/data/edit/'. $table->get('name'));
29 $operations[] = l(t('Drop'), 'admin/content/data/drop/'. $table->get('name'));
30 }
31 if (module_exists('ctools')) {
32 $operations[] = l(t('Export'), 'admin/content/data/export/'. $table->get('name'));
33 }
34
35 $row = array();
36 $row[] = $table->get('name');
37 $row[] = $status;
38 $row[] = implode(' | ', $operations);
39
40 $rows[] = $row;
41 }
42 $rows[] = array(
43 l(t('Create new table'), 'admin/content/data/create'),
44 '&nbsp;',
45 '&nbsp;',
46 );
47 $header = array(t('Name'), t('Status'), t('Operations'));
48 return theme('table', $header, $rows);
49 }
50
51 /**
52 * Comparison page.
53 */
54 function data_ui_compare() {
55 $rows = array();
56 $tables = data_get_all_tables();
57 foreach ($tables as $table) {
58 $row = array();
59 $comp = $table->compareSchema();
60 $row[] = $table->get('name');
61 $status = $comp['status'];
62 if ($status != 'same') {
63 $status .= ' - '. l(t('adjust'), 'admin/content/data/compare/'. $table->get('name'));
64 }
65 $row[] = $status;
66 $row[] = empty($comp['warning']) ? '-' : $comp['warning'];
67 $rows[] = $row;
68 }
69 $header = array(t('Name'), t('Status'), t('Warnings'));
70 return theme('table', $header, $rows);
71 }
72
73 /**
74 * Adjust table schema form: Present the user with the difference between schema information and
75 * the actual schema in the Database and offer three options:
76 *
77 * - Adjust schema info,
78 * - adjust database or
79 * - leave it.
80 */
81 function data_ui_adjust_form(&$form_state, $table) {
82 drupal_set_title(t('Adjust !table', array('!table' => $table->get('name'))));
83 $comparison = $table->compareSchema();
84
85 $form = array();
86 $form['#redirect'] = 'admin/content/data/compare';
87 $form['#table'] = $table;
88 $form['#comparison'] = $comparison;
89 $form['comparison'] = array(
90 '#type' => 'fieldset',
91 '#title' => t('Comparison'),
92 );
93 $form['comparison']['comparison']['#value'] = theme('data_ui_schema_compare_table', $comparison);
94
95 if ($comparison['status'] == 'different') {
96 $form['update_schema'] = array(
97 '#type' => 'fieldset',
98 '#title' => t('Option 1: Update schema information'),
99 );
100 $form['update_schema']['description'] = array(
101 '#value' => t('<p>This option will update the schema information about this table.</p>'),
102 );
103 $form['update_schema']['submit'] = array(
104 '#type' => 'submit',
105 '#submit' => array('data_ui_adjust_form_submit_update_schema'),
106 '#value' => t('Update schema information'),
107 );
108 $form['alter_table'] = array(
109 '#type' => 'fieldset',
110 '#title' => t('Option 2: Alter table'),
111 );
112 $form['alter_table']['description'] = array(
113 '#value' => t('<p>Review the changes above carefully!
114 This option will alter the database table and can very
115 easily cause data loss.</p>'),
116 );
117 $form['alter_table']['submit'] = array(
118 '#type' => 'submit',
119 '#submit' => array('data_ui_adjust_form_submit_alter_table'),
120 '#value' => t('Alter table'),
121 );
122 }
123 elseif ($comparison['status'] == 'missing') {
124 $form['alter_table'] = array(
125 '#type' => 'fieldset',
126 '#title' => t('Create table'),
127 );
128 $form['alter_table']['description'] = array(
129 '#value' => t('<p>Create a new table from schema information.</p>'),
130 );
131 $form['alter_table']['submit'] = array(
132 '#type' => 'submit',
133 '#submit' => array('data_ui_adjust_form_submit_create_table'),
134 '#value' => t('Create table'),
135 );
136 }
137 $form['cancel'] = array(
138 '#type' => 'fieldset',
139 '#title' => t('Don\'t change anything'),
140 );
141 $form['cancel']['cancel'] = array(
142 '#type' => 'submit',
143 '#value' => t('Cancel'),
144 );
145 return $form;
146 }
147
148 /**
149 * Submit handler for data_ui_adjust_form().
150 */
151 function data_ui_adjust_form_submit_update_schema($form, &$form_state) {
152 $table = $form['#table'];
153 $schema = schema_invoke('inspect');
154 if (isset($schema[$table->get('name')])) {
155 $table->update(array('table_schema' => $schema[$table->get('name')]));
156 drupal_set_message(t('Updated schema for !table', array('!table' => $table->get('name'))));
157 }
158 else {
159 drupal_set_message(t('Error updating schema'), 'error');
160 }
161 }
162
163 /**
164 * Submit handler for data_ui_adjust_form().
165 */
166 function data_ui_adjust_form_submit_alter_table($form, &$form_state) {
167 $resolved = $resolved = array();
168 if (isset($form['#comparison']['reasons'])) {
169 foreach ($form['#comparison']['reasons'] as $field_reason) {
170 if (_data_ui_alter_table($form['#table'], $field_reason)) {
171 $resolved[] = $field_reason;
172 }
173 else {
174 $unresolved[] = $field_reason;
175 }
176 }
177 }
178 if (count($resolved)) {
179 drupal_set_message(t('Resolved') . theme_item_list($resolved));
180 }
181 if (count($unresolved)) {
182 drupal_set_message(t('Could not resolve') . theme_item_list($unresolved), 'error');
183 }
184 }
185
186 /**
187 * Submit handler for data_ui_adjust_form().
188 */
189 function data_ui_adjust_form_submit_create_table($form, &$form_state) {
190 $table = $form['#table'];
191 $ret = array();
192 db_create_table($ret, $table->get('name'), $table->get('table_schema'));
193 if ($ret[0]['success']) {
194 drupal_set_message(t('Created table !table', array('!table' => $table->get('name'))));
195 }
196 else {
197 drupal_set_message(t('Error creating table'), 'error');
198 }
199 }
200
201 /**
202 * Form callback for create table form.
203 */
204 function data_ui_create_form(&$form_state) {
205 $form = array();
206 if (!$form_state['storage']['field_num']) {
207 $form['name'] = array(
208 '#type' => 'textfield',
209 '#title' => t('Table name'),
210 '#description' => t('Machine readable name of the table - e. g. "my_table". Must only contain lower case letters and _.'),
211 '#required' => TRUE,
212 );
213 $form['title'] = array(
214 '#type' => 'textfield',
215 '#title' => t('Table title'),
216 '#description' => t('Natural name of the table - e. g. "My Table".'),
217 );
218 $form['field_num'] = array(
219 '#type' => 'textfield',
220 '#title' => t('Number of fields'),
221 '#description' => t('The number of fields this table should contain.'),
222 '#default_value' => 1,
223 '#required' => TRUE,
224 );
225 $form['submit'] = array(
226 '#type' => 'submit',
227 '#value' => t('Next'),
228 );
229 }
230 else {
231 $form['help']['#value'] = t('Define the fields of the new table.');
232 $form['fields'] = array(
233 '#tree' => TRUE,
234 );
235 for ($i = 0; $i < $form_state['storage']['field_num']; $i++) {
236 $form['fields']['field_'. $i] = _data_ui_field_form(TRUE);
237 }
238 $form['submit'] = array(
239 '#type' => 'submit',
240 '#value' => t('Create'),
241 );
242 }
243 return $form;
244 }
245
246 /**
247 * Validate handler for create table form.
248 */
249 function data_ui_create_form_validate($form, &$form_state) {
250 if (data_get_table(data_name($form_state['values']['name']))) {
251 form_set_error('name', t('Name is already taken.'));
252 }
253 if (isset($form_state['values']['field_num'])) {
254 if (is_numeric($form_state['values']['field_num'])) {
255 if ($form_state['values']['field_num'] < 1) {
256 form_set_error('field_num', t('At least one field must be created.'));
257 }
258 }
259 else {
260 form_set_error('field_num', t('Enter a number greater than 0.'));
261 }
262 }
263 // Check for dupes.
264 if (isset($form_state['values']['fields'])) {
265 $names = array();
266 foreach ($form_state['values']['fields'] as $field) {
267 if (is_numeric($names[$field['name']])) {
268 form_set_error('name', t('Names can\'t be numbers.'));
269 }
270 if (!isset($names[$field['name']])) {
271 $names[$field['name']] = $field['name'];
272 }
273 else {
274 form_set_error('name', t('Names must be unique.'));
275 }
276 }
277 }
278 }
279
280 /**
281 * Submit handler for create table form.
282 */
283 function data_ui_create_form_submit($form, &$form_state) {
284
285 if (isset($form_state['values']['field_num'])) {
286 $form_state['storage'] = $form_state['values'];
287 }
288 elseif (isset($form_state['values']['fields'])) {
289
290 // Create a schema from user input.
291 $schema = $index = $primary = $meta = array();
292 foreach ($form_state['values']['fields'] as $field) {
293 $schema['fields'][$field['name']] = data_build_field_definition($field);
294 $meta['fields'][$field['name']]['label'] = $field['label'];
295
296 // Limit index if field type is text.
297 if (!empty($field['index'])) {
298 $index[$field['name']] = data_get_index_definition($field['name'], $field['type']);
299 }
300 if (!empty($field['primary'])) {
301 $primary[] = data_get_pk_definition($field['name'], $field['type']);
302 }
303 }
304 $schema['indexes'] = $index;
305 $schema['primary key'] = $primary;
306
307 // Create table.
308 if ($table = data_create_table(data_name(trim($form_state['storage']['name'])), $schema, trim($form_state['storage']['title']))) {
309 $meta = $table->update(array('meta' => $meta));
310 drupal_set_message(t('Created table !table', array('!table' => $table->get('name'))));
311 }
312 else {
313 drupal_set_message(t('Error creating table'), 'error');
314 }
315
316 // Unset storage to enable redirect.
317 unset($form_state['storage']);
318 $form_state['redirect'] = 'admin/content/data';
319 }
320 }
321
322 /**
323 * Form callback for revert table form.
324 */
325 function data_ui_revert_form(&$form_state, $table) {
326 $form = array();
327 $form['#redirect'] = 'admin/content/data';
328 $form['#table'] = $table;
329
330 return confirm_form($form,
331 t('Revert this table?'),
332 'admin/content/data',
333 t('Are you sure you would like to revert table !table? This will reset all information about this table its definition in code. This action cannot be undone.', array('!table' => $table->get('name'))),
334 t('Revert'), t('Cancel')
335 );
336 }
337
338 /**
339 * Submit handler for data_ui_revert_form().
340 */
341 function data_ui_revert_form_submit($form, &$form_state) {
342 $table = $form['#table'];
343 $table->revert();
344 }
345
346 /**
347 * Form callback for drop table form.
348 */
349 function data_ui_drop_form(&$form_state, $table) {
350 $form = array();
351 $form['#redirect'] = 'admin/content/data';
352 $form['#table'] = $table;
353
354 return confirm_form($form,
355 t('Drop this table?'),
356 'admin/content/data',
357 t('Are you sure you would like to drop table !table? This action cannot be undone.', array('!table' => $table->get('name'))),
358 t('Drop'), t('Cancel')
359 );
360 }
361
362 /**
363 * Submit handler for data_ui_drop_form().
364 */
365 function data_ui_drop_form_submit($form, &$form_state) {
366 $table = $form['#table'];
367 data_drop_table($table->get('name'));
368 }
369
370 /**
371 * Form callback for editing a table.
372 */
373 function data_ui_edit_form(&$form_state, $table) {
374 drupal_set_title(t('Data table !table', array('!table' => $table->get('name'))));
375 $schema = $table->get('table_schema');
376 $meta = $table->get('meta');
377
378 $form = array();
379 // Keep table.
380 $form['table'] = array(
381 '#type' => 'value',
382 '#value' => $table,
383 );
384
385 // Existing fields.
386 $form['fields'] = array('#tree' => TRUE);
387 if (isset($schema['fields'])) {
388 foreach ($schema['fields'] as $field_name => $field) {
389 $form['fields'][$field_name] = array();
390 $form['fields'][$field_name]['selected'] = array(
391 '#type' => 'checkbox',
392 );
393 $form['fields'][$field_name]['name'] = array('#value' => $field_name);
394 $form['fields'][$field_name]['label'] = array(
395 '#type' => 'textfield',
396 '#size' => 20,
397 '#default_value' => $meta['fields'][$field_name]['label'],
398 );
399 $form['fields'][$field_name]['type'] = array(
400 '#type' => 'select',
401 '#options' => data_get_field_types(),
402 '#default_value' => $field['type'],
403 );
404 $form['fields'][$field_name]['unsigned'] = array(
405 '#type' => 'checkbox',
406 '#default_value' => $field['unsigned'],
407 );
408 $form['fields'][$field_name]['index'] = array(
409 '#type' => 'checkbox',
410 '#default_value' => isset($schema['indexes'][$field_name]),
411 );
412 $form['fields'][$field_name]['primary'] = array(
413 '#type' => 'checkbox',
414 '#default_value' => isset($schema['primary key']) ? in_array($field_name, $schema['primary key']) : FALSE,
415 );
416 if ($join = _data_ui_get_join($meta['join'], $field_name)) {
417 $join = $join['left_table'] .'.'. $join['left_field'];
418 }
419 else {
420 $join = t('<none>');
421 }
422 $join = l($join, 'admin/content/data/edit/'. $table->get('name') .'/join/'.$field_name);
423 $form['fields'][$field_name]['join']['#value'] = $join;
424 }
425 }
426
427 // Add a new field.
428 $form['new'] = _data_ui_field_form();
429 $form['new']['primary'] = array(
430 '#type' => 'markup',
431 '#value' => '&nbsp;',
432 );
433 $form['new']['join'] = array(
434 '#type' => 'markup',
435 '#value' => '&nbsp;',
436 );
437 $form['new']['add'] = array(
438 '#type' => 'submit',
439 '#value' => t('Add new'),
440 );
441
442 // Bulk operations.
443 $options = array(
444 t('Bulk operations'),
445 'delete' => t('Delete all selected'),
446 );
447 $form['bulk_operation'] = array(
448 '#type' => 'select',
449 '#options' => $options,
450 );
451 $form['submit'] = array(
452 '#type' => 'submit',
453 '#value' => t('Save'),
454 );
455
456 return $form;
457 }
458
459 /**
460 * Submit form.
461 */
462 function data_ui_edit_form_submit($form, &$form_state) {
463 $table = $form_state['values']['table'];
464 $schema = $table->get('table_schema');
465
466 if ($form_state['clicked_button']['#value'] == t('Save')) {
467 $fields = $schema['fields'];
468 $new_fields = $form_state['values']['fields'];
469
470 $new_index = array();
471 $new_primary_key = array();
472
473 if (empty($form_state['values']['bulk_operation']) && isset($fields)) {
474
475 // Convert schema.
476 foreach ($fields as $field_name => $field) {
477 if ($new_spec = _data_ui_changed($new_fields[$field_name], $field)) {
478 $table->changeField($field_name, $new_spec);
479 drupal_set_message(t('Changed field !field_name', array('!field_name' => $field_name)));
480 }
481 if ($new_fields[$field_name]['index']) {
482 $new_index[] = $field_name;
483 }
484 if ($new_fields[$field_name]['primary']) {
485 $new_primary_key[] = $field_name;
486 }
487 }
488 $table->changeIndex($new_index);
489 $table->changePrimaryKey($new_primary_key);
490
491 // Update meta data.
492 $meta = $table->get('meta');
493 foreach ($new_fields as $field_name => $field) {
494 $meta['fields'][$field_name]['label'] = $field['label'];
495 }
496 $table->update(array('meta' => $meta));
497 }
498 else {
499 // Bulk updates.
500 switch ($form_state['values']['bulk_operation']) {
501 case 'delete':
502 foreach ($new_fields as $field_name => $field) {
503 if (!empty($field['selected'])) {
504 // One field must stay.
505 $schema = $table->get('table_schema');
506 if (count($schema['fields']) > 1) {
507 $table->dropField($field_name);
508 drupal_set_message(t('Deleted field !field_name', array('!field_name' => $field_name)));
509 }
510 else {
511 drupal_set_message('You cannot delete all fields from a table, drop the table instead.', 'error');
512 }
513 }
514 }
515 break;
516 }
517 }
518 }
519 elseif ($form_state['clicked_button']['#value'] == t('Add new')) {
520 $new = $form_state['values']['new'];
521 $spec = data_build_field_definition($new);
522 $table->addField($new['name'], $spec);
523 if (!empty($new['index'])) {
524 $table->addIndex($new['name']);
525 }
526 $meta = $table->get('meta');
527 $meta['fields'][$new['name']]['label'] = $new['label'];
528 $table->update(array('meta' => $meta));
529 }
530 }
531
532 /**
533 * Join form.
534 */
535 function data_ui_join_form(&$form_state, $table, $field_name) {
536 // drupal_set_title(t('Join field'));
537
538 $schema = $table->get('table_schema');
539 $meta = $table->get('meta');
540
541 // Validate input.
542 if (!isset($field_name) || !isset($schema['fields'][$field_name])) {
543 drupal_set_message(t('Invalid field.'), 'error');
544 drupal_goto('admin/content/data/edit/'. $table->get('name'));
545 }
546
547 // List all tables that schema API knows about as optoins.
548 // @todo: This is a looong list - needs some AHAH to scale better.
549 $table_schemas = drupal_get_schema();
550 ksort($table_schemas);
551 $options = array();
552 foreach ($table_schemas as $table_name => $schema) {
553 if ($table->get('name') != $table_name) {
554 foreach ($schema['fields'] as $name => $info) {
555 $options[$table_name][$table_name .'.'. $name] = $table_name .'.'. $name;
556 }
557 }
558 }
559
560 // Build form.
561 $form = array();
562 $form['#table'] = $table;
563 $form['#field_name'] = $field_name;
564 $form['#redirect'] = 'admin/content/data/edit/'. $table->get('name');
565 $join = _data_ui_get_join($meta['join'], $field_name);
566 $form['#original_join'] = $join;
567 $form['left'] = array(
568 '#type' => 'select',
569 '#title' => t('Join !table_field to', array('!table_field' => $table->get('name') .'.'. $field_name)),
570 '#options' => $options,
571 '#default_value' => $join['left_table'] .'.'. $join['left_field'],
572 );
573 $form['inner_join'] = array(
574 '#type' => 'radios',
575 '#title' => t('Join type'),
576 '#options' => array(t('Left join'), t('Inner join')),
577 '#default_value' => $join['inner_join'] ? $join['inner_join'] : 0,
578 );
579
580 // Use confirm form for its formatting.
581 $form = confirm_form($form,
582 t('Join field'),
583 'admin/content/data/edit/'. $table->get('name'),
584 '',
585 t('Save'), t('Cancel')
586 );
587 $form['actions']['delete'] = array(
588 '#type' => 'submit',
589 '#value' => t('Delete'),
590 '#submit' => array('data_ui_join_form_submit_delete'),
591 );
592 krsort($form['actions']);
593
594 return $form;
595 }
596
597 /**
598 * Submit handler for data_ui_join_form().
599 */
600 function data_ui_join_form_submit($form, &$form_state) {
601 list($left_table, $left_field) = explode('.', $form_state['values']['left']);
602 $form['#table']->link($left_table, $left_field, $form['#field_name'], $form_state['values']['inner_join']);
603 drupal_set_message(t('Updated join information.'));
604 }
605
606 /**
607 * Submit handler for data_ui_join_form() - handles deletion.
608 */
609 function data_ui_join_form_submit_delete($form, &$form_state) {
610 // Use the original join information.
611 $form['#table']->unlink($form['#original_join']['left_table']);
612 drupal_set_message(t('Removed join information.'));
613 }
614
615 /**
616 * Export form.
617 */
618 function data_ui_export_form(&$form_state, $table) {
619 $code = data_export($table->get('name'));
620
621 $form['export'] = array(
622 '#title' => t('Export table definition'),
623 '#type' => 'textarea',
624 '#value' => $code,
625 '#rows' => substr_count($code, "\n"),
626 );
627 return $form;
628 }
629
630 /**
631 * Theme data_ui_create_form.
632 */
633 function theme_data_ui_create_form($form) {
634
635 // Render field definition form elements in a table.
636 if (isset($form['fields'])) {
637 $output = drupal_render($form['help']);
638
639 $rows = array();
640 foreach (element_children($form['fields']) as $e) {
641 $row = array();
642 foreach (element_children($form['fields'][$e]) as $f) {
643 $row[] = drupal_render($form['fields'][$e][$f]);
644 }
645 $rows[] = $row;
646 }
647 $header = array(t('Name *'), t('Label'), t('Type'), t('Unsigned'), t('Index'), t('Primary key'));
648 $output .= theme('table', $header, $rows);
649
650 $output .= drupal_render($form);
651 return $output;
652 }
653 return drupal_render($form);
654 }
655
656 /**
657 * Theme data_ui_admin_form.
658 */
659 function theme_data_ui_edit_form($form) {
660
661 // Format existing fields.
662 $rows = array();
663 foreach (element_children($form['fields']) as $e) {
664 $row = array();
665 foreach (element_children($form['fields'][$e]) as $f) {
666 $row[] = drupal_render($form['fields'][$e][$f]);
667 }
668 $row[] = '&nbsp;';
669 $rows[] = $row;
670 }
671
672 // New fields form.
673 $row = array('&nbsp;');
674 foreach (element_children($form['new']) as $e) {
675 $row[] = drupal_render($form['new'][$e]);
676 }
677 $rows[] = $row;
678
679 $header = array(t('Select'), t('Name'), t('Label'), t('Type'), t('Unsigned'), t('Index'), t('Primary key'), t('Joins'));
680 $output .= theme('table', $header, $rows);
681 $output .= drupal_render($form);
682 return $output;
683 }
684
685 /**
686 * Theme a schema module comparison result. Ie. the result of schema_compare_table().
687 *
688 * @todo: move to schema module - write a patch.
689 */
690 function theme_data_ui_schema_compare_table($comparison) {
691 $output = '';
692 foreach ($comparison as $k => $v) {
693 if (!empty($v)) {
694 if (is_string($k)) {
695 $output .= '<dl>';
696 $output .= '<dt>'. ucfirst($k) .':</dt>';
697 $output .= '<dd>';
698 if (is_string($v)) {
699 $output .= $v;
700 }
701 elseif (is_array($v)) {
702 $output .= theme('item_list', $v);
703 }
704 $output .= '</dd>';
705 $output .= '</dl>';
706 }
707 }
708 }
709 return $output;
710 }
711
712 /**
713 * Magic helper function. Detect changed between keys in $new and $field
714 * and return a new field spec based on $field IF there are differences.
715 *
716 * Otherwise return FALSE.
717 *
718 * Currently checked: type, unsigned
719 */
720 function _data_ui_changed($new, $field) {
721 $changed = FALSE;
722 if ($field['type'] != $new['type']) {
723 $field['type'] = $new['type'];
724 $changed = TRUE;
725 }
726 if ($field['unsigned'] != $new['unsigned']) {
727 $field['unsigned'] = $new['unsigned'];
728 $changed = TRUE;
729 }
730 if ($changed) {
731 return $field;
732 }
733 return FALSE;
734 }
735
736 /**
737 * Helper function that generates a form snippet for defining a field.
738 */
739 function _data_ui_field_form($required = FALSE) {
740 $form = array();
741 $form['#tree'] = TRUE;
742 $form['name'] = array(
743 '#type' => 'textfield',
744 '#size' => 20,
745 '#required' => $required,
746 );
747 $form['label'] = array(
748 '#type' => 'textfield',
749 '#size' => 20,
750 );
751 $form['type'] = array(
752 '#type' => 'select',
753 '#options' => data_get_field_types(),
754 );
755 $form['unsigned'] = array(
756 '#type' => 'checkbox',
757 );
758 $form['index'] = array(
759 '#type' => 'checkbox',
760 );
761 $form['primary'] = array(
762 '#type' => 'checkbox',
763 );
764 return $form;
765 }
766
767 /**
768 * Helper function to get link information for a specific field.
769 */
770 function _data_ui_get_join($join, $field) {
771 if (is_array($join)) {
772 foreach ($join as $left_table => $info) {
773 if ($info['field'] == $field) {
774 $info['left_table'] = $left_table;
775 return $info;
776 }
777 }
778 }
779 return FALSE;
780 }
781
782 /**
783 * Helper function for adjusting a table's real schema.
784 * @todo: this should live in schema module and should use better defined $reason keys.
785 */
786 function _data_ui_alter_table($table, $field_reason) {
787 list($field, $reason) = explode(': ', $field_reason);
788 $schema = $table->get('table_schema');
789
790 switch ($reason) {
791 case 'not in database':
792 if (isset($schema['fields'][$field])) {
793 return $table->addField($field, $schema['fields'][$field]);
794 }
795 return FALSE;
796
797 case 'missing in database':
798 list($type, $field) = explode(' ', $field);
799 // @todo: support multiple keys.
800 if ($type == 'indexes') {
801 return $table->addIndex($field);
802 }
803 elseif ($type == 'unique keys') {
804 return $table->addUniqueKey($field);
805 }
806 elseif ($type == 'primary key') {
807 return $table->addPrimaryKey($schema['primary keys']);
808 }
809 return FALSE;
810
811 case 'primary key:<br />declared': // @todo: yikes!
812 $table->dropPrimaryKey();
813 return $table->changePrimaryKey($schema['primary keys']);
814 case 'missing in schema':
815 if ($field == 'primary key') {
816 return $table->dropPrimaryKey();
817 }
818 return FALSE;
819
820 case 'unexpected column in database':
821 return $this->dropField($field);
822
823 }
824 return FALSE;
825 }