mviews.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. <?php
  2. /**
  3. * @file
  4. * Contains functions for the Materialized Views API
  5. * @defgroup tripal_mviews_api Core Module Materalized Views API
  6. * @{
  7. * Provides an application programming interface (API) to manage materialized views in Chado.
  8. * The Perl-based chado comes with an interface for managing materialzed views. This
  9. * API provides an alternative Drupal-based method.
  10. * @}
  11. * @ingroup tripal_api
  12. */
  13. /**
  14. * Add a materialized view to the chado database to help speed data access. This
  15. * function supports the older style where postgres column specifications
  16. * are provided using the $mv_table, $mv_specs and $indexed variables. It also
  17. * supports the newer preferred method where the materialized view is described
  18. * using the Drupal Schema API array.
  19. *
  20. * @param $name
  21. * The name of the materialized view.
  22. * @param $modulename
  23. * The name of the module submitting the materialized view (e.g. 'tripal_library')
  24. * @param $mv_table
  25. * The name of the table to add to chado. This is the table that can be queried.
  26. * @param $mv_specs
  27. * The table definition
  28. * @param $indexed
  29. * The columns that are to be indexed
  30. * @param $query
  31. * The SQL query that loads the materialized view with data
  32. * @param $special_index
  33. * currently not used
  34. * @param $comment
  35. * A string containing a description of the materialized view
  36. * @param $mv_schema
  37. * If using the newer Schema API array to define the materialized view then
  38. * this variable should contain the array.
  39. *
  40. * @ingroup tripal_mviews_api
  41. */
  42. function tripal_add_mview($name, $modulename, $mv_table, $mv_specs, $indexed,
  43. $query, $special_index, $comment = NULL, $mv_schema = NULL) {
  44. // get the table name from the schema array
  45. $schema_arr = array();
  46. if ($mv_schema) {
  47. // get the schema from the mv_specs and use it to add the custom table
  48. eval("\$schema_arr = $mv_schema;");
  49. $mv_table = $schema_arr['table'];
  50. }
  51. // Create a new record
  52. $record = new stdClass();
  53. $record->name = $name;
  54. $record->modulename = $modulename;
  55. $record->mv_table = $mv_table;
  56. $record->mv_specs = $mv_specs;
  57. $record->indexed = $indexed;
  58. $record->query = $query;
  59. $record->special_index = $special_index;
  60. $record->comment = $comment;
  61. $record->mv_schema = $mv_schema;
  62. // add the record to the tripal_mviews table and if successful
  63. // create the new materialized view in the chado schema
  64. if (drupal_write_record('tripal_mviews', $record)) {
  65. // drop the table from chado if it exists
  66. $previous_db = tripal_db_set_active('chado'); // use chado database
  67. if (db_table_exists($mv_table)) {
  68. $sql = "DROP TABLE $mv_table";
  69. db_query($sql);
  70. }
  71. tripal_db_set_active($previous_db); // now use drupal database
  72. // now construct the indexes
  73. $index = '';
  74. if ($indexed) {
  75. // add to the array of values
  76. $vals = preg_split("/[\n,]+/", $indexed);
  77. $index = '';
  78. foreach ($vals as $field) {
  79. $field = trim($field);
  80. $index .= "CREATE INDEX idx_${mv_table}_${field} ON $mv_table ($field);";
  81. }
  82. }
  83. // create the table differently depending on if it the traditional method
  84. // or the Drupal Schema API method
  85. if ($mv_schema) {
  86. if (!tripal_core_create_custom_table ($ret, $mv_table, $schema_arr)) {
  87. drupal_set_message(t("Could not create the materialized view. Check Drupal error report logs."), 'error');
  88. }
  89. else {
  90. drupal_set_message(t("View '%name' created", array('%name' => $name)));
  91. }
  92. }
  93. else {
  94. // add the table to the database
  95. $sql = "CREATE TABLE {$mv_table} ($mv_specs); $index";
  96. $previous_db = tripal_db_set_active('chado'); // use chado database
  97. $results = db_query($sql);
  98. tripal_db_set_active($previous_db); // now use drupal database
  99. if ($results) {
  100. drupal_set_message(t("View '%name' created", array('%name' => $name)));
  101. }
  102. else {
  103. drupal_set_message(t("Failed to create the materialized view table: '%mv_table'", array('%mv_table' => $mv_table)), 'error');
  104. }
  105. }
  106. }
  107. }
  108. /**
  109. * Edits a materialized view to the chado database to help speed data access.This
  110. * function supports the older style where postgres column specifications
  111. * are provided using the $mv_table, $mv_specs and $indexed variables. It also
  112. * supports the newer preferred method where the materialized view is described
  113. * using the Drupal Schema API array.
  114. *
  115. * @param $mview_id
  116. * The mview_id of the materialized view to edit
  117. * @param $name
  118. * The name of the materialized view.
  119. * @param $modulename
  120. * The name of the module submitting the materialized view (e.g. 'tripal_library')
  121. * @param $mv_table
  122. * The name of the table to add to chado. This is the table that can be queried.
  123. * @param $mv_specs
  124. * The table definition
  125. * @param $indexed
  126. * The columns that are to be indexed
  127. * @param $query
  128. * The SQL query that loads the materialized view with data
  129. * @param $special_index
  130. * currently not used
  131. * @param $comment
  132. * A string containing a description of the materialized view
  133. * @param $mv_schema
  134. * If using the newer Schema API array to define the materialized view then
  135. * this variable should contain the array.
  136. *
  137. * @ingroup tripal_mviews_api
  138. */
  139. function tripal_edit_mview($mview_id, $name, $modulename, $mv_table, $mv_specs,
  140. $indexed, $query, $special_index, $comment = NULL, $mv_schema = NULL) {
  141. // get the table name from the schema array
  142. $schema_arr = array();
  143. if ($mv_schema) {
  144. // get the schema from the mv_specs and use it to add the custom table
  145. eval("\$schema_arr = $mv_schema;");
  146. $mv_table = $schema_arr['table'];
  147. }
  148. // Create a new record
  149. $record = new stdClass();
  150. $record->mview_id = $mview_id;
  151. $record->name = $name;
  152. $record->modulename = $modulename;
  153. $record->mv_schema = $mv_schema;
  154. $record->mv_table = $mv_table;
  155. $record->mv_specs = $mv_specs;
  156. $record->indexed = $indexed;
  157. $record->query = $query;
  158. $record->special_index = $special_index;
  159. $record->last_update = 0;
  160. $record->status = '';
  161. $record->comment = $comment;
  162. // drop the table from chado if it exists
  163. $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = %d";
  164. $mview = db_fetch_object(db_query($sql, $mview_id));
  165. $previous_db = tripal_db_set_active('chado'); // use chado database
  166. if (db_table_exists($mview->mv_table)) {
  167. $sql = "DROP TABLE %s";
  168. db_query($sql, $mview->mv_table);
  169. }
  170. tripal_db_set_active($previous_db); // now use drupal database
  171. // update the record to the tripal_mviews table and if successful
  172. // create the new materialized view in the chado schema
  173. if (drupal_write_record('tripal_mviews', $record, 'mview_id')) {
  174. // drop the table from chado if it exists
  175. $previous_db = tripal_db_set_active('chado'); // use chado database
  176. if (db_table_exists($mv_table)) {
  177. $sql = "DROP TABLE %s";
  178. db_query($sql, $mv_table);
  179. }
  180. tripal_db_set_active($previous_db); // now use drupal database
  181. // now construct the indexes
  182. $index = '';
  183. if ($indexed) {
  184. // add to the array of values
  185. $vals = preg_split("/[\n,]+/", $indexed);
  186. $index = '';
  187. foreach ($vals as $field) {
  188. $field = trim($field);
  189. $index .= "CREATE INDEX idx_${mv_table}_${field} ON $mv_table ($field);";
  190. }
  191. }
  192. // re-create the table differently depending on if it the traditional method
  193. // or the Drupal Schema API method
  194. if ($mv_schema) {
  195. if (!tripal_core_create_custom_table($ret, $mv_table, $schema_arr)) {
  196. drupal_set_message(t("Could not create the materialized view. Check Drupal error report logs."));
  197. }
  198. else {
  199. drupal_set_message(t("View '%name' created", array('%name' => $name)));
  200. }
  201. }
  202. else {
  203. $sql = "CREATE TABLE {$mv_table} ($mv_specs); $index";
  204. $previous_db = tripal_db_set_active('chado'); // use chado database
  205. $results = db_query($sql);
  206. tripal_db_set_active($previous_db); // now use drupal database
  207. if ($results) {
  208. drupal_set_message(t("View '%name' edited and saved. All results cleared. Please re-populate the view.", array('%name' => $name)));
  209. }
  210. else {
  211. drupal_set_message(t("Failed to create the materialized view table: '%mv_table'", array('%mv_table' => $mv_table)), 'error');
  212. }
  213. }
  214. }
  215. }
  216. /**
  217. * Retrieve the materialized view_id given the name
  218. *
  219. * @param $view_name
  220. * The name of the materialized view
  221. *
  222. * @return
  223. * The unique identifier for the given view
  224. *
  225. * @ingroup tripal_mviews_api
  226. */
  227. function tripal_mviews_get_mview_id($view_name) {
  228. $sql = "SELECT * FROM {tripal_mviews} ".
  229. "WHERE name = '%s'";
  230. if (db_table_exists('tripal_mviews')) {
  231. $mview = db_fetch_object(db_query($sql, $view_name));
  232. if ($mview) {
  233. return $mview->mview_id;
  234. }
  235. }
  236. return FALSE;
  237. }
  238. /**
  239. * Does the specified action for the specified Materialized View
  240. *
  241. * @param $op
  242. * The action to be taken. One of update or delete
  243. * @param $mview_id
  244. * The unique ID of the materialized view for the action to be performed on
  245. * @param $redirect
  246. * TRUE/FALSE depending on whether you want to redirect the user to admin/tripal/mviews
  247. *
  248. * @ingroup tripal_core
  249. */
  250. function tripal_mviews_action($op, $mview_id, $redirect = FALSE) {
  251. global $user;
  252. $args = array("$mview_id");
  253. if (!$mview_id) {
  254. return '';
  255. }
  256. // get this mview details
  257. $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = %d";
  258. $mview = db_fetch_object(db_query($sql, $mview_id));
  259. // add a job or perform the action based on the given operation
  260. if ($op == 'update') {
  261. tripal_add_job("Populate materialized view '$mview->name'", 'tripal_core',
  262. 'tripal_update_mview', $args, $user->uid);
  263. }
  264. if ($op == 'delete') {
  265. // remove the mview from the tripal_mviews table
  266. $sql = "DELETE FROM {tripal_mviews} ".
  267. "WHERE mview_id = $mview_id";
  268. db_query($sql);
  269. // drop the table from chado if it exists
  270. $previous_db = tripal_db_set_active('chado'); // use chado database
  271. if (db_table_exists($mview->mv_table)) {
  272. $sql = "DROP TABLE $mview->mv_table";
  273. db_query($sql);
  274. }
  275. tripal_db_set_active($previous_db); // now use drupal database
  276. }
  277. // Redirect the user
  278. if ($redirect) {
  279. drupal_goto("admin/tripal/mviews");
  280. }
  281. }
  282. /**
  283. * Update a Materialized View
  284. *
  285. * @param $mview_id
  286. * The unique identifier for the materialized view to be updated
  287. *
  288. * @return
  289. * True if successful, FALSE otherwise
  290. *
  291. * @ingroup tripal_mviews_api
  292. */
  293. function tripal_update_mview($mview_id) {
  294. $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = %d ";
  295. $mview = db_fetch_object(db_query($sql, $mview_id));
  296. if ($mview) {
  297. $previous_db = tripal_db_set_active('chado'); // use chado database
  298. $results = db_query("DELETE FROM {%s}", $mview->mv_table);
  299. $results = db_query("INSERT INTO {%s} ($mview->query)", $mview->mv_table);
  300. tripal_db_set_active($previous_db); // now use drupal database
  301. if ($results) {
  302. $sql = "SELECT count(*) as cnt FROM {%s}";
  303. $count = db_fetch_object(db_query($sql, $mview->mv_table));
  304. $record = new stdClass();
  305. $record->mview_id = $mview_id;
  306. $record->last_update = time();
  307. $record->status = "Populated with " . number_format($count->cnt) . " rows";
  308. drupal_write_record('tripal_mviews', $record, 'mview_id');
  309. return TRUE;
  310. }
  311. else {
  312. // print and save the error message
  313. $record = new stdClass();
  314. $record->mview_id = $mview_id;
  315. $record->status = "ERROR populating. See Drupal's recent log entries for details.";
  316. print $record->status . "\n";
  317. drupal_write_record('tripal_mviews', $record, 'mview_id');
  318. return FALSE;
  319. }
  320. }
  321. }
  322. /**
  323. * A template function which returns markup to display details for the current materialized view
  324. *
  325. * @param $mview_id
  326. * The unique ID of the materialized view to render
  327. *
  328. * @ingroup tripal_mviews_api
  329. */
  330. function tripal_mview_report($mview_id) {
  331. // get this mview details
  332. $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = %d";
  333. $mview = db_fetch_object(db_query($sql, $mview_id));
  334. // create a table with each row containig stats for
  335. // an individual job in the results set.
  336. $return_url = url("admin/tripal/mviews/");
  337. $output .= "<p><a href=\"$return_url\">Return to table of materialized views.</a></p>";
  338. $output .= "<br />";
  339. $output .= "<p>Details for <b>$mview->name</b>:</p>";
  340. $output .= "<br />";
  341. $output .= "<table class=\"border-table\">";
  342. if ($mview->name) {
  343. $output .= " <tr>".
  344. " <th>View Name</th>".
  345. " <td>$mview->name</td>".
  346. " </tr>";
  347. }
  348. if ($mview->modulename) {
  349. $output .= " <tr>".
  350. " <th>Module Name</th>".
  351. " <td>$mview->modulename</td>".
  352. " </tr>";
  353. }
  354. if ($mview->mv_table) {
  355. $output .= " <tr>".
  356. " <th>Table Name</th>".
  357. " <td>$mview->mv_table</td>".
  358. " </tr>";
  359. }
  360. if ($mview->mv_specs) {
  361. $output .= " <tr>".
  362. " <th>Table Field Definitions</th>".
  363. " <td>$mview->mv_specs</td>".
  364. " </tr>";
  365. }
  366. if ($mview->query) {
  367. $output .= " <tr>".
  368. " <th>Query</th>".
  369. " <td><pre>$mview->query</pre></td>".
  370. " </tr>";
  371. }
  372. if ($mview->indexed) {
  373. $output .= " <tr>".
  374. " <th>Indexed Fields</th>".
  375. " <td>$mview->indexed</td>".
  376. " </tr>";
  377. }
  378. if ($mview->special_index) {
  379. $output .= " <tr>".
  380. " <th>Special Indexed Fields</th>".
  381. " <td>$mview->speical_index</td>".
  382. " </tr>";
  383. }
  384. if ($mview->last_update > 0) {
  385. $update = format_date($mview->last_update);
  386. }
  387. else {
  388. $update = 'Not yet populated';
  389. }
  390. $output .= " <tr>".
  391. " <th>Last Update</th>".
  392. " <td>$update</td>".
  393. " </tr>";
  394. // build the URLs using the url function so we can handle installations where
  395. // clean URLs are or are not used
  396. $update_url = url("admin/tripal/mviews/action/update/$mview->mview_id");
  397. $delete_url = url("admin/tripal/mviews/action/delete/$mview->mview_id");
  398. $edit_url = url("admin/tripal/mviews/edit/$mview->mview_id");
  399. $output .= "<tr><th>Actions</th>".
  400. "<td> <a href='$update_url'>Populate</a>, ".
  401. " <a href='$edit_url'>Edit</a>, ".
  402. " <a href='$delete_url'>Delete</a></td></tr>";
  403. $output .= "</table>";
  404. return $output;
  405. }
  406. /**
  407. * A template function to render a listing of all Materialized Views
  408. *
  409. * @ingroup tripal_mviews_api
  410. */
  411. function tripal_mviews_report() {
  412. $header = array('', 'MView Name', 'Last Update', 'Status', 'Description', '');
  413. $rows = array();
  414. $mviews = db_query("SELECT * FROM {tripal_mviews} ORDER BY name");
  415. while ($mview = db_fetch_object($mviews)) {
  416. if ($mview->last_update > 0) {
  417. $update = format_date($mview->last_update);
  418. }
  419. else {
  420. $update = 'Not yet populated';
  421. }
  422. $rows[] = array(
  423. l(t('View'), "admin/tripal/mviews/report/$mview->mview_id") ." | ".
  424. l(t('Edit'), "admin/tripal/mviews/edit/$mview->mview_id") ." | ".
  425. l(t('Populate'), "admin/tripal/mviews/action/update/$mview->mview_id"),
  426. $mview->name,
  427. $update,
  428. $mview->status,
  429. $mview->comment,
  430. l(t('Delete'), "admin/tripal/mviews/action/delete/$mview->mview_id"),
  431. );
  432. }
  433. $rows[] = array(
  434. 'data' => array(
  435. array('data' => l(t('Create a new materialized view.'), "admin/tripal/mviews/new"),
  436. 'colspan' => 6),
  437. )
  438. );
  439. $page = theme('table', $header, $rows);
  440. return $page;
  441. }
  442. /**
  443. * A Form to Create/Edit a Materialized View
  444. *
  445. * @param $form_state
  446. * The current state of the form (Form API)
  447. * @param $mview_id
  448. * The unique ID of the Materialized View to Edit or NULL if creating a new materialized view
  449. *
  450. * @return
  451. * A form array (Form API)
  452. *
  453. * @ingroup tripal_core
  454. */
  455. function tripal_mviews_form(&$form_state = NULL, $mview_id = NULL) {
  456. if (!$mview_id) {
  457. $action = 'Add';
  458. }
  459. else {
  460. $action = 'Edit';
  461. }
  462. // get this requested view
  463. if (strcmp($action, 'Edit')==0) {
  464. $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = %d ";
  465. $mview = db_fetch_object(db_query($sql, $mview_id));
  466. // set the default values. If there is a value set in the
  467. // form_state then let's use that, otherwise, we'll pull
  468. // the values from the database
  469. $default_name = $form_state['values']['name'];
  470. $default_mv_table = $form_state['values']['mv_table'];
  471. $default_mv_specs = $form_state['values']['mv_specs'];
  472. $default_indexed = $form_state['values']['indexed'];
  473. $default_mvquery = $form_state['values']['mvquery'];
  474. $default_special_index = $form_state['values']['special_index'];
  475. $default_comment = $form_state['values']['cpmment'];
  476. if (!$default_name) {
  477. $default_name = $mview->name;
  478. }
  479. if (!$default_mv_table) {
  480. $default_mv_table = $mview->mv_table;
  481. }
  482. if (!$default_mv_specs) {
  483. $default_mv_specs = $mview->mv_specs;
  484. }
  485. if (!$default_indexed) {
  486. $default_indexed = $mview->indexed;
  487. }
  488. if (!$default_mvquery) {
  489. $default_mvquery = $mview->query;
  490. }
  491. if (!$default_special_index) {
  492. $default_special_index = $mview->special_index;
  493. }
  494. if (!$default_comment) {
  495. $default_comment = $mview->comment;
  496. }
  497. if (!$default_schema) {
  498. $default_schema = $mview->mv_schema;
  499. }
  500. // the mv_table column of the tripal_mviews table always has the table
  501. // name even if it is a custom table. However, for the sake of the form,
  502. // we do not want this to show up as the mv_table is needed for the
  503. // traditional style input. We'll blank it out if we have a custom
  504. // table and it will get reset in the submit function using the
  505. // 'table' value from the schema array
  506. if ($default_schema) {
  507. $default_mv_table = '';
  508. }
  509. // set which fieldset is collapsed
  510. $schema_collapsed = 0;
  511. $traditional_collapsed = 1;
  512. if (!$default_schema) {
  513. $schema_collapsed = 1;
  514. $traditional_collapsed = 0;
  515. }
  516. }
  517. // Build the form
  518. $form['action'] = array(
  519. '#type' => 'value',
  520. '#value' => $action
  521. );
  522. $form['mview_id'] = array(
  523. '#type' => 'value',
  524. '#value' => $mview_id
  525. );
  526. $form['name']= array(
  527. '#type' => 'textfield',
  528. '#title' => t('View Name'),
  529. '#description' => t('Please enter the name for this materialized view.'),
  530. '#required' => TRUE,
  531. '#default_value' => $default_name,
  532. );
  533. $form['comment']= array(
  534. '#type' => 'textarea',
  535. '#title' => t('MView Description'),
  536. '#description' => t('Optional. Please provide a description of the purpose for this materialized vieww.'),
  537. '#required' => FALSE,
  538. '#default_value' => $default_comment,
  539. );
  540. // add a fieldset for the Drupal Schema API
  541. $form['schema'] = array(
  542. '#type' => 'fieldset',
  543. '#title' => 'Drupal Schema API Setup',
  544. '#description' => t('Use the Drupal Schema API array to describe a table. The benefit is that it '.
  545. 'can be fully integrated with Tripal Views. Tripal supports an extended '.
  546. 'array format to allow for descriptoin of foreign key relationships.'),
  547. '#collapsible' => 1,
  548. '#collapsed' => $schema_collapsed ,
  549. );
  550. $form['schema']['schema']= array(
  551. '#type' => 'textarea',
  552. '#title' => t('Schema Array'),
  553. '#description' => t('Please enter the Drupal Schema API compatible array that defines the table.'),
  554. '#required' => FALSE,
  555. '#default_value' => $default_schema,
  556. '#rows' => 25,
  557. );
  558. // add a fieldset for the Original Table Description fields
  559. $form['traditional'] = array(
  560. '#type' => 'fieldset',
  561. '#title' => 'Traditional MViews Setup',
  562. '#description' => t('Traidtionally with Tripal MViews were created by specifying PostgreSQL style '.
  563. 'column types. This method can be used but is deprecated in favor of the '.
  564. 'newer Drupal schema API method provided above.'),
  565. '#collapsible' => 1,
  566. '#collapsed' => $traditional_collapsed,
  567. );
  568. $form['traditional']['mv_table']= array(
  569. '#type' => 'textfield',
  570. '#title' => t('Table Name'),
  571. '#description' => t('Please enter the table name that this view will generate in the database. You can use the schema and table name for querying the view'),
  572. '#required' => FALSE,
  573. '#default_value' => $default_mv_table,
  574. );
  575. $form['traditional']['mv_specs']= array(
  576. '#type' => 'textarea',
  577. '#title' => t('Table Definition'),
  578. '#description' => t('Please enter the field definitions for this view. Each field should be separated by a comma or enter each field definition on each line.'),
  579. '#required' => FALSE,
  580. '#default_value' => $default_mv_specs,
  581. );
  582. $form['traditional']['indexed']= array(
  583. '#type' => 'textarea',
  584. '#title' => t('Indexed Fields'),
  585. '#description' => t('Please enter the field names (as provided in the table definition above) that will be indexed for this view. Separate by a comma or enter each field on a new line.'),
  586. '#required' => FALSE,
  587. '#default_value' => $default_indexed,
  588. );
  589. /**
  590. $form['traditional']['special_index']= array(
  591. '#type' => 'textarea',
  592. '#title' => t('View Name'),
  593. '#description' => t('Please enter the name for this materialized view.'),
  594. '#required' => TRUE,
  595. '#default_value' => $default_special_index,
  596. );
  597. */
  598. $form['mvquery']= array(
  599. '#type' => 'textarea',
  600. '#title' => t('Query'),
  601. '#description' => t('Please enter the SQL statement used to populate the table.'),
  602. '#required' => TRUE,
  603. '#default_value' => $default_mvquery,
  604. '#rows' => 25,
  605. );
  606. if ($action == 'Edit') {
  607. $value = 'Save';
  608. }
  609. if ($action == 'Add') {
  610. $value = 'Add';
  611. }
  612. $form['submit'] = array(
  613. '#type' => 'submit',
  614. '#value' => t($value),
  615. '#weight' => 9,
  616. '#executes_submit_callback' => TRUE,
  617. );
  618. $form['#redirect'] = 'admin/tripal/mviews';
  619. return $form;
  620. }
  621. /**
  622. * Validate the Create/Edit Materialized View Form
  623. * Implements hook_form_validate().
  624. *
  625. * @ingroup tripal_core
  626. */
  627. function tripal_mviews_form_validate($form, &$form_state) {
  628. $action = $form_state['values']['action'];
  629. $mview_id = $form_state['values']['mview_id'];
  630. $name = $form_state['values']['name'];
  631. $mv_table = $form_state['values']['mv_table'];
  632. $mv_specs = $form_state['values']['mv_specs'];
  633. $indexed = $form_state['values']['indexed'];
  634. $query = $form_state['values']['mvquery'];
  635. $special_index = $form_state['values']['special_index'];
  636. $comment = $form_state['values']['comment'];
  637. $schema = $form_state['values']['schema'];
  638. if ($schema and ($mv_table or $mv_specs or $indexed or $special_index)) {
  639. form_set_error($form_state['values']['schema'],
  640. t('You can create an MView using the Drupal Schema API method or the '.
  641. 'traditional method but not both.'));
  642. }
  643. if (!$schema) {
  644. if (!$mv_specs) {
  645. form_set_error($form_state['values']['mv_specs'],
  646. t('The Table Definition field is required.'));
  647. }
  648. if (!$mv_table) {
  649. form_set_error($form_state['values']['mv_table'],
  650. t('The Table Name field is required.'));
  651. }
  652. }
  653. // make sure the array is valid
  654. if ($schema) {
  655. $success = eval("\$schema_array = $schema;");
  656. if ($success === FALSE) {
  657. $error = error_get_last();
  658. form_set_error($form_state['values']['schema'],
  659. t("The schema array is improperly formatted. Parse Error : " . $error["message"]));
  660. }
  661. if (!array_key_exists('table', $schema_array)) {
  662. form_set_error($form_state['values']['schema'],
  663. t("The schema array must have key named 'table'"));
  664. }
  665. // TODO: add in more validation checks of the array to help the user
  666. }
  667. }
  668. /**
  669. * Submit the Create/Edit Materialized View Form
  670. * Implements hook_form_submit().
  671. *
  672. * @ingroup tripal_core
  673. */
  674. function tripal_mviews_form_submit($form, &$form_state) {
  675. $ret = array();
  676. $action = $form_state['values']['action'];
  677. $mview_id = $form_state['values']['mview_id'];
  678. $name = $form_state['values']['name'];
  679. $mv_table = $form_state['values']['mv_table'];
  680. $mv_specs = $form_state['values']['mv_specs'];
  681. $indexed = $form_state['values']['indexed'];
  682. $query = $form_state['values']['mvquery'];
  683. $special_index = $form_state['values']['special_index'];
  684. $comment = $form_state['values']['comment'];
  685. $schema = $form_state['values']['schema'];
  686. if (strcmp($action, 'Edit') == 0) {
  687. tripal_edit_mview($mview_id, $name, 'tripal_core', $mv_table, $mv_specs,
  688. $indexed, $query, $special_index, $comment, $schema);
  689. }
  690. elseif (strcmp($action, 'Add') == 0) {
  691. tripal_add_mview($name, 'tripal_core', $mv_table, $mv_specs,
  692. $indexed, $query, $special_index, $comment, $schema);
  693. }
  694. else {
  695. drupal_set_message(t("No action performed."));
  696. }
  697. return '';
  698. }