<bridge_layer schema="godb">
  <notes>
    Bridge layer for GO Database schema - allows chado to "masquerade"
    as a GO-DB Schema, which means we can use go-db software; eg
    AmiGO. Currently read-only

    Activate this to make this bridge take precedence
    SET SEARCH_PATH TO godb,public;
    (note that placing godb first in the search path means
    that godb.dbxref takes precedence over public.dbxref)
  </notes>

  <relation id="instance_data">
    <sql>
 SELECT
      ''           AS release_name,
      ''           AS release_type,
      ''           AS release_notes;
    </sql>
  </relation>

  <relation id="go_acc">
    <notes>helper table - doesn't actually represent a godb
      table</notes>
    <notes>table name clash - be sure to prefix with schema name</notes>
    <sql>
 SELECT 
  dbxref_id                          AS dbxref_id,
  db.name || ':' || dbxref.accession AS acc
 FROM public.dbxref
  INNER JOIN public.db USING (db_id);
    </sql>
    <index>
CREATE INDEX go_acc_idx1 ON godb.go_acc (dbxref_id);
CREATE INDEX go_acc_idx2 ON godb.go_acc (acc);
    </index>
  </relation>
  
  <relation id="dbxref">
    <notes>table name clash - be sure to prefix with schema name</notes>
    <sql>
 SELECT
  dbxref_id                          AS id,
  db.name                            AS xref_dbname,
  dbxref.accession                   AS xref_key,
  CAST(NULL AS VARCHAR)              AS xref_keytype,
  dbxref.description                 AS xref_desc
 FROM public.dbxref
  INNER JOIN public.db USING (db_id);
    </sql>
    <index>
CREATE INDEX dbxref_idx1 ON godb.dbxref (id);
CREATE INDEX dbxref_idx2 ON godb.dbxref (xref_dbname);
CREATE INDEX dbxref_idx3 ON godb.dbxref (xref_key);
CREATE INDEX dbxref_idx4 ON godb.dbxref (xref_keytype);
CREATE INDEX dbxref_idx5 ON godb.dbxref (xref_desc);
    </index>
  </relation>

   <relation id="db">
    <notes>table name clash - be sure to prefix with schema name.
      (note in godb, db is only refered to from association table)
    </notes>
    <notes>This table is not used much by the go db code, no need to materialize</notes>
    <sql>
 SELECT
  db_id                                 AS id,
  name                                  AS name,
  name                                  AS fullname,
  CAST(NULL AS VARCHAR)                 AS datatype,
  CAST(NULL AS VARCHAR)                 AS url_syntax
 FROM public.db;
    </sql>
  </relation>
  
  <relation id="term">
    <sql>
SELECT
 cvterm_id       AS id,
 godb.go_acc.acc AS acc,
 name            AS name,
 is_obsolete     AS is_obsolete,
 0               AS is_root
FROM 
 public.cvterm
 INNER JOIN godb.go_acc USING (dbxref_id);
    </sql>
    <index>
CREATE INDEX term_idx1 ON godb.term (id);
CREATE INDEX term_idx2 ON godb.term (acc);
CREATE INDEX term_idx3 ON godb.term (name);
CREATE INDEX term_idx4 ON godb.term (is_obsolete);
CREATE INDEX term_idx5 ON godb.term (is_root);
    </index>
    <extra>
UPDATE term SET is_root = 1
WHERE id IN (SELECT cvterm_id FROM cvterm
      WHERE NOT EXISTS (
       SELECT subject_id FROM
       cvterm_relationship WHERE subject_id=cvterm_id) 
      AND is_obsolete = 0 AND is_relationshiptype = 0);
    </extra>
  </relation>

  <relation id="term_definition">
    <sql>
SELECT
 cvterm_id AS term_id,
 definition AS term_definition,
 CAST('' AS VARCHAR) AS term_comment
FROM public.cvterm
WHERE definition IS NOT NULL;
    </sql>
  </relation>



  <relation id="term_dbxref">
    <sql>
SELECT
 cvterm_id AS term_id,
 dbxref_id  AS dbxref_id,
 is_for_definition
FROM public.cvterm_dbxref;
    </sql>
  </relation>



  <relation id="term_synonym">
    <sql>
SELECT
 cvterm_id AS term_id,
 synonym  AS term_synonym,
 type_id AS synonym_type_id
FROM public.cvtermsynonym;
    </sql>
  </relation>



  <relation id="term2term">
    <sql>
SELECT
 cvterm_relationship_id AS id,
 type_id           AS relationship_type_id,
 object_id         AS term1_id,
 subject_id        AS term2_id
FROM public.cvterm_relationship;
    </sql>
    <index>
CREATE INDEX term2term_idx1 ON godb.term2term (id);
CREATE INDEX term2term_idx2 ON godb.term2term (relationship_type_id);
CREATE INDEX term2term_idx3 ON godb.term2term (term1_id);
CREATE INDEX term2term_idx4 ON godb.term2term (term2_id);
    </index>
  </relation>



  <relation id="graph_path">
    <sql>
