-- -*-Sql-*- mode (to keep my emacs happy)
--
-- API Package Body for Bioentry.
--
-- Scaffold auto-generated by gen-api.pl. gen-api.pl is
-- Copyright 2002-2003 Genomics Institute of the Novartis Research Foundation
-- Copyright 2002-2008 Hilmar Lapp
-- 
--  This file is part of BioSQL.
--
--  BioSQL is free software: you can redistribute it and/or modify it
--  under the terms of the GNU Lesser General Public License as
--  published by the Free Software Foundation, either version 3 of the
--  License, or (at your option) any later version.
--
--  BioSQL is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU Lesser General Public License for more details.
--
--  You should have received a copy of the GNU Lesser General Public License
--  along with BioSQL. If not, see <http://www.gnu.org/licenses/>.
--

CREATE OR REPLACE
PACKAGE BODY Ent IS

Ent_cached	SG_BIOENTRY.OID%TYPE DEFAULT NULL;
cache_key		VARCHAR2(128) DEFAULT NULL;

CURSOR Ent_Acc_c (
		Ent_ACCESSION	IN SG_BIOENTRY.ACCESSION%TYPE,
		Ent_VERSION	IN SG_BIOENTRY.VERSION%TYPE,
		Ent_DB_OID	IN SG_BIOENTRY.DB_OID%TYPE)
RETURN SG_BIOENTRY%ROWTYPE IS
	SELECT t.* FROM SG_BIOENTRY t
	WHERE
	   	t.DB_OID = Ent_DB_OID
	AND	t.ACCESSION = Ent_ACCESSION
	AND	t.VERSION = NVL(Ent_VERSION,0)
	;

CURSOR Ent_ID_c (
		Ent_DB_OID	IN SG_BIOENTRY.DB_OID%TYPE,
		Ent_IDENTIFIER	IN SG_BIOENTRY.IDENTIFIER%TYPE)
RETURN SG_BIOENTRY%ROWTYPE IS
	SELECT t.* FROM SG_BIOENTRY t
	WHERE
		t.DB_OID = Ent_DB_OID
	AND	t.IDENTIFIER = Ent_IDENTIFIER
	;

FUNCTION get_oid(
		Ent_OID	IN SG_BIOENTRY.OID%TYPE DEFAULT NULL,
		Ent_ACCESSION	IN SG_BIOENTRY.ACCESSION%TYPE,
		Ent_IDENTIFIER	IN SG_BIOENTRY.IDENTIFIER%TYPE DEFAULT NULL,
		Ent_NAME	IN SG_BIOENTRY.NAME%TYPE DEFAULT NULL,
		Ent_DESCRIPTION	IN SG_BIOENTRY.DESCRIPTION%TYPE DEFAULT NULL,
		Ent_VERSION	IN SG_BIOENTRY.VERSION%TYPE DEFAULT NULL,
		Ent_DIVISION	IN SG_BIOENTRY.DIVISION%TYPE DEFAULT NULL,
		DB_OID	IN SG_BIOENTRY.DB_OID%TYPE DEFAULT NULL,
		TAX_OID	IN SG_BIOENTRY.TAX_OID%TYPE DEFAULT NULL,
		Tax_NCBI_TAXON_ID	IN SG_TAXON.NCBI_TAXON_ID%TYPE DEFAULT NULL,
		Tnm_Name	IN SG_TAXON_NAME.NAME%TYPE DEFAULT NULL,
		DB_NAME	IN SG_BIODATABASE.NAME%TYPE DEFAULT NULL,
		DB_ACRONYM	IN SG_BIODATABASE.ACRONYM%TYPE DEFAULT NULL,
		do_DML		IN NUMBER DEFAULT BSStd.DML_NO)
RETURN SG_BIOENTRY.OID%TYPE
IS
	pk	SG_BIOENTRY.OID%TYPE DEFAULT NULL;
	Ent_row Ent_Acc_c%ROWTYPE;
	TAX_OID_	SG_TAXON.OID%TYPE DEFAULT TAX_OID;
	DB_OID_	SG_BIODATABASE.OID%TYPE DEFAULT DB_OID;
	key_str	VARCHAR2(128) DEFAULT DB_OID || '|' || Ent_ACCESSION || '|' || Ent_VERSION || '|' || Ent_IDENTIFIER;
