mviews.php 25 KB

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