chado_install.inc 13 KB

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