chado_install.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <?php
  2. /**
  3. * @file
  4. * Functions to install chado schema through Drupal
  5. */
  6. /**
  7. * Load Chado Schema 1.11 Form
  8. *
  9. * @ingroup tripal_core
  10. */
  11. function tripal_core_chado_v1_11_load_form() {
  12. $form['description'] = array(
  13. '#type' => 'item',
  14. '#value' => t("Click the submit button below to install Chado into the Drupal "
  15. ."database. <br /><font color=\"red\">WARNING:</font> use this only for a new "
  16. ."chado installation or reinstall completely. This will erase any data currently "
  17. ."in the chado database. If you are using chado in a database external to the "
  18. ."Drupal database with a 'chado' entry in the 'settings.php' \$db_url argument "
  19. ."then this option will intall chado but it will not be usable. The external "
  20. ."database specified in the settings.php file takes precedence."),
  21. '#weight' => 1,
  22. );
  23. $form['button'] = array(
  24. '#type' => 'submit',
  25. '#value' => t('Install Chado'),
  26. '#weight' => 2,
  27. );
  28. return $form;
  29. }
  30. /**
  31. * Submit Load Chado Schema 1.11 Form
  32. *
  33. * @ingroup tripal_core
  34. */
  35. function tripal_core_chado_v1_11_load_form_submit($form, &$form_state) {
  36. global $user;
  37. $args = array();
  38. tripal_add_job("Install Chado", 'tripal_core',
  39. 'tripal_core_install_chado', $args, $user->uid);
  40. }
  41. /**
  42. * Install Chado Schema
  43. *
  44. * @ingroup tripal_core
  45. */
  46. function tripal_core_install_chado() {
  47. $schema_file = drupal_get_path('module', 'tripal_core') . '/default_schema.sql';
  48. $init_file = drupal_get_path('module', 'tripal_core') . '/initialize.sql';
  49. if (tripal_core_reset_chado_schema()) {
  50. tripal_core_install_sql($schema_file);
  51. tripal_core_install_sql($init_file);
  52. }
  53. else {
  54. print "ERROR: cannot install chado. Please check database permissions\n";
  55. exit;
  56. }
  57. }
  58. /**
  59. * Reset the Chado Schema
  60. * This drops the current chado and chado-related schema and re-creates it
  61. *
  62. * @ingroup tripal_core
  63. */
  64. function tripal_core_reset_chado_schema() {
  65. global $active_db;
  66. // drop current chado and chado-related schema
  67. if (tripal_core_schema_exists('chado')) {
  68. print "Dropping existing 'chado' schema\n";
  69. pg_query($active_db, "drop schema chado cascade");
  70. }
  71. if (tripal_core_schema_exists('genetic_code')) {
  72. print "Dropping existing 'genetic_code' schema\n";
  73. pg_query($active_db, "drop schema genetic_code cascade");
  74. }
  75. if (tripal_core_schema_exists('so')) {
  76. print "Dropping existing 'so' schema\n";
  77. pg_query($active_db, "drop schema so cascade");
  78. }
  79. if (tripal_core_schema_exists('frange')) {
  80. print "Dropping existing 'frange' schema\n";
  81. pg_query($active_db, "drop schema frange cascade");
  82. }
  83. // create the new chado schema
  84. print "Creating 'chado' schema\n";
  85. pg_query($active_db, "create schema chado");
  86. if (tripal_core_schema_exists('chado')) {
  87. pg_query($active_db, "create language plpgsql");
  88. return TRUE;
  89. }
  90. return FALSE;
  91. }
  92. /**
  93. * Check that a given schema exists
  94. *
  95. * @param $schema
  96. * The name of the schema to check the existence of
  97. *
  98. * @return
  99. * TRUE/FALSE depending upon whether or not the schema exists
  100. *
  101. * @ingroup tripal_core
  102. */
  103. function tripal_core_schema_exists($schema) {
  104. // check that the chado schema now exists
  105. $sql = "SELECT nspname
  106. FROM pg_namespace
  107. WHERE has_schema_privilege(nspname, 'USAGE') and nspname = '%s'
  108. ORDER BY nspname";
  109. $name = db_fetch_object(db_query($sql, $schema));
  110. if (strcmp($name->nspname, $schema) != 0) {
  111. return FALSE;
  112. }
  113. return TRUE;
  114. }
  115. /**
  116. * Execute the provided SQL
  117. *
  118. * @param $sql_file
  119. * Contains SQL statements to be executed
  120. *
  121. * @ingroup tripal_core
  122. */
  123. function tripal_core_install_sql($sql_file) {
  124. global $active_db;
  125. pg_query($active_db, "set search_path to chado,public");
  126. print "Loading $sql_file...\n";
  127. $lines = file($sql_file, FILE_SKIP_EMPTY_LINES);
  128. if (!$lines) {
  129. return 'Cannot open $schema_file';
  130. }
  131. $stack = array();
  132. $in_string = 0;
  133. $query = '';
  134. $i = 0;
  135. foreach ($lines as $line_num => $line) {
  136. $i++;
  137. $type = '';
  138. // find and remove comments except when inside of strings
  139. if (preg_match('/--/', $line) and !$in_string and !preg_match("/'.*?--.*?'/", $line)) {
  140. $line = preg_replace('/--.*$/', '', $line); // remove comments
  141. }
  142. if (preg_match('/\/\*.*?\*\//', $line)) {
  143. $line = preg_replace('/\/\*.*?\*\//', '', $line); // remove comments
  144. }
  145. // skip empty lines
  146. if (preg_match('/^\s*$/', $line) or strcmp($line, '')==0) {
  147. continue;
  148. }
  149. // Find SQL for new objects
  150. if (preg_match('/^\s*CREATE\s+TABLE/i', $line) and !$in_string) {
  151. $stack[] = 'table';
  152. $line = preg_replace("/public./", "chado.", $line);
  153. }
  154. if (preg_match('/^\s*ALTER\s+TABLE/i', $line) and !$in_string) {
  155. $stack[] = 'alter table';
  156. $line = preg_replace("/public./", "chado.", $line);
  157. }
  158. if (preg_match('/^\s*SET/i', $line) and !$in_string) {
  159. $stack[] = 'set';
  160. }
  161. if (preg_match('/^\s*CREATE\s+SCHEMA/i', $line) and !$in_string) {
  162. $stack[] = 'schema';
  163. }
  164. if (preg_match('/^\s*CREATE\s+SEQUENCE/i', $line) and !$in_string) {
  165. $stack[] = 'sequence';
  166. $line = preg_replace("/public./", "chado.", $line);
  167. }
  168. if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*VIEW/i', $line) and !$in_string) {
  169. $stack[] = 'view';
  170. $line = preg_replace("/public./", "chado.", $line);
  171. }
  172. if (preg_match('/^\s*COMMENT/i', $line) and !$in_string and sizeof($stack)==0) {
  173. $stack[] = 'comment';
  174. $line = preg_replace("/public./", "chado.", $line);
  175. }
  176. if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*FUNCTION/i', $line) and !$in_string) {
  177. $stack[] = 'function';
  178. $line = preg_replace("/public./", "chado.", $line);
  179. }
  180. if (preg_match('/^\s*CREATE\s+INDEX/i', $line) and !$in_string) {
  181. $stack[] = 'index';
  182. }
  183. if (preg_match('/^\s*INSERT\s+INTO/i', $line) and !$in_string) {
  184. $stack[] = 'insert';
  185. $line = preg_replace("/public./", "chado.", $line);
  186. }
  187. if (preg_match('/^\s*CREATE\s+TYPE/i', $line) and !$in_string) {
  188. $stack[] = 'type';
  189. }
  190. if (preg_match('/^\s*GRANT/i', $line) and !$in_string) {
  191. $stack[] = 'grant';
  192. }
  193. if (preg_match('/^\s*CREATE\s+AGGREGATE/i', $line) and !$in_string) {
  194. $stack[] = 'aggregate';
  195. }
  196. // determine if we are in a string that spans a line
  197. $matches = preg_match_all("/[']/i", $line, $temp);
  198. $in_string = $in_string - ($matches % 2);
  199. $in_string = abs($in_string);
  200. // if we've reached the end of an object the pop the stack
  201. if (strcmp($stack[sizeof($stack)-1], 'table') == 0 and preg_match('/\);\s*$/', $line)) {
  202. $type = array_pop($stack);
  203. }
  204. if (strcmp($stack[sizeof($stack)-1], 'alter table') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  205. $type = array_pop($stack);
  206. }
  207. if (strcmp($stack[sizeof($stack)-1], 'set') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  208. $type = array_pop($stack);
  209. }
  210. if (strcmp($stack[sizeof($stack)-1], 'schema') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  211. $type = array_pop($stack);
  212. }
  213. if (strcmp($stack[sizeof($stack)-1], 'sequence') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  214. $type = array_pop($stack);
  215. }
  216. if (strcmp($stack[sizeof($stack)-1], 'view') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  217. $type = array_pop($stack);
  218. }
  219. if (strcmp($stack[sizeof($stack)-1], 'comment') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  220. $type = array_pop($stack);
  221. }
  222. if (strcmp($stack[sizeof($stack)-1], 'function') == 0 and preg_match("/LANGUAGE.*?;\s+$/i", $line)) {
  223. $type = array_pop($stack);
  224. }
  225. if (strcmp($stack[sizeof($stack)-1], 'index') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  226. $type = array_pop($stack);
  227. }
  228. if (strcmp($stack[sizeof($stack)-1], 'insert') == 0 and preg_match('/\);\s*$/', $line)) {
  229. $type = array_pop($stack);
  230. }
  231. if (strcmp($stack[sizeof($stack)-1], 'type') == 0 and preg_match('/\);\s*$/', $line)) {
  232. $type = array_pop($stack);
  233. }
  234. if (strcmp($stack[sizeof($stack)-1], 'grant') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  235. $type = array_pop($stack);
  236. }
  237. if (strcmp($stack[sizeof($stack)-1], 'aggregate') == 0 and preg_match('/\);\s*$/', $line)) {
  238. $type = array_pop($stack);
  239. }
  240. // if we're in a recognized SQL statement then let's keep track of lines
  241. if ($type or sizeof($stack) > 0) {
  242. $query .= "$line";
  243. }
  244. else {
  245. print "UNHANDLED $i, $in_string: $line";
  246. return tripal_core_chado_install_done();
  247. }
  248. if (preg_match_all("/\n/", $query, $temp) > 100) {
  249. print "SQL query is too long. Terminating:\n$query\n";
  250. return tripal_core_chado_install_done();
  251. }
  252. if ($type and sizeof($stack) == 0) {
  253. print "Adding $type: line $i\n";
  254. // rewrite the set serach_path to make 'public' be 'chado'
  255. if (strcmp($type, 'set')==0) {
  256. $query = preg_replace("/public/m", "chado", $query);
  257. }
  258. $result = pg_query($active_db, $query);
  259. if (!$result) {
  260. $error = pg_last_error();
  261. print "Installation failed:\nSQL $i, $in_string: $query\n$error\n";
  262. pg_query($active_db, "set search_path to public,chado");
  263. return tripal_core_chado_install_done();
  264. }
  265. $query = '';
  266. }
  267. }
  268. print "Installation Complete!\n";
  269. tripal_core_chado_install_done();
  270. }
  271. /**
  272. * Finish the Chado Schema Installation
  273. *
  274. * @ingroup tripal_core
  275. */
  276. function tripal_core_chado_install_done() {
  277. // return the search path to normal
  278. global $active_db;
  279. pg_query($active_db, "set search_path to public,chado");
  280. }