tripal_chado.install.inc 16 KB

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