BEGIN
	-- initialize
	IF (do_DML > BSStd.DML_NO) THEN
		pk := Ent_OID;
	END IF;
	-- look up
	IF pk IS NULL THEN
		IF (DB_OID_ IS NULL) THEN
			DB_OID_ := DB.get_oid(
				DB_NAME => DB_NAME,
				DB_ACRONYM => DB_ACRONYM,
				do_DML => do_DML);
		END IF;
		-- reset cache
		cache_key := NULL;
		Ent_cached := NULL;
		-- do the look up
		IF (Ent_IDENTIFIER IS NULL) THEN
		        FOR Ent_row IN Ent_Acc_c(Ent_ACCESSION, 
						 Ent_VERSION, DB_OID_) LOOP
			    pk := Ent_row.OID;
			    -- cache result
			    cache_key := key_str;
			    Ent_cached := pk;
			END LOOP;
		ELSE
		        FOR Ent_row IN Ent_ID_c(DB_OID_, Ent_IDENTIFIER) LOOP
			    pk := Ent_row.OID;
			    -- cache result
			    cache_key := key_str;
			    Ent_cached := pk;
			END LOOP;
		END IF;
	END IF;
	-- insert/update if requested
	IF (pk IS NULL) AND 
	   ((do_DML = BSStd.DML_I) OR (do_DML = BSStd.DML_UI)) THEN
	    	-- look up foreign keys if not provided:
		-- look up SG_BIODATABASE successful?
		IF (DB_OID_ IS NULL) THEN
			raise_application_error(-20101,
				'failed to look up DB <' || DB_NAME || '|' || DB_ACRONYM || '>');
		END IF;
		-- look up SG_TAXON
		IF (TAX_OID_ IS NULL) AND
		   ((Tnm_Name IS NOT NULL) OR
		    (Tax_NCBI_Taxon_ID IS NOT NULL)) THEN
			TAX_OID_ := Tax.get_oid(
				Tax_NCBI_TAXON_ID => Tax_NCBI_TAXON_ID,
				Tnm_Name => Tnm_Name);
			IF (TAX_OID_ IS NULL) THEN
			   raise_application_error(-20101,
				'failed to look up Tax <' || Tax_NCBI_TAXON_ID || '|' || '>');
			END IF;
		END IF;
	    	-- insert the record and obtain the primary key
	    	pk := do_insert(
		        ACCESSION => Ent_ACCESSION,
			IDENTIFIER => Ent_IDENTIFIER,
			NAME => Ent_NAME,
			DESCRIPTION => Ent_DESCRIPTION,
			VERSION => Ent_VERSION,
			DIVISION => Ent_DIVISION,
			DB_OID => DB_OID_,
			TAX_OID => TAX_OID_);
	ELSIF (do_DML = BSStd.DML_U) OR (do_DML = BSStd.DML_UI) THEN
	        -- update the record (note that not provided FKs will not
		-- be changed nor looked up)
		do_update(
			Ent_OID	=> pk,
		        Ent_ACCESSION => Ent_ACCESSION,
			Ent_IDENTIFIER => Ent_IDENTIFIER,
			Ent_NAME => Ent_NAME,
			Ent_DESCRIPTION => Ent_DESCRIPTION,
			Ent_VERSION => Ent_VERSION,
			Ent_DIVISION => Ent_DIVISION,
			Ent_DB_OID => DB_OID_,
			Ent_TAX_OID => TAX_OID_);
	END IF;
	-- return the primary key
	RETURN pk;
END;

FUNCTION do_insert(
		ACCESSION	IN SG_BIOENTRY.ACCESSION%TYPE,
		IDENTIFIER	IN SG_BIOENTRY.IDENTIFIER%TYPE,
		NAME	IN SG_BIOENTRY.NAME%TYPE,
		DESCRIPTION	IN SG_BIOENTRY.DESCRIPTION%TYPE,
		VERSION	IN SG_BIOENTRY.VERSION%TYPE,
		DIVISION	IN SG_BIOENTRY.DIVISION%TYPE,
		DB_OID	IN SG_BIOENTRY.DB_OID%TYPE,
		TAX_OID	IN SG_BIOENTRY.TAX_OID%TYPE)
RETURN SG_BIOENTRY.OID%TYPE 
IS
	pk	SG_BIOENTRY.OID%TYPE;
BEGIN
	-- pre-generate the primary key value
	SELECT SG_Sequence.nextval INTO pk FROM DUAL;
	-- insert the record
	INSERT INTO SG_BIOENTRY (
		OID,
		ACCESSION,
		IDENTIFIER,
		NAME,
		DESCRIPTION,
		VERSION,
		DIVISION,
		DB_OID,
		TAX_OID)
	VALUES (pk,
		ACCESSION,
		IDENTIFIER,
		NAME,
		DESCRIPTION,
		VERSION,
		DIVISION,
		DB_OID,
		TAX_OID)
	;
	-- return the new pk value
	RETURN pk;
END;

PROCEDURE do_update(
		Ent_OID	IN SG_BIOENTRY.OID%TYPE,
		Ent_ACCESSION	IN SG_BIOENTRY.ACCESSION%TYPE,
		Ent_IDENTIFIER	IN SG_BIOENTRY.IDENTIFIER%TYPE,
		Ent_NAME	IN SG_BIOENTRY.NAME%TYPE,
		Ent_DESCRIPTION	IN SG_BIOENTRY.DESCRIPTION%TYPE,
		Ent_VERSION	IN SG_BIOENTRY.VERSION%TYPE,
		Ent_DIVISION	IN SG_BIOENTRY.DIVISION%TYPE,
		Ent_DB_OID	IN SG_BIOENTRY.DB_OID%TYPE,
		Ent_TAX_OID	IN SG_BIOENTRY.TAX_OID%TYPE)
IS
BEGIN
	-- update the record (and leave attributes passed as NULL untouched)
	UPDATE SG_BIOENTRY
	SET
		ACCESSION = NVL(Ent_ACCESSION, ACCESSION),
		IDENTIFIER = NVL(Ent_IDENTIFIER, IDENTIFIER),
		NAME = NVL(Ent_NAME, NAME),
		DESCRIPTION = NVL(Ent_DESCRIPTION, DESCRIPTION),
		VERSION = NVL(Ent_VERSION, VERSION),
		DIVISION = NVL(Ent_DIVISION, DIVISION),
		DB_OID = NVL(Ent_DB_OID, DB_OID),
		TAX_OID = NVL(Ent_TAX_OID, TAX_OID)
	WHERE OID = Ent_OID
	;
END;

END Ent;
/

