tripal_cv.api.inc

  1. 2.x tripal_cv/api/tripal_cv.api.inc
  2. 1.x tripal_cv/api/tripal_cv.api.inc

Controlled Vocabulary API

tripal_cv_api CV Module API This module provides a set of functions to simplify working with controlled vocabularies. Most of the API functions deal with retrieving terms or their parent vocabularies.

However, the API also supports generation of trees for browsing a vocabulary as well as generation of pie graphs for display of hierarchical counts of terms. Version 0.3b of Tripal provides a feature browser and a feature summary chart uses the API functions provided here. But in general charts and trees can be created for any controlled vocabulary.

File

tripal_cv/api/tripal_cv.api.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Controlled Vocabulary API
  5. *
  6. * @defgroup tripal_cv_api CV Module API
  7. * @ingroup tripal_api
  8. * This module provides a set of functions to simplify working with
  9. * controlled vocabularies. Most of the API functions deal with retrieving
  10. * terms or their parent vocabularies.
  11. *
  12. * However, the API also supports
  13. * generation of trees for browsing a vocabulary as well as generation of
  14. * pie graphs for display of hierarchical counts of terms. Version 0.3b of
  15. * Tripal provides a feature browser and a feature summary chart uses
  16. * the API functions provided here. But in general charts and trees can be
  17. * created for any controlled vocabulary.
  18. *
  19. */
  20. /**
  21. * Purpose: To retrieve a chado controlled vocabulary object
  22. *
  23. * @param $select_values
  24. * An array meant to uniquely select a given controlled vocabulary
  25. *
  26. * @return
  27. * Chado controlled vocabulary object
  28. *
  29. * The controlled vocabulary is selected using tripal_core_chado select and as such the
  30. * $select_values array parameter meant to uniquely identify the controlled vocab to be
  31. * returned follows the same form as when using tripal_core_chado_select directly.
  32. *
  33. * Example Usage:
  34. * @code
  35. $select_values = array(
  36. 'name' => 'feature_property'
  37. );
  38. $cv_object = tripal_cv_get_cv($select_values);
  39. * @endcode
  40. * The above code selects the feature_property cv and returns the following object:
  41. * @code
  42. $cv_object = stdClass Object (
  43. [cv_id] => 13
  44. [name] => feature_property
  45. [definition] =>
  46. );
  47. * @endcode
  48. *
  49. * @ingroup tripal_cv_api
  50. */
  51. function tripal_cv_get_cv($select_values) {
  52. $columns = array(
  53. 'cv_id',
  54. 'name',
  55. 'definition',
  56. );
  57. $results = tripal_core_chado_select('cv', $columns, $select_values);
  58. if (sizeof($results) == 1) {
  59. return $results[0];
  60. }
  61. elseif (empty($results)) {
  62. watchdog('tripal_cv',
  63. 'tripal_cv_get_cv: No cv matches criteria values:%values',
  64. array('%values' => print_r($select_values, TRUE)),
  65. WATCHDOG_WARNING
  66. );
  67. return FALSE;
  68. }
  69. else {
  70. watchdog('tripal_cv',
  71. 'tripal_cv_get_cv: 2+ cvs match criteria values:%values',
  72. array('%values' => print_r($select_values, TRUE)),
  73. WATCHDOG_WARNING
  74. );
  75. }
  76. }
  77. // Purpose: To retrieve a chado cv object
  78. // @param $where_options
  79. // @code
  80. // array(
  81. // <column_name> => array(
  82. // 'type' => <type of column: INT/STRING>,
  83. // 'value' => <the vlaue you want to filter on>,
  84. // 'exact' => <if TRUE use =; if FALSE use ~>,
  85. // )
  86. // )
  87. // @endcode
  88. //
  89. // @return
  90. // Chado cv object with all fields from the chado cv table
  91. //
  92. // @ingroup tripal_cv_api
  93. //
  94. //function tripal_cv_get_cv ($where_options)
  95. /**
  96. * Retrieve a cv given the cv name
  97. *
  98. * @param $name
  99. * The name of the cv to be returned
  100. * @return
  101. * The cv object for the specified CV name
  102. *
  103. * @ingroup tripal_cv_api
  104. */
  105. function tripal_cv_get_cv_by_name($name) {
  106. $r = tripal_core_chado_select('cv', array('*'), array('name' => $name));
  107. return $r[0];
  108. }
  109. /**
  110. * Retrieve the cv object for the specified CV id
  111. *
  112. * NOTE: This function is deprecated.
  113. * @see tripal_core_chado_generate_vars()
  114. *
  115. * @param $cv_id
  116. * The unique identifier for the cv to retrieve
  117. *
  118. * @return
  119. * An object describing the cv
  120. *
  121. * @ingroup tripal_cv_api
  122. */
  123. function tripal_cv_get_cv_by_id($cv_id) {
  124. $r = tripal_core_chado_select('cv', array('*'), array('cv_id' => $cv_id));
  125. return $r;
  126. }
  127. /**
  128. * Retrieve the cv id for the specified CV by name
  129. *
  130. * NOTE: This function is deprecated.
  131. * @see tripal_core_chado_generate_vars()
  132. *
  133. * @param $cv_name
  134. * The unique name for the cv to retrieve
  135. *
  136. * @return
  137. * The numeric cv ID
  138. *
  139. * @ingroup tripal_cv_api
  140. */
  141. function tripal_cv_get_cv_id($cv_name) {
  142. $sql = "
  143. SELECT cv_id FROM {cv} WHERE name = '%s'
  144. ";
  145. $cv = db_fetch_object(chado_query($sql, $cv_name));
  146. return $cv->cv_id;
  147. }
  148. /**
  149. * Create an options array to be used in a form element which provides a
  150. * list of all chado cvs
  151. *
  152. * NOTE: This function is deprecated as of Tripal v1.0
  153. *
  154. * @return
  155. * An array(cv_id => name) for each cv in the chado cv table
  156. *
  157. * @ingroup tripal_cv_api
  158. */
  159. function tripal_cv_get_cv_options() {
  160. $results = tripal_core_chado_select('cv', array('cv_id', 'name'), array());
  161. $options = array();
  162. foreach ($results as $r) {
  163. $options[$r->cv_id] = $r->name;
  164. }
  165. return $options;
  166. }
  167. /**
  168. * Retrieve a chado cvterm object with a given name
  169. *
  170. * @param $cvterm_id
  171. * the cvterm.cvterm_id
  172. *
  173. * @return
  174. * cvterm array or FALSE on error
  175. *
  176. * @ingroup tripal_cv_api
  177. */
  178. function tripal_cv_get_cvterm_by_id($cvterm_id) {
  179. if (!is_numeric($cvterm_id)) {
  180. return FALSE;
  181. }
  182. $values = array('cvterm_id' => $cvterm_id);
  183. $options = array('statement_name' => 'sel_cvterm_id');
  184. $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
  185. if (!$r) {
  186. return FALSE;
  187. }
  188. return $r[0];
  189. }
  190. /**
  191. * Retrieve a chado cvterm object with a given name
  192. *
  193. * @param $name
  194. * the cvterm.name
  195. * @param $cv_id
  196. * the cv_id of the term you are looking for
  197. * @param $cv_name
  198. * the name of the CV
  199. *
  200. * @return
  201. * cvterm array or FALSE on error
  202. *
  203. * @ingroup tripal_cv_api
  204. */
  205. function tripal_cv_get_cvterm_by_name($name, $cv_id = NULL, $cv_name = 'tripal') {
  206. if ($cv_id) {
  207. $values = array(
  208. 'name' => $name,
  209. 'cv_id' => $cv_id,
  210. );
  211. $options = array(
  212. 'statement_name' => 'sel_cvterm_nacv',
  213. 'case_insensitive_columns' => array('name')
  214. );
  215. $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
  216. }
  217. elseif ($cv_name) {
  218. $values = array(
  219. 'name' => $name,
  220. 'cv_id' => array(
  221. 'name' => $cv_name,
  222. ),
  223. );
  224. $options = array(
  225. 'statement_name' => 'sel_cvterm_nacv',
  226. 'case_insensitive_columns' => array('name')
  227. );
  228. $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
  229. }
  230. else {
  231. $values = array(
  232. 'name' => $name,
  233. );
  234. $options = array(
  235. 'statement_name' => 'sel_cvterm_na',
  236. 'case_insensitive_columns' => array('name')
  237. );
  238. $r = tripal_core_chado_select('cvterm', array('*'), $values, $options);
  239. }
  240. if (!$r) {
  241. return FALSE;
  242. }
  243. if (count($r) > 1) {
  244. watchdog('tripal_cv', "Cannot find a unique term for the term '%name' in the vocabulary '%cv'. Multiple entries exist for this name",
  245. array('%name' => $name, '%cv' => $cv_name ? $cv_name : $cv_id), WATCHDOG_ERROR);
  246. return FALSE;
  247. }
  248. if (count($r) == 0) {
  249. return FALSE;
  250. }
  251. return $r[0];
  252. }
  253. /**
  254. * Retrieve a chado cvterm object with a given name
  255. *
  256. * @param $synonym
  257. * the synonym of the term
  258. * @param $cv_id
  259. * the cv_id of the term you are looking for
  260. * @param $cv_name
  261. * the name of the CV
  262. *
  263. * @return
  264. * cvterm object
  265. *
  266. * @ingroup tripal_cv_api
  267. */
  268. function tripal_cv_get_cvterm_by_synonym($synonym, $cv_id = NULL, $cv_name = 'tripal') {
  269. // first find the CVTerm synonym
  270. $values = array(
  271. 'synonym' => $synonym,
  272. );
  273. $statement = "sel_cvtermsynonym_sy";
  274. if ($cv_id) {
  275. $values['cvterm_id'] = array('cv_id' => $cv_id);
  276. $statement = "sel_cvtermsynonym_sycv";
  277. }
  278. if ($cv_name) {
  279. $values['cvterm_id'] = array('cv_id' => array('name' => $cv_name));
  280. $statement = "sel_cvtermsynonym_sycv";
  281. }
  282. $options = array(
  283. 'statement_name' => $statement,
  284. 'case_insensitive_columns' => array('name')
  285. );
  286. $synonym = tripal_core_chado_select('cvtermsynonym', array('cvterm_id'), $values, $options);
  287. // if the synonym doens't exist or more than one record is returned then return false
  288. if(count($synonym) == 0) {
  289. return FALSE;
  290. }
  291. if(count($synonym) > 1) {
  292. return FALSE;
  293. }
  294. // get the cvterm
  295. $values = array('cvterm_id' => $synonym[0]->cvterm_id);
  296. $options = array('statement_name' => 'sel_cvterm_id');
  297. $cvterm = tripal_core_chado_select('cvterm', array('*'), $values, $options);
  298. return $cvterm[0];
  299. }
  300. /**
  301. * Create an options array to be used in a form element
  302. * which provides a list of all chado cvterms
  303. *
  304. * @param $cv_id
  305. * The chado cv_id;
  306. * only cvterms with the supplied cv_id will be returned
  307. * @return
  308. * An array(cvterm_id => name)
  309. * for each cvterm in the chado cvterm table where cv_id=that supplied
  310. *
  311. * @ingroup tripal_cv_api
  312. */
  313. function tripal_cv_get_cvterm_options($cv_id = 0) {
  314. if ($cv_id > 0) {
  315. $results = tripal_core_chado_select('cvterm', array('cvterm_id', 'name'), array('cv_id' => $cv_id));
  316. }
  317. else {
  318. $results = tripal_core_chado_select('cvterm', array('cvterm_id', 'name'), array());
  319. }
  320. $options = array();
  321. foreach ($results as $r) {
  322. $options[$r->cvterm_id] = $r->name;
  323. }
  324. return $options;
  325. }
  326. /**
  327. * Updates the cvtermpath table of Chado for the specified CV.
  328. *
  329. * @param $cv_id
  330. * The chado cv_id;
  331. * @param $job_id
  332. * This function is intended to be used with the Tripal Jobs API.
  333. * When this function is called as a job the $job_id is automatically
  334. * passed to this function.
  335. * @return
  336. * TRUE on success FALSE on failure
  337. *
  338. * @ingroup tripal_cv_api
  339. */
  340. function tripal_cv_update_cvtermpath($cvid, $job_id = NULL) {
  341. // TODO: need better error checking in this function
  342. // first get the controlled vocabulary name:
  343. $cv = db_fetch_object(chado_query("SELECT * FROM {cv} WHERE cv_id = %d", $cvid));
  344. print "\nUpdating cvtermpath for $cv->name...\n";
  345. // now fill the cvtermpath table
  346. // @coder-ignore: using a function rather then tablename therefore table prefixing doesn't apply
  347. $sql = "SELECT * FROM fill_cvtermpath('%s')";
  348. $success = chado_query($sql, $cv->name);
  349. return TRUE;
  350. }
  351. /**
  352. * Adds a controlled vocabular to the CV table of Chado.
  353. *
  354. * @param $name
  355. * The name of the controlled vocabulary. These are typically all lower case
  356. * with no special characters other than an undrescore (for spaces).
  357. * @param $comment
  358. * A description or definition of the vocabulary.
  359. *
  360. * @return
  361. * An object populated with fields from the newly added database.
  362. *
  363. * @ingroup tripal_cv_api
  364. */
  365. function tripal_cv_add_cv($name, $definition) {
  366. // insert/update values
  367. $ins_values = array(
  368. 'name' => $name,
  369. 'definition' => $definition
  370. );
  371. // see if the CV (default-namespace) exists already in the database
  372. $sel_values = array('name' => $name);
  373. $sel_options = array('statement_name' => 'sel_cv_na');
  374. $results = tripal_core_chado_select('cv', array('*'), $sel_values, $sel_options);
  375. // if it does not exists then add it
  376. if (count($results) == 0) {
  377. $ins_options = array('statement_name' => 'ins_cv_nade');
  378. $success = tripal_core_chado_insert('cv', $ins_values, $ins_options);
  379. if (!$success) {
  380. watchdog('tripal_cv', "Failed to create the CV record", NULL, WATCHDOG_WARNING);
  381. return FALSE;
  382. }
  383. $results = tripal_core_chado_select('cv', array('*'), $sel_values, $sel_options);
  384. }
  385. // if it already exists then do an update
  386. else {
  387. $upd_options = array('statement_name' => 'upd_cv_nade');
  388. $success = tripal_core_chado_update('cv', $sel_values, $ins_values, $upd_options);
  389. if (!$success) {
  390. watchdog('tripal_cv', "Failed to update the CV record", NULL, WATCHDOG_WARNING);
  391. return FALSE;
  392. }
  393. $results = tripal_core_chado_select('cv', array('*'), $sel_values, $sel_options);
  394. }
  395. // return the cv object
  396. return $results[0];
  397. }
  398. /**
  399. * Add's a CV term to the cvterm table. If the parent CV does not exist then
  400. * that too is added to the CV table. If the cvterm is a relationship term
  401. * then the $is_relationship argument should be set. The function will try
  402. * to first find the relationship in the relationship ontology for updating and
  403. * if it can't be found will add the relationship to the __global CV. All terms
  404. * must also have a corresponding database. This is specified in the term's
  405. * ID just before the colon (e.g. GO:003824). If the database does not exist
  406. * in the DB table then it will be added automatically. The accession (the
  407. * value just after the colon in the term's ID) will be added to the dbxref
  408. * table. If the CVterm already exists and $update is set (default) then the
  409. * cvterm is updated. If the CVTerm already exists and $update is not set, then
  410. * no changes are made and the CVTerm object is returned.
  411. *
  412. * @param $term
  413. * An associative array with the following keys: 'id', 'name' and 'namespace',
  414. * 'is_obsolete', and 'def'. Where 'id' is the term accession, 'name' is the
  415. * term name, 'namespace' is the CV name for the term, 'def' is the term
  416. * definition and 'is_obsolete' is present and set to 1 if the term is defunct.
  417. * The 'id' must be of the form <DB>:<ACCESSION>, where <DB> is the name of
  418. * the database to which the cvterm belongs and the <ACCESSION> is the
  419. * term's accession number in the database.
  420. * @param $defaultcv
  421. * Optional. The CV name to which the term
  422. * belongs. If this arugment is null or not provided then the function tries
  423. * to find a record in the CV table with the same name provided in the
  424. * $term[namespace]. If this field is provided then it overrides what the
  425. * value in $term[namespace]
  426. * @param $is_relationship
  427. * If this term is a relationship term then this value should be 1.
  428. * @param $update
  429. * By default this is set to 1. If the term exists it is automatically updated.
  430. * @param $dbname
  431. * In some cases the database name will not be part of the $term['id'] and it
  432. * needs to be explicitly set. Use this argument only if the database name
  433. * cannot be specififed in the term ID (e.g. <DB>:<ACCESSION>).
  434. *
  435. * @return
  436. * A CVTerm object
  437. *
  438. * @ingroup tripal_cv_api
  439. */
  440. function tripal_cv_add_cvterm($term, $defaultcv = '_global', $is_relationship = 0,
  441. $update = 1, $dbname = 'internal') {
  442. // get the term properties
  443. $id = $term['id'];
  444. $name = '';
  445. $cvname = '';
  446. $definition = '';
  447. $is_obsolete = 0;
  448. $accession = '';
  449. if (array_key_exists('name', $term)) {
  450. $name = $term['name'];
  451. }
  452. else {
  453. $name = $id;
  454. }
  455. if (array_key_exists('namespace', $term)) {
  456. $cvname = $term['namespace'];
  457. }
  458. else {
  459. $cvname = $defaultcv;
  460. }
  461. if (array_key_exists('def', $term)) {
  462. $definition = preg_replace('/^\"(.*)\"/', '\1', $term['def']);
  463. }
  464. else {
  465. $definition = '';
  466. }
  467. if (array_key_exists('is_obsolete', $term)) {
  468. $is_obsolete = $term['is_obsolete'];
  469. if (strcmp($is_obsolete, 'true') == 0) {
  470. $is_obsolete = 1;
  471. }
  472. }
  473. if (!$name and !$id) {
  474. watchdog('tripal_cv', "Cannot find cvterm without 'id' or 'name'", NULL, WATCHDOG_WARNING);
  475. return 0;
  476. }
  477. if (!$id) {
  478. $id = $name;
  479. }
  480. // get the accession and the database from the cvterm id
  481. if ($dbname) {
  482. $accession = $id;
  483. }
  484. if (preg_match('/^.+?:.*$/', $id)) {
  485. $accession = preg_replace('/^.+?:(.*)$/', '\1', $id);
  486. $dbname = preg_replace('/^(.+?):.*$/', '\1', $id);
  487. }
  488. // check that we have a database name, give a different message if it's a relationship
  489. if ($is_relationship and !$dbname) {
  490. watchdog('tripal_cv', "A database name is not provided for this relationship term: $id", NULL, WATCHDOG_WARNING);
  491. return 0;
  492. }
  493. if (!$is_relationship and !$dbname) {
  494. watchdog('tripal_cv', "A database identifier is missing from the term: $id", NULL, WATCHDOG_WARNING);
  495. return 0;
  496. }
  497. // make sure the CV name exists
  498. $cv = tripal_cv_add_cv($cvname, '');
  499. if (!$cv) {
  500. watchdog('tripal_cv', "Cannot find namespace '$cvname' when adding/updating $id", NULL, WATCHDOG_WARNING);
  501. return 0;
  502. }
  503. // this SQL statement will be used a lot to find a cvterm so just set it
  504. // here for easy reference below. Because CV terms can change their names
  505. // but accessions don't change, the following SQL finds cvterms based on
  506. // their accession rather than the name
  507. if (!tripal_core_is_sql_prepared('sel_cvterm_by_accession')) {
  508. $pcvtermsql = "
  509. PREPARE sel_cvterm_by_accession(text, text) AS
  510. SELECT CVT.name, CVT.cvterm_id, CV.cv_id, CV.name as cvname,
  511. DB.name as dbname, DB.db_id, DBX.accession
  512. FROM {cvterm} CVT
  513. INNER JOIN {dbxref} DBX on CVT.dbxref_id = DBX.dbxref_id
  514. INNER JOIN {db} DB on DBX.db_id = DB.db_id
  515. INNER JOIN {cv} CV on CV.cv_id = CVT.cv_id
  516. WHERE DBX.accession = $1 and DB.name = $2";
  517. if (!tripal_core_chado_prepare('sel_cvterm_by_accession', $pcvtermsql, array('text', 'text'))) {
  518. watchdog('tripal_cv', "Cannot prepare statement 'sel_cvterm_by_accession'", NULL, WATCHDOG_WARNING);
  519. return 0;
  520. }
  521. }
  522. $cvtermsql = "EXECUTE sel_cvterm_by_accession('%s','%s')";
  523. // add the database. The function will just return the DB object if the
  524. // database already exists.
  525. $db = tripal_db_add_db($dbname);
  526. if (!$db) {
  527. watchdog('tripal_cv', "Cannot find database '$dbname' in Chado.", NULL, WATCHDOG_WARNING);
  528. return 0;
  529. }
  530. // the cvterm table has two unique dependencies. We need to check both.
  531. // first check the (name, cv_id, is_obsolete) constraint
  532. $values = array(
  533. 'name' => $name,
  534. 'is_obsolete' => $is_obsolete,
  535. 'cv_id' => array(
  536. 'name' => $cvname,
  537. ),
  538. );
  539. $options = array('statement_name' => 'sel_cvterm_c1');
  540. $result = tripal_core_chado_select('cvterm', array('*'), $values, $options);
  541. // if the constraint is met then let's check it to see if
  542. // the database name matches the one we have been provided
  543. if (count($result) == 1) {
  544. $cvterm = $result[0];
  545. // get the dbxref record
  546. $values = array('dbxref_id' => $cvterm->dbxref_id);
  547. $options = array('statement_name' => 'sel_dbxref_id');
  548. $result = tripal_core_chado_select('dbxref', array('*'), $values, $options);
  549. $dbxref = $result[0];
  550. // get the db
  551. $values = array('db_id' => $dbxref->db_id);
  552. $options = array('statement_name' => 'sel_db_id');
  553. $result = tripal_core_chado_select('db', array('*'), $values, $options);
  554. $db_check = $result[0];
  555. // the database name for this existing term does not match that of the
  556. // one provided to this function. The CV name matches otherwise we
  557. // wouldn't have made it this far. So, let's swap the database for
  558. // this term
  559. if ($db_check->name != $db->name) {
  560. // look to see if the correct dbxref record already exists for this database
  561. $values = array(
  562. 'db_id' => $db->db_id,
  563. 'accession' => $accession,
  564. );
  565. $options = array('statement_name' => 'sel_dbxref_idac');
  566. $result = tripal_core_chado_select('dbxref', array('*'), $values, $options);
  567. // if we already have a good dbxref then we want to update our cvterm
  568. // to use this dbxref
  569. if (count($result) > 0) {
  570. $dbxref = $result[0];
  571. $match = array('cvterm_id' => $cvterm->cvterm_id);
  572. $values = array('dbxref_id' => $dbxref->dbxref_id);
  573. $options = array('statement_name' => 'upd_cvterm_db');
  574. $success = tripal_core_chado_update('cvterm', $match, $values, $options);
  575. if (!$success) {
  576. watchdog('tripal_cv', "Failed to correct the dbxref id for the cvterm " .
  577. "'$name' (id: $accession), for database $dbname", NULL, WATCHDOG_WARNING);
  578. return 0;
  579. }
  580. }
  581. // if we don't have the record then we want to delete our cvterm and let the code
  582. // below recreate it with the correct info
  583. else {
  584. $match = array('cvterm_id' => $cvterm->cvterm_id);
  585. $options = array('statement_name' => 'del_cvterm_cv');
  586. tripal_core_chado_delete('cvterm', $match, $options);
  587. }
  588. }
  589. // check that the accession matches. Sometimes an OBO can define the same term
  590. // multiple times but with different accessions. If this is the case we
  591. // can't do an insert or it will violate the constraint in the cvterm table.
  592. // so we'll need to add the record to the cvterm_dbxref table instead
  593. if ($dbxref->accession != $accession) {
  594. // get/add the dbxref fort his term
  595. $dbxref_new = tripal_db_add_dbxref($db->db_id, $accession);
  596. if (!$dbxref_new) {
  597. watchdog('tripal_cv', "Failed to find or insert the dbxref record for cvterm, " .
  598. "$name (id: $accession), for database $dbname", NULL, WATCHDOG_WARNING);
  599. return 0;
  600. }
  601. // check to see if the cvterm_dbxref record already exists
  602. $values = array(
  603. 'cvterm_id' => $cvterm->cvterm_id,
  604. 'dbxref_id' => $dbxref_new->dbxref_id,
  605. 'is_for_definition' => 1,
  606. );
  607. $options = array('statement_name' => 'sel_cvtermdbxref_cvdbis');
  608. $result = tripal_core_chado_select('cvterm_dbxref', array('*'), $values, $options);
  609. // if the cvterm_dbxref record does not exists then add it
  610. if (count($result)==0) {
  611. $options = array(
  612. 'statement_name' => 'ins_cvtermdbxref_cvdbis',
  613. 'return_record' => FALSE,
  614. );
  615. $success = tripal_core_chado_insert('cvterm_dbxref', $values, $options);
  616. if (!$success) {
  617. watchdog('tripal_cv', "Failed to find or insert the cvterm_dbxref record for a " .
  618. "duplicated cvterm: $name (id: $accession), for database $dbname", NULL, WATCHDOG_WARNING);
  619. return 0;
  620. }
  621. }
  622. // get the original cvterm with the same name and return that.
  623. $cvterm = db_fetch_object(chado_query($cvtermsql, $dbxref->accession, $dbname));
  624. return $cvterm;
  625. }
  626. // continue on, we've fixed the record if the db_id did not match,
  627. // we can now perform and updated if we need to.
  628. }
  629. // get the CVterm record
  630. $cvterm = db_fetch_object(chado_query($cvtermsql, $accession, $dbname));
  631. //print "$pcvtermsql\n$cvtermsql\n$accession, $dbname\n";
  632. //print "CVTERM:\n";
  633. //print_r($cvterm);
  634. if (!$cvterm) {
  635. // check to see if the dbxref exists if not, add it
  636. $dbxref = tripal_db_add_dbxref($db->db_id, $accession);
  637. if (!$dbxref) {
  638. watchdog('tripal_cv', "Failed to find or insert the dbxref record for cvterm, " .
  639. "$name (id: $accession), for database $dbname", NULL, WATCHDOG_WARNING);
  640. return 0;
  641. }
  642. // check to see if the dbxref already has an entry in the cvterm table
  643. // this is the second constraint in the cvterm table
  644. $values = array('dbxref_id' => $dbxref->dbxref_id);
  645. $options = array('statement_name' => 'sel_cvterm_db');
  646. $check = tripal_core_chado_select('cvterm', array('cvterm_id'), $values, $options);
  647. if (count($check) == 0) {
  648. // now add the cvterm
  649. $ins_values = array(
  650. 'cv_id' => $cv->cv_id,
  651. 'name' => $name,
  652. 'definition' => $definition,
  653. 'dbxref_id' => $dbxref->dbxref_id,
  654. 'is_obsolete' => $is_obsolete,
  655. 'is_relationshiptype' => $is_relationship,
  656. );
  657. $ins_options = array('statement_name' => 'ins_cvterm_all');
  658. $success = tripal_core_chado_insert('cvterm', $ins_values, $ins_options);
  659. if (!$success) {
  660. if (!$is_relationship) {
  661. watchdog('tripal_cv', "Failed to insert the term: $name ($dbname)", NULL, WATCHDOG_WARNING);
  662. return 0;
  663. }
  664. else {
  665. watchdog('tripal_cv', "Failed to insert the relationship term: $name (cv: " . $cvname . " db: $dbname)", NULL, WATCHDOG_WARNING);
  666. return 0;
  667. }
  668. }
  669. }
  670. // this dbxref already exists in the cvterm table
  671. else {
  672. watchdog('tripal_cv', "The dbxref already exists for another cvterm record: $name (cv: " . $cvname . " db: $dbname)", NULL, WATCHDOG_WARNING);
  673. return 0;
  674. }
  675. $cvterm = db_fetch_object(chado_query($cvtermsql, $accession, $dbname));
  676. }
  677. // upate the cvterm
  678. elseif ($update) {
  679. $match = array('cvterm_id' => $cvterm->cvterm_id);
  680. $upd_values = array(
  681. 'name' => $name,
  682. 'definition' => $definition,
  683. 'is_obsolete' => $is_obsolete,
  684. 'is_relationshiptype' => $is_relationship,
  685. );
  686. $upd_options = array('statement_name' => 'upd_cvterm_nadeisis');
  687. $success = tripal_core_chado_update('cvterm', $match, $upd_values, $upd_options);
  688. if (!$success) {
  689. watchdog('tripal_cv', "Failed to update the term: $name", NULL, WATCHDOG_WARNING);
  690. return 0;
  691. }
  692. $cvterm = db_fetch_object(chado_query($cvtermsql, $accession, $dbname));
  693. }
  694. else {
  695. // do nothing, we have the cvterm but we don't want to update
  696. }
  697. // return the cvterm
  698. return $cvterm;
  699. }
  700. /**
  701. * This function defines the custom tables that will be created
  702. * in the chado schema.
  703. *
  704. * @ingroup tripal_cv_api
  705. */
  706. function tripal_cv_get_custom_tables($table = NULL) {
  707. if (!$table or strcmp($table, 'tripal_obo_temp')==0) {
  708. $schema['tripal_obo_temp'] = array(
  709. 'table' => 'tripal_obo_temp',
  710. 'fields' => array(
  711. 'id' => array(
  712. 'type' => 'varchar',
  713. 'length' => '255',
  714. 'not null' => TRUE,
  715. ),
  716. 'stanza' => array(
  717. 'type' => 'text',
  718. 'not null' => TRUE,
  719. ),
  720. 'type' => array(
  721. 'type' => 'varchar',
  722. 'length' => '50',
  723. 'not null' => TRUE,
  724. ),
  725. ),
  726. 'indexes' => array(
  727. 'tripal_obo_temp_idx0' => array('id'),
  728. 'tripal_obo_temp_idx0' => array('type'),
  729. ),
  730. 'unique keys' => array(
  731. 'tripal_obo_temp_uq0' => array('id'),
  732. ),
  733. );
  734. }
  735. return $schema;
  736. }
  737. /**
  738. * This function allows other modules to programatically
  739. * submit an ontology for loading into Chado. This function
  740. * will add a job to the Jobs subsystem for parsing the ontology.
  741. * You can either pass a known OBO ID to the function or the URL
  742. * or full path the the ontology file. If a URL or file name is
  743. * passed then the $obo_name argument must also be provided. If
  744. * this is the first time the ontology has been provided to Tripal
  745. * then it will be added to the database and will be assigned a
  746. * unique OBO ID.
  747. *
  748. * @param $obo_id
  749. * If the ontology is already loaded into the Tripal tables then
  750. * use this argument to specify the unique ID for the ontology
  751. * that will be loaded
  752. * @param $obo_name
  753. * If the OBO has not been added before then use this argument
  754. * to specify the human readable name of the ontology.
  755. * @param $obo_url
  756. * If the OBO to be loaded is located on a remote server then
  757. * use this argument to provide the URL.
  758. * @param $obo_file
  759. * If the OBO is housed on the local file system of the server then
  760. * use this argument to specify the full path.
  761. *
  762. * @return
  763. * returns the job_id of the submitted job or FALSE if the job was not added
  764. *
  765. * @ingroup tripal_cv_api
  766. */
  767. function tripal_cv_submit_obo_job($obo_id = NULL, $obo_name = NULL, $obo_url = NULL, $obo_file = NULL) {
  768. global $user;
  769. if ($obo_id) {
  770. $sql = "SELECT * FROM {tripal_cv_obo} WHERE obo_id = %d";
  771. $obo = db_fetch_object(db_query($sql, $obo_id));
  772. $args = array($obo_id);
  773. return tripal_add_job("Load OBO $obo->name", 'tripal_cv',
  774. "tripal_cv_load_obo_v1_2_id", $args, $user->uid);
  775. }
  776. else {
  777. if ($obo_url) {
  778. $args = array($obo_name, $obo_url);
  779. return tripal_add_job("Load OBO $obo_name", 'tripal_cv',
  780. "tripal_cv_load_obo_v1_2_url", $args, $user->uid);
  781. }
  782. elseif ($obo_file) {
  783. $args = array($obo_name, $obo_file);
  784. return tripal_add_job("Load OBO $obo_name", 'tripal_cv',
  785. "tripal_cv_load_obo_v1_2_file", $args, $user->uid);
  786. }
  787. }
  788. return FALSE;
  789. }
  790. /**
  791. * Add the obo to the tripal_cv_obo table in the Drupal database
  792. *
  793. * @param $name
  794. * The human readable name of this ontology
  795. * @param $path
  796. * The file path or URL of the ontology
  797. *
  798. * @return
  799. * Returns the ontology ID
  800. *
  801. * @ingroup tripal_cv_api
  802. */
  803. function tripal_cv_add_obo_ref($name, $path) {
  804. $record = new stdClass;
  805. $record->name = $name;
  806. $record->path = $path;
  807. drupal_write_record('tripal_cv_obo', $record);
  808. return $record->obo_id;
  809. }
  810. /**
  811. * This function is intended to be used in autocomplete forms
  812. * for searching for CV terms that begin with the provided string
  813. *
  814. * @param $cv_id
  815. * The CV ID in which to search for the term
  816. * @param $string
  817. * The string to search for
  818. *
  819. * @return
  820. * A json array of terms that begin with the provided string
  821. *
  822. * @ingroup tripal_cv_api
  823. */
  824. function tripal_cv_cvterm_name_autocomplete($cv_id, $string = '') {
  825. $sql = "
  826. SELECT cvterm_id, name
  827. FROM {cvterm}
  828. WHERE cv_id = %d and lower(name) like lower('%s%%')
  829. ORDER by name
  830. ";
  831. $results = chado_query($sql, $cv_id, $string);
  832. $items = array();
  833. while($term = db_fetch_object($results)) {
  834. $items[$term->name] = $term->name;
  835. }
  836. drupal_json($items);
  837. }

Related topics