tripal_chado/src/Database/ChadoSchema.php
<?php
namespace Drupal\tripal_chado\Database;
use Symfony\Component\Yaml\Yaml;
use Drupal\tripal\TripalDBX\TripalDbxSchema;
use Drupal\tripal\TripalDBX\Exceptions\SchemaException;
/**
* Chado schema class.
*/
class ChadoSchema extends TripalDbxSchema {
/**
* {@inheritdoc}
*/
public function getSchemaDef(array $parameters) :array {
static $schema_structure = [];
$source = $parameters['source'] ?? 'file';
$format = strtolower($parameters['format'] ?? '');
$version = $parameters['version']
?? $this->connection->getVersion()
?? $DEFAULT_VERSION
;
if (!empty($parameters['clear'])) {
$schema_structure = [];
}
if ('none' == $format) {
return [];
}
// Adjust cache key.
if ('database' == $source) {
// Make sure we got a schema to work on.
if (empty($this->defaultSchema)) {
throw new SchemaException("No schema to work on.");
}
$version = $this->defaultSchema;
}
$cache_key = $source . '-' . $format . '-' . $version;
// Check cache and compute if needed.
if (empty($schema_structure[$cache_key])) {
if ('file' == $source) {
$filename =
\Drupal::service('extension.list.module')->getPath('tripal_chado')
. '/chado_schema/chado_schema-'
. $version
. '.yml'
;
// Make sure we got a valid version format.
if (!preg_match('/^\\d\\.\\d$/', $version)
|| !file_exists($filename)
) {
throw new SchemaException("Invalid or unsupported Chado schema version '$version'.");
}
$schema_structure[$cache_key] =
Yaml::parse(file_get_contents($filename));
}
elseif ('database' == $source) {
// Use Schema object to fetch each table structures from database.
$schema_def = [];
$tables = $this->getTables();
foreach (array_keys($tables) as $table) {
$schema_def[$table] =
$this->getTableDef($table, $parameters);
}
$schema_structure[$cache_key] = $schema_def;
}
else {
throw new SchemaException("Invalid schema definition source '$source'.");
}
}
return $schema_structure[$cache_key];
}
/**
* Returns all chado base tables.
*
* Base tables are those that contain the primary record for a data type.
* For
* example, feature, organism, stock, are all base tables. Other tables
* include linker tables (which link two or more base tables), property
* tables, and relationship tables. These provide additional information
* about primary data records and are therefore not base tables. This
* function retreives only the list of tables that are considered 'base'
* tables.
*
* @return
* An array of base table names.
*/
public function getMainTables() {
// Initialize the base tables with those tables that are missing a type.
// Ideally they should have a type, but that's for a future version of Chado.
$base_tables = [
'organism',
'project',
'analysis',
'biomaterial',
'eimage',
'assay',
];
// We'll use the cvterm table to guide which tables are base tables. Typically
// base tables (with a few exceptions) all have a type. Iterate through the
// referring tables.
$schema = $this->getTableSchema('cvterm');
if (isset($schema['referring_tables'])) {
foreach ($schema['referring_tables'] as $tablename) {
// Ignore the cvterm tables, relationships, chadoprop tables.
if ($tablename == 'cvterm_dbxref' || $tablename == 'cvterm_relationship' ||
$tablename == 'cvtermpath' || $tablename == 'cvtermprop' || $tablename == 'chadoprop' ||
$tablename == 'cvtermsynonym' || preg_match('/_relationship$/', $tablename) ||
preg_match('/_cvterm$/', $tablename) ||
// Ignore prop tables
preg_match('/prop$/', $tablename) || preg_match('/prop_.+$/', $tablename) ||
// Ignore nd_tables
preg_match('/^nd_/', $tablename)) {
continue;
}
else {
array_push($base_tables, $tablename);
}
}
}
// Remove any linker tables that have snuck in. Linker tables are those
// whose foreign key constraints link to two or more base table.
$final_list = [];
foreach ($base_tables as $i => $tablename) {
// A few tables break our rule and seems to look
// like a linking table, but we want to keep it as a base table.
if ($tablename == 'biomaterial' or $tablename == 'assay' or $tablename == 'arraydesign') {
$final_list[] = $tablename;
continue;
}
// Remove the phenotype table. It really shouldn't be a base table as
// it is meant to store individual phenotype measurements.
if ($tablename == 'phenotype') {
continue;
}
$num_links = 0;
$schema = $this->getTableSchema($tablename);
$fkeys = $schema['foreign keys'];
foreach ($fkeys as $fkid => $details) {
$fktable = $details['table'];
if (in_array($fktable, $base_tables)) {
$num_links++;
}
}
if ($num_links < 2) {
$final_list[] = $tablename;
}
}
// Now add in the cvterm table to the list.
$final_list[] = 'cvterm';
// Sort the tables and return the list.
sort($final_list);
return $final_list;
}
/**
* Get information about which Chado base table a cvterm is mapped to.
*
* Vocbulary terms that represent content types in Tripal must be mapped to
* Chado tables. A cvterm can only be mapped to one base table in Chado.
* This function will return an object that contains the chado table and
* foreign key field to which the cvterm is mapped. The 'chado_table'
* property of the returned object contains the name of the table, and the
* 'chado_field' property contains the name of the foreign key field (e.g.
* type_id), and the
* 'cvterm' property contains a cvterm object.
*
* @params
* An associative array that contains the following keys:
* - cvterm_id: the cvterm ID value for the term.
* - vocabulary: the short name for the vocabulary (e.g. SO, GO, PATO)
* - accession: the accession for the term.
* - bundle_id: the ID for the bundle to which a term is associated.
* The 'vocabulary' and 'accession' must be used together, the 'cvterm_id'
* can be used on it's own.
*
* @return
* An object containing the chado_table and chado_field properties or NULL
* if if no mapping was found for the term.
*
public function getCvtermMapping($params) {
return chado_get_cvterm_mapping($params);
}*/
}