SELECT
 cvtermpath_id      AS id,
 object_id      AS term1_id,
 subject_id     AS term2_id,
 pathdistance   AS distance
FROM public.cvtermpath;
    </sql>
    <notes>
CREATE INDEX graph_path_idx1 ON godb.graph_path (id);
CREATE INDEX graph_path_idx2 ON godb.graph_path (term1_id);
CREATE INDEX graph_path_idx3 ON godb.graph_path (term2_id);
CREATE INDEX graph_path_idx4 ON godb.graph_path (distance);
    </notes>
  </relation>

  <relation id="species">
    <sql>SELECT
  organism_id                        AS id,
--  CAST(accession AS INT)             AS ncbi_taxa_id,
  accession                          AS ncbi_taxa_id,
  common_name,
  CAST(NULL AS VARCHAR)              AS lineage_string,
  genus,
  species
 FROM
  organism
  INNER JOIN public.organism_dbxref USING (organism_id)
  INNER JOIN public.dbxref USING (dbxref_id)
  INNER JOIN public.db     USING (db_id)
 WHERE db.name='NCBITaxon';
    </sql>
  </relation>


  <relation id="gene_product">
    <notes>
--  note: secondary_species_id; eg for host species with parasite
--        this will be handled by a feature_relationship in chado
    </notes>
    <sql>SELECT
  feature_id                    AS id,
  name                          AS symbol,
  dbxref_id                     AS dbxref_id,
  organism_id                   AS species_id,
  CAST(NULL AS INT)             AS secondary_species_id,
  type_id,
-- todo: make this a left outer join on a featureprop
  name                          AS fullname
 FROM public.feature;
    </sql>
  </relation>

  <relation id="gene_product_synonym">
    <sql>SELECT
  feature_id                    AS gene_product_id,
  synonym.name                  AS product_synonym
 FROM
  feature_synonym INNER JOIN public.synonym USING (synonym_id);
    </sql>
  </relation>

  <relation id="gene_product_property">
    <sql>SELECT
  feature_id                    AS gene_product_id,
  prop.name                     AS property_key,
  value                         AS property_value
 FROM
  featureprop INNER JOIN public.cvterm AS prop ON (type_id=cvterm_id);
    </sql>
  </relation>

  <relation id="association">
    <sql>SELECT
  feature_cvterm_id             AS id,
  cvterm_id                     AS term_id,
  feature_id                    AS gene_product_id,
  is_not,
-- not used in godb; maybe never will be
  0                             AS role_group,
-- lets be lazy for now; these are actually feature_cvtermprops
  0                             AS assocdate,
  0                             AS source_db_id
 FROM public.feature_cvterm;
    </sql>
  </relation>

  <relation id="association_qualifier">
    <sql>
 SELECT
  feature_cvtermprop_id         AS id,
  feature_cvterm_id             AS association_id,
  type_id                       AS term_id,
  value                         AS value
 FROM public.feature_cvtermprop;
    </sql>
  </relation>

  <relation id="evidence">
    <notes>TODO</notes>
    <sql>
 SELECT
  feature_cvtermprop_id         AS id,
  feature_cvterm_id             AS association_id,
  type_id                       AS term_id,
  value                         AS value
 FROM public.feature_cvtermprop
 INNER JOIN public.feature_cvterm_dbxref USING (feature_cvterm_id);
    </sql>
  </relation>


  <relation id="evidence_dbxref">
    <notes>TODO</notes>
    <sql>
 SELECT
  feature_cvterm_id         AS id,
  feature_cvterm_id             AS association_id,
  type_id                       AS term_id,
  value                         AS value
 FROM public.feature_cvtermprop
 INNER JOIN public.feature_cvterm_dbxref USING (feature_cvterm_id);
    </sql>
  </relation>

  <relation id="seq">
    <sql>
 SELECT
  feature_id                    AS id,
  feature.name                  AS display_id,
  feature.name                  AS description,
  residues                      AS seq,
  seqlen                        AS seq_len,
  md5checksum,
  type.name                     AS moltype,
-- this is never used
  0                             AS timestamp
 FROM public.feature INNER JOIN public.cvterm AS type ON (type_id=cvterm_id);
    </sql>
  </relation>

  <relation id="seq_property">
    <sql>
 SELECT
  *
 FROM public.feature WHERE NULL;
    </sql>
  </relation>

  <relation id="seq_dbxref">
    <notes>
      -- [in GO this typically has interpro ids, etc; diff semantics here]
    </notes>
    <sql>SELECT 
  feature_id                    AS seq_id,
  dbxref_id
 FROM public.feature_dbxref;
    </sql>
  </relation>

  <relation id="gene_product_seq">
    <notes>
      -- 1:{0,1} relationship between features and seqs in chado
    </notes>
    <sql>SELECT
  feature_id              AS gene_product_id,
  feature_id              AS seq_id
 FROM public.feature
 WHERE feature.residues IS NOT NULL;
    </sql>
  </relation>


  <relation id="gene_product_count">
    <notes>
