tripal_core.chado_install.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  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_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.2' => t('New Install of Chado v1.2 (erases all existing Chado data if Chado already exists)'),
  27. 'Upgrade Chado v1.11 to v1.2' => t('Upgrade existing Chado v1.11 to v1.2 (no data is lost)'),
  28. 'Install Chado v1.11' => t('New Install of Chado v1.11 (erases all existing Chado data if Chado already exists)')
  29. ),
  30. '#description' => t('Select an action to perform. If you want to install Chado all other Tripal modules must not be installed.'),
  31. '#required' => TRUE,
  32. );
  33. $form['warning'] = array(
  34. '#markup' => "<div><font color=\"red\">WARNING:</font>" . t('A new install of
  35. Chado will remove and recreate the Chado database if it already exists.') . '</div>',
  36. );
  37. $form['button'] = array(
  38. '#type' => 'submit',
  39. '#value' => t('Install/Upgrade Chado'),
  40. );
  41. return $form;
  42. }
  43. function tripal_chado_chado_load_form_validate($form, &$form_state) {
  44. // We do not want to allow re-installation of Chado if other
  45. // Tripal modules are installed. This is because the install files
  46. // of those modules may add content to Chado and reinstalling Chado
  47. // removes that content which may break the modules.
  48. if ($form_state['values']['action_to_do'] == "Install Chado v1.2" or
  49. $form_state['values']['action_to_do'] == "Install Chado v1.11") {
  50. $modules = system_get_info('module');
  51. $list = array();
  52. foreach ($modules as $mname => $module) {
  53. if (array_key_exists('dependencies', $module) and in_array('tripal_chado', $module['dependencies'])) {
  54. $list[] = $module['name'] . " ($mname)";
  55. }
  56. }
  57. if (count($list) > 0) {
  58. form_set_error("action_to_do", "Chado cannot be installed while other Tripal modules
  59. are enabled. You must fully uninstall the following modules if you
  60. would like to install or re-install chado.<br>" .
  61. implode("<br>", $list));
  62. }
  63. }
  64. if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.11 to v1.2") {
  65. // Make sure we are already not at v1.2
  66. $real_version = chado_get_version(TRUE);
  67. if ($real_version == "1.2") {
  68. form_set_error("action_to_do", "You are already at v1.2. There is no need to upgrade.");
  69. }
  70. }
  71. }
  72. /**
  73. * Submit Load Chado Schema Form
  74. *
  75. * @ingroup tripal_chado
  76. */
  77. function tripal_chado_chado_load_form_submit($form, &$form_state) {
  78. global $user;
  79. $action_to_do = trim($form_state['values']['action_to_do']);
  80. $args = array($action_to_do);
  81. tripal_add_job($action_to_do, 'tripal_chado', 'tripal_chado_install_chado', $args, $user->uid);
  82. }
  83. /**
  84. * Install Chado Schema
  85. *
  86. * @ingroup tripal_chado
  87. */
  88. function tripal_chado_install_chado($action) {
  89. $vsql = "
  90. INSERT INTO {chadoprop} (type_id, value)
  91. VALUES (
  92. (SELECT cvterm_id
  93. FROM {cvterm} CVT
  94. INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
  95. WHERE CV.name = 'chado_properties' AND CVT.name = 'version'),
  96. :version)
  97. ";
  98. if ($action == 'Install Chado v1.2') {
  99. $schema_file = drupal_get_path('module', 'tripal_chado') . '/chado_schema/default_schema-1.2.sql';
  100. $init_file = drupal_get_path('module', 'tripal_chado') . '/chado_schema/initialize-1.2.sql';
  101. if (tripal_chado_reset_chado_schema()) {
  102. $success = tripal_chado_install_sql($schema_file);
  103. if ($success) {
  104. print "Install of Chado v1.2 (Step 1 of 2) Successful!\n";
  105. }
  106. else {
  107. print "Installation (Step 1 of 2) Problems! Please check output above for errors.\n";
  108. exit;
  109. }
  110. $success = tripal_chado_install_sql($init_file);
  111. if ($success) {
  112. print "Install of Chado v1.2 (Step 2 of 2) Successful.\nInstallation Complete\n";
  113. }
  114. else {
  115. print "Installation (Step 2 of 2) Problems! Please check output above for errors.\n";
  116. exit;
  117. }
  118. chado_query($vsql, array(':version' => '1.2')); # set the version
  119. }
  120. else {
  121. print "ERROR: cannot install chado. Please check database permissions\n";
  122. exit;
  123. }
  124. }
  125. elseif ($action == 'Upgrade Chado v1.11 to v1.2') {
  126. $schema_file = drupal_get_path('module', 'tripal_chado') . '/chado_schema/default_schema-1.11-1.2-diff.sql';
  127. $init_file = drupal_get_path('module', 'tripal_chado') . '/chado_schema/upgrade-1.11-1.2.sql';
  128. $success = tripal_chado_install_sql($schema_file);
  129. if ($success) {
  130. print "Upgrade from v1.11 to v1.2 (Step 1 of 2) Successful!\n";
  131. }
  132. else {
  133. print "Upgrade (Step 1 of 2) problems! Please check output above for errors.\n";
  134. exit;
  135. }
  136. $success = tripal_chado_install_sql($init_file);
  137. if ($success) {
  138. print "Upgrade from v1.11 to v1.2 (Step 2 of 2) Successful.\nUpgrade Complete!\n";
  139. }
  140. else {
  141. print "Upgrade (Step 2 of 2) problems! Please check output above for errors.\n";
  142. exit;
  143. }
  144. chado_query($vsql, array(':version' => '1.2')); # set the version
  145. }
  146. elseif ($action == 'Install Chado v1.11') {
  147. $schema_file = drupal_get_path('module', 'tripal_chado') . '/chado_schema/default_schema-1.11.sql';
  148. $init_file = drupal_get_path('module', 'tripal_chado') . '/chado_schema/initialize-1.11.sql';
  149. if (tripal_chado_reset_chado_schema()) {
  150. $success = tripal_chado_install_sql($schema_file);
  151. if ($success) {
  152. print "Install of Chado v1.11 (Step 1 of 2) Successful!\n";
  153. }
  154. else {
  155. print "Installation (Step 1 of 2) Problems! Please check output above for errors.\n";
  156. exit;
  157. }
  158. $success = tripal_chado_install_sql($init_file);
  159. if ($success) {
  160. print "Install of Chado v1.11 (Step 2 of 2) Successful.\nInstallation Complete!\n";
  161. }
  162. else {
  163. print "Installation (Step 2 of 2) Problems! Please check output above for errors.\n";
  164. exit;
  165. }
  166. }
  167. else {
  168. print "ERROR: cannot install chado. Please check database permissions\n";
  169. exit;
  170. }
  171. }
  172. }
  173. /**
  174. * Reset the Chado Schema
  175. * This drops the current chado and chado-related schema and re-creates it
  176. *
  177. * @ingroup tripal_chado
  178. */
  179. function tripal_chado_reset_chado_schema() {
  180. // drop current chado and chado-related schema
  181. if (chado_dbschema_exists('genetic_code')) {
  182. print "Dropping existing 'genetic_code' schema\n";
  183. db_query("drop schema genetic_code cascade");
  184. }
  185. if (chado_dbschema_exists('so')) {
  186. print "Dropping existing 'so' schema\n";
  187. db_query("drop schema so cascade");
  188. }
  189. if (chado_dbschema_exists('frange')) {
  190. print "Dropping existing 'frange' schema\n";
  191. db_query("drop schema frange cascade");
  192. }
  193. if (chado_dbschema_exists('chado')) {
  194. print "Dropping existing 'chado' schema\n";
  195. db_query("drop schema chado cascade");
  196. }
  197. // create the new chado schema
  198. print "Creating 'chado' schema\n";
  199. db_query("create schema chado");
  200. if (chado_dbschema_exists('chado')) {
  201. // before creating the plpgsql language let's check to make sure
  202. // it doesn't already exists
  203. $sql = "SELECT COUNT(*) FROM pg_language WHERE lanname = 'plpgsql'";
  204. $results = db_query($sql);
  205. $count = $results->fetchObject();
  206. if (!$count or $count->count == 0) {
  207. db_query("create language plpgsql");
  208. }
  209. return TRUE;
  210. }
  211. return FALSE;
  212. }
  213. /**
  214. * Execute the provided SQL
  215. *
  216. * @param $sql_file
  217. * Contains SQL statements to be executed
  218. *
  219. * @ingroup tripal_chado
  220. */
  221. function tripal_chado_install_sql($sql_file) {
  222. $chado_local = chado_dbschema_exists('chado');
  223. if ($chado_local) {
  224. db_query("set search_path to chado");
  225. }
  226. print "Loading $sql_file...\n";
  227. $lines = file($sql_file, FILE_SKIP_EMPTY_LINES);
  228. if (!$lines) {
  229. return 'Cannot open $schema_file';
  230. }
  231. $stack = array();
  232. $in_string = 0;
  233. $query = '';
  234. $i = 0;
  235. $success = 1;
  236. foreach ($lines as $line_num => $line) {
  237. $i++;
  238. $type = '';
  239. // find and remove comments except when inside of strings
  240. if (preg_match('/--/', $line) and !$in_string and !preg_match("/'.*?--.*?'/", $line)) {
  241. $line = preg_replace('/--.*$/', '', $line); // remove comments
  242. }
  243. if (preg_match('/\/\*.*?\*\//', $line)) {
  244. $line = preg_replace('/\/\*.*?\*\//', '', $line); // remove comments
  245. }
  246. // skip empty lines
  247. if (preg_match('/^\s*$/', $line) or strcmp($line, '')==0) {
  248. continue;
  249. }
  250. // Find SQL for new objects
  251. if (preg_match('/^\s*CREATE\s+TABLE/i', $line) and !$in_string) {
  252. $stack[] = 'table';
  253. $line = preg_replace("/public\./", "chado.", $line);
  254. }
  255. if (preg_match('/^\s*ALTER\s+TABLE/i', $line) and !$in_string) {
  256. $stack[] = 'alter table';
  257. $line = preg_replace("/public\./", "chado.", $line);
  258. }
  259. if (preg_match('/^\s*SET/i', $line) and !$in_string) {
  260. $stack[] = 'set';
  261. }
  262. if (preg_match('/^\s*CREATE\s+SCHEMA/i', $line) and !$in_string) {
  263. $stack[] = 'schema';
  264. }
  265. if (preg_match('/^\s*CREATE\s+SEQUENCE/i', $line) and !$in_string) {
  266. $stack[] = 'sequence';
  267. $line = preg_replace("/public\./", "chado.", $line);
  268. }
  269. if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*VIEW/i', $line) and !$in_string) {
  270. $stack[] = 'view';
  271. $line = preg_replace("/public\./", "chado.", $line);
  272. }
  273. if (preg_match('/^\s*COMMENT/i', $line) and !$in_string and sizeof($stack)==0) {
  274. $stack[] = 'comment';
  275. $line = preg_replace("/public\./", "chado.", $line);
  276. }
  277. if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*FUNCTION/i', $line) and !$in_string) {
  278. $stack[] = 'function';
  279. $line = preg_replace("/public\./", "chado.", $line);
  280. }
  281. if (preg_match('/^\s*CREATE\s+INDEX/i', $line) and !$in_string) {
  282. $stack[] = 'index';
  283. }
  284. if (preg_match('/^\s*INSERT\s+INTO/i', $line) and !$in_string) {
  285. $stack[] = 'insert';
  286. $line = preg_replace("/public\./", "chado.", $line);
  287. }
  288. if (preg_match('/^\s*CREATE\s+TYPE/i', $line) and !$in_string) {
  289. $stack[] = 'type';
  290. }
  291. if (preg_match('/^\s*GRANT/i', $line) and !$in_string) {
  292. $stack[] = 'grant';
  293. }
  294. if (preg_match('/^\s*CREATE\s+AGGREGATE/i', $line) and !$in_string) {
  295. $stack[] = 'aggregate';
  296. }
  297. // determine if we are in a string that spans a line
  298. $matches = preg_match_all("/[']/i", $line, $temp);
  299. $in_string = $in_string - ($matches % 2);
  300. $in_string = abs($in_string);
  301. // if we've reached the end of an object the pop the stack
  302. if (strcmp($stack[sizeof($stack)-1], 'table') == 0 and preg_match('/\);\s*$/', $line)) {
  303. $type = array_pop($stack);
  304. }
  305. if (strcmp($stack[sizeof($stack)-1], 'alter table') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  306. $type = array_pop($stack);
  307. }
  308. if (strcmp($stack[sizeof($stack)-1], 'set') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  309. $type = array_pop($stack);
  310. }
  311. if (strcmp($stack[sizeof($stack)-1], 'schema') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  312. $type = array_pop($stack);
  313. }
  314. if (strcmp($stack[sizeof($stack)-1], 'sequence') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  315. $type = array_pop($stack);
  316. }
  317. if (strcmp($stack[sizeof($stack)-1], 'view') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  318. $type = array_pop($stack);
  319. }
  320. if (strcmp($stack[sizeof($stack)-1], 'comment') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  321. $type = array_pop($stack);
  322. }
  323. if (strcmp($stack[sizeof($stack)-1], 'function') == 0 and preg_match("/LANGUAGE.*?;\s+$/i", $line)) {
  324. $type = array_pop($stack);
  325. }
  326. if (strcmp($stack[sizeof($stack)-1], 'index') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  327. $type = array_pop($stack);
  328. }
  329. if (strcmp($stack[sizeof($stack)-1], 'insert') == 0 and preg_match('/\);\s*$/', $line)) {
  330. $type = array_pop($stack);
  331. }
  332. if (strcmp($stack[sizeof($stack)-1], 'type') == 0 and preg_match('/\);\s*$/', $line)) {
  333. $type = array_pop($stack);
  334. }
  335. if (strcmp($stack[sizeof($stack)-1], 'grant') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  336. $type = array_pop($stack);
  337. }
  338. if (strcmp($stack[sizeof($stack)-1], 'aggregate') == 0 and preg_match('/\);\s*$/', $line)) {
  339. $type = array_pop($stack);
  340. }
  341. // if we're in a recognized SQL statement then let's keep track of lines
  342. if ($type or sizeof($stack) > 0) {
  343. $query .= "$line";
  344. }
  345. else {
  346. print "UNHANDLED $i, $in_string: $line";
  347. tripal_chado_chado_install_done();
  348. return FALSE;
  349. }
  350. if (preg_match_all("/\n/", $query, $temp) > 100) {
  351. print "SQL query is too long. Terminating:\n$query\n";
  352. tripal_chado_chado_install_done();
  353. return FALSE;
  354. }
  355. if ($type and sizeof($stack) == 0) {
  356. //print "Adding $type: line $i\n";
  357. // rewrite the set search_path to make 'public' be 'chado', but only if the
  358. // chado schema exists
  359. if (strcmp($type, 'set') == 0 and $chado_local) {
  360. $query = preg_replace("/public/m", "chado", $query);
  361. }
  362. // execute the statement
  363. $result = db_query($query);
  364. if (!$result) {
  365. $error = pg_last_error();
  366. print "FAILED. Line $i, $in_string\n$error:\n$query\n\n";
  367. tripal_chado_chado_install_done();
  368. $success = 0;
  369. return $success;
  370. }
  371. $query = '';
  372. }
  373. }
  374. tripal_chado_chado_install_done();
  375. return $success;
  376. }
  377. /**
  378. * Finish the Chado Schema Installation
  379. *
  380. * @ingroup tripal_chado
  381. */
  382. function tripal_chado_chado_install_done() {
  383. db_query("set search_path to default");
  384. }