tripal_core.chado_install.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. <?php
  2. /**
  3. * @file
  4. * Functions to install chado schema through Drupal
  5. */
  6. /**
  7. * Load Chado Schema Form
  8. *
  9. * @ingroup tripal_core
  10. */
  11. function tripal_core_chado_load_form() {
  12. // we want to force the version of Chado to be set properly
  13. $real_version = chado_get_version(TRUE);
  14. // get the effective version. Pass true as second argument
  15. // to warn the user if the current version is not compatible
  16. $version = chado_get_version(FALSE, TRUE);
  17. $form['current_version'] = array(
  18. '#type' => 'item',
  19. '#title' => t("Current installed version of Chado:"),
  20. '#description' => $real_version,
  21. );
  22. $form['action_to_do'] = array(
  23. '#type' => 'radios',
  24. '#title' => 'Installation/Upgrade Action',
  25. '#options' => array(
  26. 'Install Chado v1.3' => t('New Install of Chado v1.3 (erases all existing Chado data if Chado already exists)'),
  27. 'Upgrade Chado v1.2 to v1.3' => t('Upgrade existing Chado v1.2 to v1.3 (no data is lost)'),
  28. 'Install Chado v1.2' => t('New Install of Chado v1.2 (erases all existing Chado data if Chado already exists)'),
  29. 'Upgrade Chado v1.11 to v1.2' => t('Upgrade existing Chado v1.11 to v1.2 (no data is lost)'),
  30. 'Install Chado v1.11' => t('New Install of Chado v1.11 (erases all existing Chado data if Chado already exists)'),
  31. ),
  32. '#description' => t('Select an action to perform. If you want to install Chado all other Tripal modules must not be installed.'),
  33. '#required' => TRUE,
  34. );
  35. $form['warning'] = array(
  36. '#markup' => "<div><font color=\"red\">WARNING:</font>" . t('A new install of
  37. Chado will remove and recreate the Chado database if it already exists.') . '</div>',
  38. );
  39. $form['button'] = array(
  40. '#type' => 'submit',
  41. '#value' => t('Install/Upgrade Chado'),
  42. );
  43. return $form;
  44. }
  45. function tripal_core_chado_load_form_validate($form, &$form_state) {
  46. // We do not want to allow re-installation of Chado if other
  47. // Tripal modules are installed. This is because the install files
  48. // of those modules may add content to Chado and reinstalling Chado
  49. // removes that content which may break the modules.
  50. if ($form_state['values']['action_to_do'] == "Install Chado v1.3" or
  51. $form_state['values']['action_to_do'] == "Install Chado v1.2" or
  52. $form_state['values']['action_to_do'] == "Install Chado v1.11") {
  53. $modules = system_get_info('module');
  54. // The tripal_views module should not be included as it's a rquired
  55. // dependency of tripal_core
  56. unset($modules['tripal_views']);
  57. $list = array();
  58. foreach ($modules as $mname => $module) {
  59. if (array_key_exists('dependencies', $module) and in_array('tripal_core', $module['dependencies'])) {
  60. $list[] = $module['name'] . " ($mname)";
  61. }
  62. }
  63. if (count($list) > 0) {
  64. form_set_error("action_to_do", "Chado cannot be installed while other Tripal modules
  65. are enabled. You must fully uninstall the following modules if you
  66. would like to install or re-install chado.<br>" .
  67. implode("<br>", $list));
  68. }
  69. }
  70. if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.11 to v1.2") {
  71. // Make sure we are already not at v1.2
  72. $real_version = chado_get_version(TRUE);
  73. if ($real_version == "1.2") {
  74. form_set_error("action_to_do", "You are already at v1.2. There is no need to upgrade.");
  75. }
  76. }
  77. if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.2 to v1.3") {
  78. // Make sure we are already not at v1.3
  79. $real_version = chado_get_version(TRUE);
  80. if ($real_version == "1.3") {
  81. form_set_error("action_to_do", "You are already at v1.3. There is no need to upgrade.");
  82. }
  83. }
  84. }
  85. /**
  86. * Submit Load Chado Schema Form
  87. *
  88. * @ingroup tripal_core
  89. */
  90. function tripal_core_chado_load_form_submit($form, &$form_state) {
  91. global $user;
  92. $action_to_do = trim($form_state['values']['action_to_do']);
  93. $args = array($action_to_do);
  94. tripal_add_job($action_to_do, 'tripal_core',
  95. 'tripal_core_install_chado', $args, $user->uid);
  96. }
  97. /**
  98. * Install Chado Schema
  99. *
  100. * @ingroup tripal_core
  101. */
  102. function tripal_core_install_chado($action) {
  103. $vsql = "
  104. INSERT INTO {chadoprop} (type_id, value)
  105. VALUES (
  106. (SELECT cvterm_id
  107. FROM {cvterm} CVT
  108. INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
  109. WHERE CV.name = 'chado_properties' AND CVT.name = 'version'),
  110. :version)
  111. ";
  112. try {
  113. if ($action == 'Install Chado v1.3') {
  114. tripal_core_install_chado_1_3();
  115. chado_query($vsql, array(':version' => '1.3'));
  116. }
  117. elseif ($action == 'Upgrade Chado v1.2 to v1.3') {
  118. tripal_core_upgrade_chado_1_2_to_1_3();
  119. chado_query($vsql, array(':version' => '1.3'));
  120. }
  121. elseif ($action == 'Install Chado v1.2') {
  122. tripal_core_install_chado_1_2();
  123. chado_query($vsql, array(':version' => '1.2'));
  124. }
  125. elseif ($action == 'Upgrade Chado v1.11 to v1.2') {
  126. tripal_core_upgrade_chado_1_11_to_1_2();
  127. chado_query($vsql, array(':version' => '1.2'));
  128. }
  129. elseif ($action == 'Install Chado v1.11') {
  130. tripal_core_install_chado_1_11();
  131. }
  132. }
  133. catch (Exception $e) {
  134. tripal_chado_install_done();
  135. tripal_log($e->getMessage(), 'error');
  136. return FALSE;
  137. }
  138. return TRUE;
  139. }
  140. /**
  141. * Installs Chado v1.3.
  142. */
  143. function tripal_core_install_chado_1_3() {
  144. // Get the path to the schema and init SQL files.
  145. $schema_file = drupal_get_path('module', 'tripal_core') .
  146. '/chado_schema/default_schema-1.3.sql';
  147. $init_file = drupal_get_path('module', 'tripal_core') .
  148. '/chado_schema/initialize-1.3.sql';
  149. // Erase the Chado schema if it exists and perform the install.
  150. if (tripal_core_reset_chado_schema()) {
  151. $success = tripal_core_install_sql($schema_file);
  152. if ($success) {
  153. print "Install of Chado v1.3 (Step 1 of 2) Successful!\n";
  154. }
  155. else {
  156. throw new Exception("Installation (Step 1 of 2) Problems! Please check output above for errors.");
  157. }
  158. $success = tripal_core_install_sql($init_file);
  159. if ($success) {
  160. print "Install of Chado v1.3 (Step 2 of 2) Successful.\nInstallation Complete\n";
  161. }
  162. else {
  163. throw new Exception("Installation (Step 2 of 2) Problems! Please check output above for errors.");
  164. }
  165. }
  166. else {
  167. throw new Exception("ERROR: cannot install chado. Please check database permissions");
  168. }
  169. }
  170. /**
  171. * Installs Chado v1.2.
  172. */
  173. function tripal_core_install_chado_1_2() {
  174. // Get the path to the schema and init SQL files.
  175. $schema_file = drupal_get_path('module', 'tripal_core') .
  176. '/chado_schema/default_schema-1.2.sql';
  177. $init_file = drupal_get_path('module', 'tripal_core') .
  178. '/chado_schema/initialize-1.2.sql';
  179. // Erase the Chado schema if it exists and perform the install.
  180. if (tripal_core_reset_chado_schema()) {
  181. $success = tripal_core_install_sql($schema_file);
  182. if ($success) {
  183. print "Install of Chado v1.2 (Step 1 of 2) Successful!\n";
  184. }
  185. else {
  186. throw new Exception("Installation (Step 1 of 2) Problems! Please check output above for errors.");
  187. }
  188. $success = tripal_core_install_sql($init_file);
  189. if ($success) {
  190. print "Install of Chado v1.2 (Step 2 of 2) Successful.\nInstallation Complete\n";
  191. }
  192. else {
  193. throw new Exception("Installation (Step 2 of 2) Problems! Please check output above for errors.");
  194. }
  195. }
  196. else {
  197. throw new Exception("ERROR: cannot install chado. Please check database permissions");
  198. }
  199. }
  200. /**
  201. *
  202. */
  203. function tripal_core_install_chado_1_11() {
  204. // Get the path to the schema and init SQL files.
  205. $schema_file = drupal_get_path('module', 'tripal_core') .
  206. '/chado_schema/default_schema-1.11.sql';
  207. $init_file = drupal_get_path('module', 'tripal_core') .
  208. '/chado_schema/initialize-1.11.sql';
  209. // Erase the Chado schema if it exists and perform the install.
  210. if (tripal_core_reset_chado_schema()) {
  211. $success = tripal_core_install_sql($schema_file);
  212. if ($success) {
  213. print "Install of Chado v1.11 (Step 1 of 2) Successful!\n";
  214. }
  215. else {
  216. throw new Exception("Installation (Step 1 of 2) Problems! Please check output above for errors.");
  217. }
  218. $success = tripal_core_install_sql($init_file);
  219. if ($success) {
  220. print "Install of Chado v1.11 (Step 2 of 2) Successful.\nInstallation Complete!\n";
  221. }
  222. else {
  223. throw new Exception("Installation (Step 2 of 2) Problems! Please check output above for errors.");
  224. }
  225. }
  226. else {
  227. throw new Exception("ERROR: cannot install chado. Please check database permissions");
  228. }
  229. }
  230. /**
  231. * Upgrades Chado from v1.2 to v1.3
  232. */
  233. function tripal_core_upgrade_chado_1_2_to_1_3() {
  234. // Get the path to the diff schema and upgrade SQL files.
  235. $diff_file = drupal_get_path('module', 'tripal_core') .
  236. '/chado_schema/default_schema-1.2-1.3-diff.sql';
  237. $success = tripal_core_install_sql($diff_file);
  238. if ($success) {
  239. print "Upgrade from v1.2 to v1.3 Successful!\n";
  240. }
  241. else {
  242. throw new Exception("Upgrade problems! Please check output above for errors.");
  243. }
  244. }
  245. /**
  246. * Upgrades Chado from v1.11 to v1.2
  247. */
  248. function tripal_core_upgrade_chado_1_11_to_1_2() {
  249. // Get the path to the schema diff and upgarde SQL files.
  250. $schema_file = drupal_get_path('module', 'tripal_core') .
  251. '/chado_schema/default_schema-1.11-1.2-diff.sql';
  252. $init_file = drupal_get_path('module', 'tripal_core') .
  253. '/chado_schema/upgrade-1.11-1.2.sql';
  254. $success = tripal_core_install_sql($schema_file);
  255. if ($success) {
  256. print "Upgrade from v1.11 to v1.2 (Step 1 of 2) Successful!\n";
  257. }
  258. else {
  259. throw new Exception("Upgrade (Step 1 of 2) problems! Please check output above for errors.");
  260. }
  261. $success = tripal_core_install_sql($init_file);
  262. if ($success) {
  263. print "Upgrade from v1.11 to v1.2 (Step 2 of 2) Successful.\nUpgrade Complete!\n";
  264. }
  265. else {
  266. throw new Exception("Upgrade (Step 2 of 2) problems! Please check output above for errors.");
  267. }
  268. }
  269. /**
  270. * Reset the Chado Schema
  271. * This drops the current chado and chado-related schema and re-creates it
  272. *
  273. * @ingroup tripal_core
  274. */
  275. function tripal_core_reset_chado_schema() {
  276. // drop current chado and chado-related schema
  277. if (chado_dbschema_exists('genetic_code')) {
  278. print "Dropping existing 'genetic_code' schema\n";
  279. db_query("drop schema genetic_code cascade");
  280. }
  281. if (chado_dbschema_exists('so')) {
  282. print "Dropping existing 'so' schema\n";
  283. db_query("drop schema so cascade");
  284. }
  285. if (chado_dbschema_exists('frange')) {
  286. print "Dropping existing 'frange' schema\n";
  287. db_query("drop schema frange cascade");
  288. }
  289. if (chado_dbschema_exists('chado')) {
  290. print "Dropping existing 'chado' schema\n";
  291. db_query("drop schema chado cascade");
  292. }
  293. // create the new chado schema
  294. print "Creating 'chado' schema\n";
  295. db_query("create schema chado");
  296. if (chado_dbschema_exists('chado')) {
  297. // before creating the plpgsql language let's check to make sure
  298. // it doesn't already exists
  299. $sql = "SELECT COUNT(*) FROM pg_language WHERE lanname = 'plpgsql'";
  300. $results = db_query($sql);
  301. $count = $results->fetchObject();
  302. if (!$count or $count->count == 0) {
  303. db_query("create language plpgsql");
  304. }
  305. return TRUE;
  306. }
  307. return FALSE;
  308. }
  309. /**
  310. * Execute the provided SQL
  311. *
  312. * @param $sql_file
  313. * Contains SQL statements to be executed
  314. *
  315. * @ingroup tripal_core
  316. */
  317. function tripal_core_install_sql($sql_file) {
  318. $chado_local = chado_dbschema_exists('chado');
  319. if ($chado_local) {
  320. db_query("set search_path to chado");
  321. }
  322. print "Loading $sql_file...\n";
  323. $lines = file($sql_file, FILE_SKIP_EMPTY_LINES);
  324. if (!$lines) {
  325. return 'Cannot open $schema_file';
  326. }
  327. $stack = array();
  328. $in_string = 0;
  329. $query = '';
  330. $i = 0;
  331. $success = 1;
  332. foreach ($lines as $line_num => $line) {
  333. $i++;
  334. $type = '';
  335. // find and remove comments except when inside of strings
  336. if (preg_match('/--/', $line) and !$in_string and !preg_match("/'.*?--.*?'/", $line)) {
  337. $line = preg_replace('/--.*$/', '', $line); // remove comments
  338. }
  339. if (preg_match('/\/\*.*?\*\//', $line)) {
  340. $line = preg_replace('/\/\*.*?\*\//', '', $line); // remove comments
  341. }
  342. // skip empty lines
  343. if (preg_match('/^\s*$/', $line) or strcmp($line, '')==0) {
  344. continue;
  345. }
  346. // Find SQL for new objects
  347. if (preg_match('/^\s*CREATE\s+TABLE/i', $line) and !$in_string) {
  348. $stack[] = 'table';
  349. $line = preg_replace("/public\./", "chado.", $line);
  350. }
  351. if (preg_match('/^\s*ALTER\s+TABLE/i', $line) and !$in_string) {
  352. $stack[] = 'alter table';
  353. $line = preg_replace("/public\./", "chado.", $line);
  354. }
  355. if (preg_match('/^\s*SET/i', $line) and !$in_string) {
  356. $stack[] = 'set';
  357. }
  358. if (preg_match('/^\s*CREATE\s+SCHEMA/i', $line) and !$in_string) {
  359. $stack[] = 'schema';
  360. }
  361. if (preg_match('/^\s*CREATE\s+SEQUENCE/i', $line) and !$in_string) {
  362. $stack[] = 'sequence';
  363. $line = preg_replace("/public\./", "chado.", $line);
  364. }
  365. if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*VIEW/i', $line) and !$in_string) {
  366. $stack[] = 'view';
  367. $line = preg_replace("/public\./", "chado.", $line);
  368. }
  369. if (preg_match('/^\s*COMMENT/i', $line) and !$in_string and sizeof($stack)==0) {
  370. $stack[] = 'comment';
  371. $line = preg_replace("/public\./", "chado.", $line);
  372. }
  373. if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*FUNCTION/i', $line) and !$in_string) {
  374. $stack[] = 'function';
  375. $line = preg_replace("/public\./", "chado.", $line);
  376. }
  377. if (preg_match('/^\s*CREATE\s+INDEX/i', $line) and !$in_string) {
  378. $stack[] = 'index';
  379. }
  380. if (preg_match('/^\s*INSERT\s+INTO/i', $line) and !$in_string) {
  381. $stack[] = 'insert';
  382. $line = preg_replace("/public\./", "chado.", $line);
  383. }
  384. if (preg_match('/^\s*CREATE\s+TYPE/i', $line) and !$in_string) {
  385. $stack[] = 'type';
  386. }
  387. if (preg_match('/^\s*GRANT/i', $line) and !$in_string) {
  388. $stack[] = 'grant';
  389. }
  390. if (preg_match('/^\s*CREATE\s+AGGREGATE/i', $line) and !$in_string) {
  391. $stack[] = 'aggregate';
  392. }
  393. // determine if we are in a string that spans a line
  394. $matches = preg_match_all("/[']/i", $line, $temp);
  395. $in_string = $in_string - ($matches % 2);
  396. $in_string = abs($in_string);
  397. // if we've reached the end of an object the pop the stack
  398. if (strcmp($stack[sizeof($stack)-1], 'table') == 0 and preg_match('/\);\s*$/', $line)) {
  399. $type = array_pop($stack);
  400. }
  401. if (strcmp($stack[sizeof($stack)-1], 'alter table') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  402. $type = array_pop($stack);
  403. }
  404. if (strcmp($stack[sizeof($stack)-1], 'set') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  405. $type = array_pop($stack);
  406. }
  407. if (strcmp($stack[sizeof($stack)-1], 'schema') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  408. $type = array_pop($stack);
  409. }
  410. if (strcmp($stack[sizeof($stack)-1], 'sequence') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  411. $type = array_pop($stack);
  412. }
  413. if (strcmp($stack[sizeof($stack)-1], 'view') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  414. $type = array_pop($stack);
  415. }
  416. if (strcmp($stack[sizeof($stack)-1], 'comment') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  417. $type = array_pop($stack);
  418. }
  419. if (strcmp($stack[sizeof($stack)-1], 'function') == 0 and preg_match("/LANGUAGE.*?;\s+$/i", $line)) {
  420. $type = array_pop($stack);
  421. }
  422. if (strcmp($stack[sizeof($stack)-1], 'index') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  423. $type = array_pop($stack);
  424. }
  425. if (strcmp($stack[sizeof($stack)-1], 'insert') == 0 and preg_match('/\);\s*$/', $line)) {
  426. $type = array_pop($stack);
  427. }
  428. if (strcmp($stack[sizeof($stack)-1], 'type') == 0 and preg_match('/\);\s*$/', $line)) {
  429. $type = array_pop($stack);
  430. }
  431. if (strcmp($stack[sizeof($stack)-1], 'grant') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  432. $type = array_pop($stack);
  433. }
  434. if (strcmp($stack[sizeof($stack)-1], 'aggregate') == 0 and preg_match('/\);\s*$/', $line)) {
  435. $type = array_pop($stack);
  436. }
  437. // if we're in a recognized SQL statement then let's keep track of lines
  438. if ($type or sizeof($stack) > 0) {
  439. $query .= "$line";
  440. }
  441. else {
  442. print "UNHANDLED $i, $in_string: $line";
  443. tripal_core_chado_install_done();
  444. return FALSE;
  445. }
  446. if (preg_match_all("/\n/", $query, $temp) > 100) {
  447. print "SQL query is too long. Terminating:\n$query\n";
  448. tripal_core_chado_install_done();
  449. return FALSE;
  450. }
  451. if ($type and sizeof($stack) == 0) {
  452. //print "Adding $type: line $i\n";
  453. // rewrite the set search_path to make 'public' be 'chado', but only if the
  454. // chado schema exists
  455. if (strcmp($type, 'set') == 0 and $chado_local) {
  456. $query = preg_replace("/public/m", "chado", $query);
  457. }
  458. // execute the statement
  459. $result = db_query($query);
  460. if (!$result) {
  461. $error = pg_last_error();
  462. print "FAILED. Line $i, $in_string\n$error:\n$query\n\n";
  463. tripal_core_chado_install_done();
  464. $success = 0;
  465. return $success;
  466. }
  467. $query = '';
  468. }
  469. }
  470. tripal_core_chado_install_done();
  471. return $success;
  472. }
  473. /**
  474. * Finish the Chado Schema Installation
  475. *
  476. * @ingroup tripal_core
  477. */
  478. function tripal_core_chado_install_done() {
  479. db_query("set search_path to default");
  480. }