-- this is an OPTIONAL godb optimization
--  simulate a rowless table for now
    </notes>
    <sql>SELECT
  *
 FROM public.feature WHERE NULL;
    </sql>
  </relation>
  
  <rules>
    <notes>
-- ************************************************************
-- UPDATE RULES
-- ************************************************************
-- NOT COMPLETE

-- we don't really need these as loading is easy enough
-- to do with xslts
    </notes>
    <sql>

CREATE RULE "_RuleI_term_definition" AS
 ON INSERT TO term_definition
 DO INSTEAD
  UPDATE cvterm
  SET
  definition = NEW.term_definition
  WHERE cvterm_id = NEW.term_id;

CREATE RULE "_RuleU_term_definition" AS
 ON UPDATE TO term_definition
 DO INSTEAD
  UPDATE cvterm
  SET
  definition = NEW.term_definition
  WHERE cvterm_id = OLD.term_id;

CREATE RULE "_RuleD_term_definition" AS
 ON DELETE TO term_definition
 DO INSTEAD
  UPDATE cvterm
  SET
  definition = NULL
  WHERE cvterm_id = OLD.term_id;

CREATE RULE "_RuleI_term2term" AS
 ON INSERT TO term2term
 DO INSTEAD
  INSERT INTO cvterm_relationship
  (
   type_id,
   object_id,
   subject_id)
  VALUES
  (
   NEW.relationship_type_id, 
   NEW.term1_id,
   NEW.term2_id
  );

CREATE RULE "_RuleU_term2term" AS
 ON UPDATE TO term2term
 DO INSTEAD
  UPDATE cvterm_relationship
  SET
 type_id        = NEW.relationship_type_id,
 object_id        = NEW.term1_id,
 subject_id       = NEW.term2_id
  WHERE cvterm_relationship_id = OLD.id;

CREATE RULE "_RuleD_term2term" AS
 ON DELETE TO term2term
 DO INSTEAD
  DELETE FROM cvterm_relationship
  WHERE cvterm_relationship_id = OLD.id;

CREATE RULE "_RuleI_graph_path" AS
 ON INSERT TO graph_path
 DO INSTEAD
  INSERT INTO cvtermpath
  (
   type_id,
   object_id,
   subject_id,
   pathdistance)
  VALUES
  (
   NULL,
   NEW.term1_id,
   NEW.term2_id,
   NEW.distance
  );

CREATE RULE "_RuleU_graph_path" AS
 ON UPDATE TO graph_path
 DO INSTEAD
  UPDATE cvtermpath
  SET
 type_id        = NULL,
 object_id        = NEW.term1_id,
 subject_id       = NEW.term2_id,
 pathdistance      = NEW.distance
  WHERE cvtermpath_id = OLD.id;

CREATE RULE "_RuleD_graph_path" AS
 ON DELETE TO graph_path
 DO INSTEAD
  DELETE FROM cvtermpath
  WHERE cvtermpath_id = OLD.id;


CREATE RULE "_RuleI_term_synonym" AS
 ON INSERT TO term_synonym
 DO INSTEAD
  INSERT INTO cvtermsynonym
  (cvterm_id, synonym)
  VALUES
  (NEW.term_id, NEW.term_synonym);

CREATE RULE "_RuleU_term_synonym" AS
 ON UPDATE TO term_synonym
 DO INSTEAD
  UPDATE cvtermsynonym
  SET
 cvterm_id = NEW.term_id,
 synonym  = NEW.term_synonym
  WHERE cvterm_id = OLD.term_id AND synonym = OLD.term_synonym;

CREATE RULE "_RuleD_term_synonym" AS
 ON DELETE TO term_synonym
 DO INSTEAD
  DELETE FROM cvtermsynonym
  WHERE cvterm_id = OLD.term_id AND synonym = OLD.term_synonym;

CREATE RULE "_RuleI_term_dbxref" AS
 ON INSERT TO term_dbxref
 DO INSTEAD
  INSERT INTO cvterm_dbxref
  (cvterm_id, dbxref_id)
  VALUES
  (NEW.term_id, NEW.dbxref_id);

CREATE RULE "_RuleU_term_dbxref" AS
 ON UPDATE TO term_dbxref
 DO INSTEAD
  UPDATE cvterm_dbxref
  SET
 cvterm_id = NEW.term_id,
 dbxref_id  = NEW.dbxref_id
  WHERE cvterm_id = OLD.term_id AND dbxref_id = OLD.dbxref_id;

CREATE RULE "_RuleD_term_dbxref" AS
 ON DELETE TO term_dbxref
 DO INSTEAD
  DELETE FROM cvterm_dbxref
  WHERE cvterm_id = OLD.term_id AND dbxref_id = OLD.dbxref_id;
    </sql>
  </rules>
</bridge_layer>
