tripal_chado.install.inc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  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_load_form($form, $form_state) {
  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. if (array_key_exists('values', $form_state)) {
  18. if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.2 to v1.3") {
  19. $tables_list = implode(', ', array('analysis_cvterm', 'analysis_dbxref', 'analysis_pub',
  20. 'analysis_relationship', 'contactprop', 'dbprop', 'feature_contact',
  21. 'featuremap_contact', 'featuremap_dbxref', 'featuremap_organism', 'featuremapprop',
  22. 'featureposprop', 'library_contact', 'library_expression', 'library_expressionprop',
  23. 'library_featureprop', 'library_relationship', 'library_relationship_pub', 'nd_experiment_analysis',
  24. 'organism_cvterm', 'organism_cvtermprop', 'organism_pub', 'organism_relationship',
  25. 'organismprop_pub', 'phenotypeprop', 'phylotreeprop', 'project_analysis',
  26. 'project_dbxref', 'project_feature', 'project_stock', 'pubauthor_contact',
  27. 'stock_feature', 'stock_featuremap', 'stock_library', 'stockcollection_db'));
  28. $items = array(
  29. 'PostgreSQL version 9.1 is required to perform this upgrade. If your Tripal
  30. site uses an older version please upgrade before proceeding.',
  31. 'A major change between Chado v1.2 and v1.3 is that primary and foreign
  32. keys were upgraded from integers to big integers. If your site has custom
  33. materialized views that will hold data derived from fields changed to
  34. big integers then you may need to alter the views to change the fields
  35. from integers to big integers and repopulate those views. If you have not
  36. added any materialized views you can ignore this issue.',
  37. 'Custom PL/pgSQL functions that expect primary and
  38. foreign key fields to be integers will not work after the upgrade.
  39. Those functions will need to be altered to accept big integers. If you
  40. do not have any custom PL/pgSQL functions you can ignore this issue.',
  41. 'PostgreSQL Views that use fields that are converted to big
  42. integers will cause this upgrade to fail. You must first remove
  43. those views, perform the upgrade and then recreate them with the
  44. appropriate fields change to big integers. If you do not have custom
  45. PostgreSQL Views you can ignore this issue.',
  46. 'Several new tables were added to Chado v1.3. However, some groups have
  47. added these tables to their Chado v1.2 installation. The Tripal upgrader
  48. will alter the primary and foreign keys of those tables to be "bigints"
  49. if they already exist but will otherwise leave them the same. You should
  50. verify that any tables with Chado v1.3 names correctly match the v1.3 schema.
  51. Otherwise you may have problems using Tripal. If you have not added any
  52. Chado v1.3 tables to your Chado v1.2 database you can ignore this issue.
  53. These are the newly added tables: ' .
  54. $tables_list . '.'
  55. );
  56. $list = theme_item_list(array(
  57. 'items' => $items,
  58. 'title' => '',
  59. 'type' => 'ul',
  60. 'attributes' => array(),
  61. ));
  62. drupal_set_message('Please note: the upgrade of Chado from v1.2 to v1.3 may
  63. require several fixes to your database. Please review the following
  64. list to ensure a safe upgrade. The Tripal upgrader is
  65. not able to fix these problems automatically: ' . $list, 'warning');
  66. }
  67. if ($form_state['values']['action_to_do'] == "Install Chado v1.3" or
  68. $form_state['values']['action_to_do'] == "Install Chado v1.2" or
  69. $form_state['values']['action_to_do'] == "Install Chado v1.11") {
  70. drupal_set_message('Please note: if Chado is already installed it will
  71. be removed and recreated and all data will be lost. If this is
  72. desired or if this is the first time Chado has been installed
  73. you can ignore this issue.', 'warning');
  74. }
  75. }
  76. $form['current_version'] = array(
  77. '#type' => 'item',
  78. '#title' => t("Current installed version of Chado:"),
  79. '#description' => $real_version,
  80. );
  81. $form['action_to_do'] = array(
  82. '#type' => 'radios',
  83. '#title' => 'Installation/Upgrade Action',
  84. '#options' => array(
  85. 'Install Chado v1.3' => t('New Install of Chado v1.3 (erases all existing Chado data if Chado already exists)'),
  86. 'Upgrade Chado v1.2 to v1.3' => t('Upgrade existing Chado v1.2 to v1.3 (no data is lost)'),
  87. 'Install Chado v1.2' => t('New Install of Chado v1.2 (erases all existing Chado data if Chado already exists)'),
  88. 'Upgrade Chado v1.11 to v1.2' => t('Upgrade existing Chado v1.11 to v1.2 (no data is lost)'),
  89. 'Install Chado v1.11' => t('New Install of Chado v1.11 (erases all existing Chado data if Chado already exists)'),
  90. ),
  91. '#description' => t('Select an action to perform. If you want to install Chado all other Tripal modules must not be installed.'),
  92. '#required' => TRUE,
  93. '#ajax' => array(
  94. 'callback' => "tripal_chado_load_form_ajax_callback",
  95. 'wrapper' => 'tripal_chado_load_form',
  96. 'effect' => 'fade',
  97. 'method' => 'replace',
  98. ),
  99. );
  100. $form['warning'] = array(
  101. '#markup' => "<div><font color=\"red\">WARNING:</font>" . t('A new install of
  102. Chado will remove and recreate the Chado database if it already exists.') . '</div>',
  103. );
  104. $form['button'] = array(
  105. '#type' => 'submit',
  106. '#value' => t('Install/Upgrade Chado'),
  107. );
  108. $form['#prefix'] = '<div id="tripal_chado_load_form">';
  109. $form['#suffix'] = '</div>';
  110. return $form;
  111. }
  112. /**
  113. * Ajax callback function for the gensas_job_view_panel_form.
  114. *
  115. * @param $form
  116. * @param $form_state
  117. */
  118. function tripal_chado_load_form_ajax_callback($form, $form_state) {
  119. return $form;
  120. }
  121. function tripal_chado_load_form_validate($form, &$form_state) {
  122. // We do not want to allow re-installation of Chado if other
  123. // Tripal modules are installed. This is because the install files
  124. // of those modules may add content to Chado and reinstalling Chado
  125. // removes that content which may break the modules.
  126. if ($form_state['values']['action_to_do'] == "Install Chado v1.3" or
  127. $form_state['values']['action_to_do'] == "Install Chado v1.2" or
  128. $form_state['values']['action_to_do'] == "Install Chado v1.11") {
  129. $modules = system_get_info('module');
  130. // The tripal_chado_views module should not be included as it's a required
  131. // dependency of tripal_chado
  132. unset($modules['tripal_chado_views']);
  133. $list = array();
  134. foreach ($modules as $mname => $module) {
  135. if (array_key_exists('dependencies', $module) and in_array('tripal_chado', $module['dependencies'])) {
  136. $list[] = $module['name'] . " ($mname)";
  137. }
  138. }
  139. if (count($list) > 0) {
  140. form_set_error("action_to_do", "Chado cannot be installed while other Tripal modules
  141. are enabled. You must fully uninstall the following modules if you
  142. would like to install or re-install chado.<br>" .
  143. implode("<br>", $list));
  144. }
  145. }
  146. if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.11 to v1.2") {
  147. // Make sure we are already not at v1.2
  148. $real_version = chado_get_version(TRUE);
  149. if ($real_version == "1.2") {
  150. form_set_error("action_to_do", "You are already at v1.2. There is no need to upgrade.");
  151. }
  152. }
  153. if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.2 to v1.3") {
  154. // Make sure we are already not at v1.3
  155. $real_version = chado_get_version(TRUE);
  156. if ($real_version == "1.3") {
  157. form_set_error("action_to_do", "You are already at v1.3. There is no need to upgrade.");
  158. }
  159. }
  160. }
  161. /**
  162. * Submit Load Chado Schema Form
  163. *
  164. * @ingroup tripal_chado
  165. */
  166. function tripal_chado_load_form_submit($form, &$form_state) {
  167. global $user;
  168. $action_to_do = trim($form_state['values']['action_to_do']);
  169. $args = array($action_to_do);
  170. $includes = array(module_load_include('inc', 'tripal_chado', 'includes/tripal_chado.install'));
  171. tripal_add_job($action_to_do, 'tripal_chado',
  172. 'tripal_chado_install_chado', $args, $user->uid, 10, $includes);
  173. }
  174. /**
  175. * Submit Load Chado Schema Form
  176. *
  177. * @ingroup tripal_chado
  178. */
  179. function tripal_chado_load_drush_submit($version) {
  180. $args = array($version);
  181. $includes = array(module_load_include('inc', 'tripal_chado', 'includes/tripal_chado.install'));
  182. tripal_add_job($version, 'tripal_chado',
  183. 'tripal_chado_install_chado', $args, 1, 10, $includes);
  184. }
  185. /**
  186. * Install Chado Schema
  187. *
  188. * @ingroup tripal_chado
  189. */
  190. function tripal_chado_install_chado($action, TripalJob $job = NULL) {
  191. $vsql = "
  192. INSERT INTO {chadoprop} (type_id, value)
  193. VALUES (
  194. (SELECT cvterm_id
  195. FROM {cvterm} CVT
  196. INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
  197. WHERE CV.name = 'chado_properties' AND CVT.name = 'version'),
  198. :version)
  199. ";
  200. $vusql = "
  201. UPDATE {chadoprop}
  202. SET value = :version
  203. WHERE type_id = (SELECT cvterm_id
  204. FROM {cvterm} CVT
  205. INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
  206. WHERE CV.name = 'chado_properties' AND CVT.name = 'version')
  207. ";
  208. $transaction = db_transaction();
  209. try {
  210. if ($action == 'Install Chado v1.3') {
  211. tripal_chado_install_chado_1_3();
  212. chado_query($vsql, array(':version' => '1.3'));
  213. }
  214. elseif ($action == 'Upgrade Chado v1.2 to v1.3') {
  215. tripal_chado_upgrade_chado_1_2_to_1_3();
  216. chado_query($vusql, array(':version' => '1.3'));
  217. }
  218. elseif ($action == 'Install Chado v1.2') {
  219. tripal_chado_install_chado_1_2();
  220. chado_query($vsql, array(':version' => '1.2'));
  221. }
  222. elseif ($action == 'Upgrade Chado v1.11 to v1.2') {
  223. tripal_chado_upgrade_chado_1_11_to_1_2();
  224. chado_query($vsql, array(':version' => '1.2'));
  225. }
  226. elseif ($action == 'Install Chado v1.11') {
  227. tripal_chado_install_chado_1_11();
  228. }
  229. }
  230. catch (Exception $e) {
  231. $transaction->rollback();
  232. tripal_chado_install_done();
  233. tripal_report_error('tripal_chado', TRIPAL_ERROR, $e->getMessage(), array('print' => TRUE));
  234. return FALSE;
  235. }
  236. return TRUE;
  237. }
  238. /**
  239. * Installs Chado v1.3.
  240. */
  241. function tripal_chado_install_chado_1_3(TripalJob $job = NULL) {
  242. // Get the path to the schema and init SQL files.
  243. $schema_file = drupal_get_path('module', 'tripal_chado') .
  244. '/chado_schema/default_schema-1.3.sql';
  245. $init_file = drupal_get_path('module', 'tripal_chado') .
  246. '/chado_schema/initialize-1.3.sql';
  247. // Erase the Chado schema if it exists and perform the install.
  248. if (tripal_chado_reset_chado_schema()) {
  249. $success = tripal_chado_install_sql($schema_file);
  250. if ($success) {
  251. print "Install of Chado v1.3 (Step 1 of 2) Successful!\n";
  252. }
  253. else {
  254. throw new Exception("Installation (Step 1 of 2) Problems! Please check output above for errors.");
  255. }
  256. $success = tripal_chado_install_sql($init_file);
  257. if ($success) {
  258. print "Install of Chado v1.3 (Step 2 of 2) Successful.\nInstallation Complete\n";
  259. }
  260. else {
  261. throw new Exception("Installation (Step 2 of 2) Problems! Please check output above for errors.");
  262. }
  263. }
  264. else {
  265. throw new Exception("ERROR: cannot install chado. Please check database permissions");
  266. }
  267. }
  268. /**
  269. * Installs Chado v1.2.
  270. */
  271. function tripal_chado_install_chado_1_2() {
  272. // Get the path to the schema and init SQL files.
  273. $schema_file = drupal_get_path('module', 'tripal_chado') .
  274. '/chado_schema/default_schema-1.2.sql';
  275. $init_file = drupal_get_path('module', 'tripal_chado') .
  276. '/chado_schema/initialize-1.2.sql';
  277. // Erase the Chado schema if it exists and perform the install.
  278. if (tripal_chado_reset_chado_schema()) {
  279. $success = tripal_chado_install_sql($schema_file);
  280. if ($success) {
  281. print "Install of Chado v1.2 (Step 1 of 2) Successful!\n";
  282. }
  283. else {
  284. throw new Exception("Installation (Step 1 of 2) Problems! Please check output above for errors.");
  285. }
  286. $success = tripal_chado_install_sql($init_file);
  287. if ($success) {
  288. print "Install of Chado v1.2 (Step 2 of 2) Successful.\nInstallation Complete\n";
  289. }
  290. else {
  291. throw new Exception("Installation (Step 2 of 2) Problems! Please check output above for errors.");
  292. }
  293. }
  294. else {
  295. throw new Exception("ERROR: cannot install chado. Please check database permissions");
  296. }
  297. }
  298. /**
  299. *
  300. */
  301. function tripal_chado_install_chado_1_11() {
  302. // Get the path to the schema and init SQL files.
  303. $schema_file = drupal_get_path('module', 'tripal_chado') .
  304. '/chado_schema/default_schema-1.11.sql';
  305. $init_file = drupal_get_path('module', 'tripal_chado') .
  306. '/chado_schema/initialize-1.11.sql';
  307. // Erase the Chado schema if it exists and perform the install.
  308. if (tripal_chado_reset_chado_schema()) {
  309. $success = tripal_chado_install_sql($schema_file);
  310. if ($success) {
  311. print "Install of Chado v1.11 (Step 1 of 2) Successful!\n";
  312. }
  313. else {
  314. throw new Exception("Installation (Step 1 of 2) Problems! Please check output above for errors.");
  315. }
  316. $success = tripal_chado_install_sql($init_file);
  317. if ($success) {
  318. print "Install of Chado v1.11 (Step 2 of 2) Successful.\nInstallation Complete!\n";
  319. }
  320. else {
  321. throw new Exception("Installation (Step 2 of 2) Problems! Please check output above for errors.");
  322. }
  323. }
  324. else {
  325. throw new Exception("ERROR: cannot install chado. Please check database permissions");
  326. }
  327. }
  328. /**
  329. * Upgrades Chado from v1.2 to v1.3
  330. */
  331. function tripal_chado_upgrade_chado_1_2_to_1_3() {
  332. // Upgrade some of the custom tables that Tripal created that are now in
  333. // Chado v1.3. We'll do this ahead of time because the upgrade script won't
  334. // upgrade tables if they already exist.
  335. print "Checking for existing v1.3 tables in v1.2 and fixing bigints...\n";
  336. tripal_chado_upgrade_chado_1_2_to_1_3_pre_alter();
  337. // Get the path to the diff schema and upgrade SQL files.
  338. print "Incorporating additional changes...\n";
  339. $diff_file = drupal_get_path('module', 'tripal_chado') .
  340. '/chado_schema/default_schema-1.2-1.3-diff.sql';
  341. $success = tripal_chado_install_sql($diff_file);
  342. if ($success) {
  343. print "Upgrade from v1.2 to v1.3 Successful!\n";
  344. }
  345. else {
  346. throw new Exception("Upgrade problems! Please check output above for errors.");
  347. }
  348. }
  349. /**
  350. * Upgrade custom tables that may match the tables now in Chado v1.3.
  351. *
  352. * There were many new tables that were added to Chado v1.3 that were
  353. * suggested by the Chado user community. Some of those were Tripal users.
  354. * Therefore, to help these Tripal users upgrade more seemlessly this function
  355. * checks if those custom tables already exists, and if so updates them as
  356. * best it can to match. At a minimum it will create the table if it doesn't
  357. * exist and if it does it will change the primary keys and foreign keys to
  358. * be big ints.
  359. */
  360. function tripal_chado_upgrade_chado_1_2_to_1_3_pre_alter() {
  361. // Include the Chado v1.3 schema definitions.
  362. module_load_include('inc', 'tripal_chado', '/api/tripal_chado.schema_v1.3.api');
  363. // The list of new tables in Chado v1.3
  364. $new_tables = array('analysis_cvterm', 'analysis_dbxref', 'analysis_pub', 'analysis_relationship',
  365. 'contactprop', 'dbprop', 'feature_contact', 'featuremap_contact', 'featuremap_dbxref',
  366. 'featuremap_organism', 'featuremapprop', 'featureposprop', 'library_contact',
  367. 'library_expression', 'library_expressionprop', 'library_featureprop',
  368. 'library_relationship', 'library_relationship_pub', 'nd_experiment_analysis',
  369. 'organism_cvterm', 'organism_cvtermprop', 'organism_pub', 'organism_relationship',
  370. 'organismprop_pub', 'phenotypeprop', 'phylotreeprop', 'project_analysis',
  371. 'project_dbxref', 'project_feature', 'project_stock', 'pubauthor_contact',
  372. 'stock_feature', 'stock_featuremap', 'stock_library', 'stockcollection_db',
  373. );
  374. // Get the name of the chado schema.
  375. $chado_schema = chado_get_schema_name('chado');
  376. // Iterate through the new Chado tables and create them or if they already
  377. // exist then update them.
  378. foreach ($new_tables as $table) {
  379. // Get the schema for this table.
  380. $function = 'tripal_chado_chado_schema_v1_3_' . $table;
  381. $schema = $function();
  382. // If the table exists then fix the pkeys and fkeys.
  383. if (chado_table_exists($table)) {
  384. // Update the primary key fields to be bigints.
  385. $fields = $schema['fields'];
  386. foreach ($fields as $field_name => $field) {
  387. if ($field['type'] == 'serial') {
  388. if (chado_column_exists($table, $field_name)) {
  389. $sql = 'ALTER TABLE {' . $table . '} ALTER COLUMN ' . $field_name . ' TYPE bigint';
  390. chado_query($sql);
  391. }
  392. else {
  393. throw new Exception('Could not alter primary key to bigint: ' . $table . '.' . $field_name);
  394. }
  395. }
  396. }
  397. // Update the foreign key fields to be bigints.
  398. $fkeys = $schema['foreign keys'];
  399. foreach ($fkeys as $fktable => $details) {
  400. foreach ($details['columns'] as $leftkey => $rightkey) {
  401. if (chado_column_exists($table, $leftkey)) {
  402. $sql = 'ALTER TABLE {' . $table . '} ALTER COLUMN ' . $leftkey . ' TYPE bigint';
  403. chado_query($sql);
  404. }
  405. else {
  406. throw new Exception('Could not alter foreign key to bigint: ' . $table . '.' . $leftkey);
  407. }
  408. }
  409. }
  410. }
  411. }
  412. // Now create the sequences if they don't already exist.
  413. $sequences = array(
  414. 'analysis_cvterm_analysis_cvterm_id_seq',
  415. 'analysis_dbxref_analysis_dbxref_id_seq',
  416. 'analysis_pub_analysis_pub_id_seq',
  417. 'analysis_relationship_analysis_relationship_id_seq',
  418. 'contactprop_contactprop_id_seq',
  419. 'dbprop_dbprop_id_seq',
  420. 'feature_contact_feature_contact_id_seq',
  421. 'featuremap_contact_featuremap_contact_id_seq',
  422. 'featuremap_dbxref_featuremap_dbxref_id_seq',
  423. 'featuremap_organism_featuremap_organism_id_seq',
  424. 'featuremapprop_featuremapprop_id_seq',
  425. 'featureposprop_featureposprop_id_seq',
  426. 'library_contact_library_contact_id_seq',
  427. 'library_expression_library_expression_id_seq',
  428. 'library_expressionprop_library_expressionprop_id_seq',
  429. 'library_featureprop_library_featureprop_id_seq',
  430. 'library_relationship_library_relationship_id_seq',
  431. 'library_relationship_pub_library_relationship_pub_id_seq',
  432. 'nd_experiment_analysis_nd_experiment_analysis_id_seq',
  433. 'organism_cvterm_organism_cvterm_id_seq',
  434. 'organism_cvtermprop_organism_cvtermprop_id_seq',
  435. 'organism_pub_organism_pub_id_seq',
  436. 'organism_relationship_organism_relationship_id_seq',
  437. 'organismprop_pub_organismprop_pub_id_seq',
  438. 'phenotypeprop_phenotypeprop_id_seq',
  439. 'phylotreeprop_phylotreeprop_id_seq',
  440. 'project_analysis_project_analysis_id_seq',
  441. 'project_dbxref_project_dbxref_id_seq',
  442. 'project_feature_project_feature_id_seq',
  443. 'project_stock_project_stock_id_seq',
  444. 'pubauthor_contact_pubauthor_contact_id_seq',
  445. 'stock_feature_stock_feature_id_seq',
  446. 'stock_featuremap_stock_featuremap_id_seq',
  447. 'stock_library_stock_library_id_seq',
  448. 'stockcollection_db_stockcollection_db_id_seq'
  449. );
  450. foreach ($sequences as $sequence) {
  451. // Now add in the sequences if they don't already exist. There is no
  452. // PostgreSQL 'CREATE SEQUENCE IF NOT EXIST' so we're forced to do it here
  453. // and these create statements were removed from the diff upgrade file.
  454. if (!chado_sequence_exists($sequence)) {
  455. $sql = "CREATE SEQUENCE {" . $sequence . "} START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1";
  456. chado_query($sql);
  457. }
  458. }
  459. }
  460. /**
  461. * Upgrades Chado from v1.11 to v1.2
  462. */
  463. function tripal_chado_upgrade_chado_1_11_to_1_2() {
  464. // Get the path to the schema diff and upgarde SQL files.
  465. $schema_file = drupal_get_path('module', 'tripal_chado') . '/chado_schema/default_schema-1.11-1.2-diff.sql';
  466. $init_file = drupal_get_path('module', 'tripal_chado') . '/chado_schema/upgrade-1.11-1.2.sql';
  467. $success = tripal_chado_install_sql($schema_file);
  468. if ($success) {
  469. print "Upgrade from v1.11 to v1.2 (Step 1 of 2) Successful!\n";
  470. }
  471. else {
  472. throw new Exception("Upgrade (Step 1 of 2) problems! Please check output above for errors.");
  473. }
  474. $success = tripal_chado_install_sql($init_file);
  475. if ($success) {
  476. print "Upgrade from v1.11 to v1.2 (Step 2 of 2) Successful.\nUpgrade Complete!\n";
  477. }
  478. else {
  479. throw new Exception("Upgrade (Step 2 of 2) problems! Please check output above for errors.");
  480. }
  481. }
  482. /**
  483. * Reset the Chado Schema
  484. * This drops the current chado and chado-related schema and re-creates it
  485. *
  486. * @ingroup tripal_chado
  487. */
  488. function tripal_chado_reset_chado_schema() {
  489. // determine the schema name.
  490. $chado_schema = chado_get_schema_name('chado');
  491. $chado_dot = $chado_schema . '.';
  492. // drop current chado and chado-related schema
  493. if (chado_dbschema_exists('genetic_code')) {
  494. print "Dropping existing 'genetic_code' schema\n";
  495. db_query("drop schema genetic_code cascade");
  496. }
  497. if (chado_dbschema_exists('so')) {
  498. print "Dropping existing 'so' schema\n";
  499. db_query("drop schema so cascade");
  500. }
  501. if (chado_dbschema_exists('frange')) {
  502. print "Dropping existing 'frange' schema\n";
  503. db_query("drop schema frange cascade");
  504. }
  505. if (chado_dbschema_exists($chado_schema)) {
  506. if ($chado_schema != 'chado') {
  507. print "Dropping existing Chado ('$chado_schema') schema\n";
  508. }
  509. else {
  510. print "Dropping existing 'chado' schema\n";
  511. }
  512. db_query("drop schema $chado_schema cascade");
  513. }
  514. // create the new chado schema
  515. print "Creating 'chado' schema\n";
  516. db_query("create schema $chado_schema");
  517. if (chado_dbschema_exists('chado')) {
  518. // before creating the plpgsql language let's check to make sure
  519. // it doesn't already exists
  520. $sql = "SELECT COUNT(*) FROM pg_language WHERE lanname = 'plpgsql'";
  521. $results = db_query($sql);
  522. $count = $results->fetchObject();
  523. if (!$count or $count->count == 0) {
  524. db_query("create language plpgsql");
  525. }
  526. return TRUE;
  527. }
  528. return FALSE;
  529. }
  530. /**
  531. * Execute the provided SQL
  532. *
  533. * @param $sql_file
  534. * Contains SQL statements to be executed
  535. *
  536. * @ingroup tripal_chado
  537. */
  538. function tripal_chado_install_sql($sql_file) {
  539. $chado_local = chado_dbschema_exists('chado');
  540. // determine the schema name.
  541. $chado_schema = chado_get_schema_name('chado');
  542. $chado_dot = $chado_schema . '.';
  543. if ($chado_local) {
  544. db_query("set search_path to $chado_schema");
  545. }
  546. print "Loading $sql_file...\n";
  547. $lines = file($sql_file, FILE_SKIP_EMPTY_LINES);
  548. if (!$lines) {
  549. return 'Cannot open $schema_file';
  550. }
  551. $stack = array();
  552. $in_string = 0;
  553. $in_function = FALSE;
  554. $query = '';
  555. $i = 0;
  556. $success = 1;
  557. foreach ($lines as $line_num => $line) {
  558. $i++;
  559. $type = '';
  560. // find and remove comments except when inside of strings
  561. if (preg_match('/--/', $line) and !$in_string and !preg_match("/'.*?--.*?'/", $line)) {
  562. $line = preg_replace('/--.*$/', '', $line); // remove comments
  563. }
  564. if (preg_match('/\/\*.*?\*\//', $line)) {
  565. $line = preg_replace('/\/\*.*?\*\//', '', $line); // remove comments
  566. }
  567. // skip empty lines
  568. if (preg_match('/^\s*$/', $line) or strcmp($line, '')==0) {
  569. continue;
  570. }
  571. // Find SQL for new objects
  572. if (preg_match('/^\s*CREATE\s+TABLE/i', $line) and !$in_string and !$in_function) {
  573. $stack[] = 'table';
  574. $line = preg_replace("/public\./", $chado_dot, $line);
  575. }
  576. if (preg_match('/^\s*ALTER\s+TABLE\s+/i', $line) and !$in_string and !$in_function) {
  577. $stack[] = 'alter_table';
  578. $line = preg_replace("/public\./", $chado_dot, $line);
  579. }
  580. if (preg_match('/^\s*SET/i', $line) and !$in_string and !$in_function) {
  581. $stack[] = 'set';
  582. }
  583. if (preg_match('/^\s*CREATE\s+SCHEMA/i', $line) and !$in_string and !$in_function) {
  584. $stack[] = 'schema';
  585. }
  586. if (preg_match('/^\s*CREATE\s+SEQUENCE/i', $line) and !$in_string and !$in_function) {
  587. $stack[] = 'sequence';
  588. $line = preg_replace("/public\./", $chado_dot, $line);
  589. }
  590. if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*VIEW/i', $line) and !$in_string and !$in_function) {
  591. $stack[] = 'view';
  592. $line = preg_replace("/public\./", $chado_dot, $line);
  593. }
  594. if (preg_match('/^\s*COMMENT/i', $line) and !$in_string and sizeof($stack)==0 and !$in_function) {
  595. $stack[] = 'comment';
  596. $line = preg_replace("/public\./", $chado_dot, $line);
  597. }
  598. if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*FUNCTION/i', $line) and !$in_string and !$in_function) {
  599. $in_function = TRUE;
  600. $stack[] = 'function';
  601. $line = preg_replace("/public\./", $chado_dot, $line);
  602. }
  603. if (preg_match('/^\s*CREATE\s+INDEX/i', $line) and !$in_string and !$in_function) {
  604. $stack[] = 'index';
  605. }
  606. if (preg_match('/^\s*INSERT\s+INTO/i', $line) and !$in_string and !$in_function) {
  607. $stack[] = 'insert';
  608. $line = preg_replace("/public\./", $chado_dot, $line);
  609. }
  610. if (preg_match('/^\s*CREATE\s+TYPE/i', $line) and !$in_string and !$in_function) {
  611. $stack[] = 'type';
  612. }
  613. if (preg_match('/^\s*GRANT/i', $line) and !$in_string and !$in_function) {
  614. $stack[] = 'grant';
  615. }
  616. if (preg_match('/^\s*CREATE\s+AGGREGATE/i', $line) and !$in_string and !$in_function) {
  617. $stack[] = 'aggregate';
  618. }
  619. if (preg_match('/^\s*DROP\s+FUNCTION/i', $line) and !$in_string and !$in_function) {
  620. $stack[] = 'drop_function';
  621. }
  622. if (preg_match('/^\s*DROP\s+VIEW/i', $line) and !$in_string and !$in_function) {
  623. $stack[] = 'drop_view';
  624. }
  625. if (preg_match('/^\s*DROP\s+INDEX/i', $line) and !$in_string and !$in_function) {
  626. $stack[] = 'drop_index';
  627. }
  628. if (preg_match('/^\s*DROP\s+SEQUENCE/i', $line) and !$in_string and !$in_function) {
  629. $stack[] = 'drop_seq';
  630. }
  631. if (preg_match('/^\s*ALTER\s+TYPE\s+/i', $line) and !$in_string and !$in_function) {
  632. $stack[] = 'alter_type';
  633. }
  634. if (preg_match('/^\s*ALTER\s+SEQUENCE\s+/i', $line) and !$in_string and !$in_function) {
  635. $stack[] = 'alter_seq';
  636. }
  637. // determine if we are in a string that spans a line
  638. $matches = preg_match_all("/[']/i", $line, $temp);
  639. $in_string = $in_string - ($matches % 2);
  640. $in_string = abs($in_string);
  641. // if we've reached the end of an object then pop the stack
  642. if (strcmp($stack[sizeof($stack)-1], 'table') == 0 and preg_match('/\);\s*$/', $line)) {
  643. $type = array_pop($stack);
  644. }
  645. elseif (strcmp($stack[sizeof($stack)-1], 'alter_table') == 0 and preg_match('/;\s*$/', $line)) {
  646. $type = array_pop($stack);
  647. }
  648. elseif (strcmp($stack[sizeof($stack)-1], 'set') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  649. $type = array_pop($stack);
  650. }
  651. elseif (strcmp($stack[sizeof($stack)-1], 'schema') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  652. $type = array_pop($stack);
  653. }
  654. elseif (strcmp($stack[sizeof($stack)-1], 'sequence') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  655. $type = array_pop($stack);
  656. }
  657. elseif (strcmp($stack[sizeof($stack)-1], 'view') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  658. $type = array_pop($stack);
  659. }
  660. elseif (strcmp($stack[sizeof($stack)-1], 'comment') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  661. $type = array_pop($stack);
  662. }
  663. elseif (strcmp($stack[sizeof($stack)-1], 'function') == 0) {
  664. if(preg_match('/LANGUAGE.*?;\s*$/i', $line)) {
  665. $type = array_pop($stack);
  666. $in_function = FALSE;
  667. //print "FUNCTION DONE ($i): $line";
  668. }
  669. else if(preg_match('/\$_\$;\s*$/i', $line)) {
  670. $type = array_pop($stack);
  671. $in_function = FALSE;
  672. //print "FUNCTION DONE ($i): $line";
  673. }
  674. else if(preg_match('/\$\$;\s*$/i', $line)) {
  675. $type = array_pop($stack);
  676. $in_function = FALSE;
  677. // print "FUNCTION DONE ($i): $line";
  678. }
  679. else {
  680. // print "FUNCTION ($i): $line";
  681. }
  682. }
  683. elseif (strcmp($stack[sizeof($stack)-1], 'index') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  684. $type = array_pop($stack);
  685. }
  686. elseif (strcmp($stack[sizeof($stack)-1], 'insert') == 0 and preg_match('/\);\s*$/', $line)) {
  687. $type = array_pop($stack);
  688. }
  689. elseif (strcmp($stack[sizeof($stack)-1], 'type') == 0 and preg_match('/\);\s*$/', $line)) {
  690. $type = array_pop($stack);
  691. }
  692. elseif (strcmp($stack[sizeof($stack)-1], 'grant') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
  693. $type = array_pop($stack);
  694. }
  695. elseif (strcmp($stack[sizeof($stack)-1], 'aggregate') == 0 and preg_match('/\);\s*$/', $line)) {
  696. $type = array_pop($stack);
  697. }
  698. elseif (strcmp($stack[sizeof($stack)-1], 'drop_function') == 0 and preg_match('/;\s*$/i', $line)) {
  699. $type = array_pop($stack);
  700. }
  701. elseif (strcmp($stack[sizeof($stack)-1], 'drop_view') == 0 and preg_match('/;\s*$/i', $line)) {
  702. $type = array_pop($stack);
  703. }
  704. elseif (strcmp($stack[sizeof($stack)-1], 'drop_index') == 0 and preg_match("/;\s*$/i", $line)) {
  705. $type = array_pop($stack);
  706. }
  707. elseif (strcmp($stack[sizeof($stack)-1], 'drop_seq') == 0 and preg_match("/;\s*$/i", $line)) {
  708. $type = array_pop($stack);
  709. }
  710. elseif (strcmp($stack[sizeof($stack)-1], 'alter_type') == 0 and preg_match('/;\s*$/i', $line)) {
  711. $type = array_pop($stack);
  712. }
  713. elseif (strcmp($stack[sizeof($stack)-1], 'alter_seq') == 0 and preg_match('/;\s*$/i', $line)) {
  714. $type = array_pop($stack);
  715. }
  716. // if we're in a recognized SQL statement then let's keep track of lines
  717. if ($type or sizeof($stack) > 0) {
  718. $query .= "$line";
  719. }
  720. else {
  721. throw new Exception("UNHANDLED $i, $in_string: $line");
  722. }
  723. if (preg_match_all("/\n/", $query, $temp) > 1000) {
  724. throw new Exception("SQL query is too long. Terminating:\n$query\n");
  725. }
  726. if ($type and sizeof($stack) == 0) {
  727. //print "Adding $type: line $i\n";
  728. // rewrite the set search_path to make 'public' be 'chado', but only if the
  729. // chado schema exists
  730. if (strcmp($type, 'set') == 0 and $chado_local) {
  731. $query = preg_replace("/public/m", $chado_schema, $query);
  732. }
  733. // execute the statement
  734. try {
  735. $result = db_query($query);
  736. }
  737. catch (Exception $e) {
  738. $error = $e->getMessage();
  739. throw new Exception("FAILED. Line $i, $in_string\n$error:\n$query\n\n");
  740. }
  741. if (!$result) {
  742. $error = pg_last_error();
  743. throw new Exception("FAILED. Line $i, $in_string\n$error:\n$query\n\n");
  744. }
  745. $query = '';
  746. }
  747. }
  748. tripal_chado_install_done();
  749. return $success;
  750. }
  751. /**
  752. * Finish the Chado Schema Installation
  753. *
  754. * @ingroup tripal_chado
  755. */
  756. function tripal_chado_install_done() {
  757. $drupal_schema = chado_get_schema_name('drupal');
  758. db_query("set search_path to $drupal_schema");
  759. }