diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DatabaseVersionHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DatabaseVersionHolder.java index 8819e6fff1c04a4129e304908f9d66662246c3a1..99554b9a485766d4949f370dd57c9825e5303cee 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DatabaseVersionHolder.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DatabaseVersionHolder.java @@ -23,8 +23,10 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess.db; */ public final class DatabaseVersionHolder { - /** Current version of the database. */ - private static final String DATABASE_VERSION = "188"; + /** + * Current version of the database. + */ + private static final String DATABASE_VERSION = "189"; /** Current version of the database INDICES. */ private static final String DATABASE_FULL_TEXT_SEARCH_DOCUMENT_VERSION = "002"; diff --git a/openbis/source/sql/generic/189/data-189.sql b/openbis/source/sql/generic/189/data-189.sql new file mode 100644 index 0000000000000000000000000000000000000000..6baee01371cdcfdb496a61b46d9f7fccd841faf7 --- /dev/null +++ b/openbis/source/sql/generic/189/data-189.sql @@ -0,0 +1,482 @@ +---------------------------------------------------------------------- +-- Purpose: Insert an initial data set into the table PERSONS +----------------------------------------------------------------------- + +insert into persons +(id +,first_name +,last_name +,user_id +,email) +values +(nextval('PERSON_ID_SEQ') +,'' +,'System User' +,'system' +,''); + +----------------------------------------------------------------------------------- +-- Purpose: Create Controlled Vocabulary STORAGE_FORMAT +----------------------------------------------------------------------------------- +insert into controlled_vocabularies + ( id + , code + , description + , pers_id_registerer + , is_managed_internally) +values (nextval('CONTROLLED_VOCABULARY_ID_SEQ') + , 'STORAGE_FORMAT' + , 'The on-disk storage format of a data set' + , (select id from persons where user_id ='system') + , true); + + +----------------------------------------------------------------------------------- +-- Purpose: Create Controlled Vocabulary Terms for STORAGE_FORMAT +----------------------------------------------------------------------------------- +insert into controlled_vocabulary_terms + ( id + , code + , covo_id + , pers_id_registerer + , ordinal ) +values (nextval('CVTE_ID_SEQ') + , 'PROPRIETARY' + , (select id from controlled_vocabularies where code = 'STORAGE_FORMAT' and is_managed_internally = true) + , (select id from persons where user_id ='system') + , 1); + +insert into controlled_vocabulary_terms + ( id + , code + , covo_id + , pers_id_registerer + , ordinal) +values (nextval('CVTE_ID_SEQ') + , 'BDS_DIRECTORY' + , (select id from controlled_vocabularies where code = 'STORAGE_FORMAT' and is_managed_internally = true) + , (select id from persons where user_id ='system') + , 2); + +------------------------------------------------------------------ +-- Purpose: Insert an initial data set into the table DATA_TYPES +------------------------------------------------------------------ + +insert into data_types +(id +,code +,description) +values +(nextval('DATA_TYPE_ID_SEQ') +,'VARCHAR' +,'Short text' +); + +insert into data_types +(id + ,code + ,description) + values + (nextval('DATA_TYPE_ID_SEQ') + ,'MULTILINE_VARCHAR' + ,'Long text' +); + +insert into data_types +(id +,code +,description) +values +(nextval('DATA_TYPE_ID_SEQ') +,'INTEGER' +,'Integer number' +); + +insert into data_types +(id +,code +,description) +values +(nextval('DATA_TYPE_ID_SEQ') +,'REAL' +,'Real number, i.e. an inexact, variable-precision numeric type' +); + +insert into data_types +(id +,code +,description) +values +(nextval('DATA_TYPE_ID_SEQ') +,'BOOLEAN' +,'True or False' +); + +insert into data_types +(id +,code +,description) +values +(nextval('DATA_TYPE_ID_SEQ') +,'TIMESTAMP' +,'Both date and time. Format: yyyy-mm-dd hh:mm:ss' +); + +insert into data_types +(id + ,code + ,description) + values + (nextval('DATA_TYPE_ID_SEQ') + ,'CONTROLLEDVOCABULARY' + ,'Controlled Vocabulary' +); + +insert into data_types +(id + ,code + ,description) + values + (nextval('DATA_TYPE_ID_SEQ') + ,'MATERIAL' + ,'Reference to a material' +); + +insert into data_types +(id + ,code + ,description) + values + (nextval('DATA_TYPE_ID_SEQ') + ,'HYPERLINK' + ,'Address of a web page' +); + +insert into data_types +(id + ,code + ,description) + values + (nextval('DATA_TYPE_ID_SEQ') + ,'XML' + ,'XML document' +); + +insert into data_types +(id + ,code + ,description) + values + (nextval('DATA_TYPE_ID_SEQ') + ,'SAMPLE' + ,'Reference to a sample' +); + +insert into data_types +(id +,code +,description) +values +(nextval('DATA_TYPE_ID_SEQ') +,'DATE' +,'Date. Format: yyyy-mm-dd' +); + +---------------------------------------------------------------------- +-- Purpose: Insert an initial data set into the table PROPERTY_TYPES +----------------------------------------------------------------------- + +insert into property_types +(id +,code +,description +,label +,daty_id +,pers_id_registerer) +values +(nextval('PROPERTY_TYPE_ID_SEQ') +,'DESCRIPTION' +,'A Description' +,'Description' +,(select id from data_types where code ='VARCHAR') +,(select id from persons where user_id ='system') +); + +-------------------------------------------------------------------------- +-- Purpose: Insert an initial data set into the table EXPERIMENT_TYPES +-------------------------------------------------------------------------- + +insert into experiment_types +(id +,code +,description) +values +(nextval('EXPERIMENT_TYPE_ID_SEQ') +,'UNKNOWN' +,'Unknown' +); + +-------------------------------------------------------------------------- +-- Purpose: Insert an initial data set into the table SAMPLE_TYPES +-------------------------------------------------------------------------- + +insert into sample_types +(id +,code +,description) +values +(nextval('SAMPLE_TYPE_ID_SEQ') +,'UNKNOWN' +,'Unknown' +); + +-------------------------------------------------------------------------- +-- Purpose: Insert an initial data set into the table DATA_SET_TYPES +-------------------------------------------------------------------------- + +insert into data_set_types +(id +,code +,description) +values +(nextval('DATA_SET_TYPE_ID_SEQ') +,'UNKNOWN' +,'Unknown' +); + +------------------------------------------------------------------------- +-- Purpose: Insert an initial data set into the table FILE_FORMAT_TYPES +------------------------------------------------------------------------- + +insert into file_format_types +(id +,code +,description) +values +(nextval('FILE_FORMAT_TYPE_ID_SEQ') +,'HDF5' +,'Hierarchical Data Format File, version 5' +); + +insert into file_format_types +(id +,code +,description) +values +(nextval('FILE_FORMAT_TYPE_ID_SEQ') +,'PROPRIETARY' +,'Proprietary Format File' +); + +insert into file_format_types +(id +,code +,description +) +values +(nextval('FILE_FORMAT_TYPE_ID_SEQ') +,'SRF' +,'Sequence Read Format File' +); + +insert into file_format_types +(id +,code +,description +) +values +(nextval('FILE_FORMAT_TYPE_ID_SEQ') +,'TIFF' +,'TIFF File' +); + +insert into file_format_types +(id +,code +,description +) +values +(nextval('FILE_FORMAT_TYPE_ID_SEQ') +,'TSV' +,'Tab Separated Values File' +); + +insert into file_format_types +(id +,code +,description +) +values +(nextval('FILE_FORMAT_TYPE_ID_SEQ') +,'XML' +,'XML File' +); + +--------------------------------------------------------------------- +-- Purpose: Insert an initial data set into the table LOCATOR_TYPES +--------------------------------------------------------------------- + +insert into locator_types +(id +,code +,description) +values +(nextval('LOCATOR_TYPE_ID_SEQ') +,'RELATIVE_LOCATION' +,'Relative Location' +); + +--------------------------------------------------------------------- +-- Purpose: Insert an initial data into table RELATIONSHIP_TYPES +--------------------------------------------------------------------- + +insert into relationship_types +(id, +code, +label, +parent_label, +child_label, +description, +pers_id_registerer, +is_managed_internally +) +values +( +nextval('RELATIONSHIP_TYPE_ID_SEQ'), +'PARENT_CHILD', +'Parent - Child', +'Parent', +'Child', +'Parent - Child relationship', +(select id from persons where user_id ='system'), +'T' +); + +insert into relationship_types +(id, +code, +label, +parent_label, +child_label, +description, +pers_id_registerer, +is_managed_internally) +values +( +nextval('RELATIONSHIP_TYPE_ID_SEQ'), +'PLATE_CONTROL_LAYOUT', +'Plate - Control Layout', +'Plate', +'Control Layout', +'Plate - Control Layout relationship', +(select id from persons where user_id ='system'), +'T' +); + +insert into relationship_types +(id, +code, +label, +parent_label, +child_label, +description, +pers_id_registerer, +is_managed_internally) +values +( +nextval('RELATIONSHIP_TYPE_ID_SEQ'), +'CONTAINER_COMPONENT', +'Container - Component', +'Container', +'Component', +'Container - Component relationship', +(select id from persons where user_id ='system'), +'T'); + +--------------------------------------------------------------------- +-- Purpose: Create default space +--------------------------------------------------------------------- + +insert into spaces +(id, +code, +pers_id_registerer) +values +( +nextval('SPACE_ID_SEQ'), +'DEFAULT', +(select id from persons where user_id ='system') +); + +--------------------------------------------------------------------- +-- Purpose: Create default project +--------------------------------------------------------------------- + +select nextval('PROJECT_ID_SEQ'); +insert into projects +(id, +perm_id, +code, +space_id, +pers_id_registerer) +values +( +currval('PROJECT_ID_SEQ'), +to_char(now(), 'YYYYMMDDHH24MISSMS')||'-'||currval('PROJECT_ID_SEQ'), +'DEFAULT', +(select id from spaces where code = 'DEFAULT'), +(select id from persons where user_id ='system') +); + +--------------------------------------------------------------------- +-- Purpose: Create default experiment +--------------------------------------------------------------------- + +select nextval('EXPERIMENT_ID_SEQ'); +insert into experiments_all +(id, +perm_id, +code, +proj_id, +exty_id, +pers_id_registerer, +tsvector_document) +values +( +currval('EXPERIMENT_ID_SEQ'), +to_char(now(), 'YYYYMMDDHH24MISSMS')||'-'||currval('EXPERIMENT_ID_SEQ'), +'DEFAULT', +(select id from projects where code = 'DEFAULT'), +(select id from experiment_types where code = 'UNKNOWN'), +(select id from persons where user_id ='system'), +(to_char(now(), 'YYYYMMDDHH24MISSMS')||'-'||currval('EXPERIMENT_ID_SEQ') || ':1')::tsvector || + 'DEFAULT:1'::tsvector || '/DEFAULT/DEFAULT/DEFAULT:1'::tsvector +); + +--------------------------------------------------------------------- +-- Purpose: Create default sample +--------------------------------------------------------------------- + +select nextval('SAMPLE_ID_SEQ'); +insert into samples_all +(id, +perm_id, +code, +expe_id, +space_id, +saty_id, +pers_id_registerer, +tsvector_document) +values +( +currval('SAMPLE_ID_SEQ'), +to_char(now(), 'YYYYMMDDHH24MISSMS')||'-'||currval('SAMPLE_ID_SEQ'), +'DEFAULT', +(select id from experiments where code = 'DEFAULT'), +(select id from spaces where code = 'DEFAULT'), +(select id from sample_types where code = 'UNKNOWN'), +(select id from persons where user_id ='system'), +(to_char(now(), 'YYYYMMDDHH24MISSMS')||'-'||currval('SAMPLE_ID_SEQ') || ':1')::tsvector || + 'DEFAULT:1'::tsvector || '/DEFAULT/DEFAULT:1'::tsvector +); + diff --git a/openbis/source/sql/generic/189/schema-189.sql b/openbis/source/sql/generic/189/schema-189.sql new file mode 100644 index 0000000000000000000000000000000000000000..b47332ac0a3d9a52b5c721fb81411b9af03e5a68 --- /dev/null +++ b/openbis/source/sql/generic/189/schema-189.sql @@ -0,0 +1,1060 @@ +-- Creating tables + +CREATE TABLE CONTROLLED_VOCABULARIES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,PERS_ID_REGISTERER TECH_ID NOT NULL,IS_MANAGED_INTERNALLY BOOLEAN_CHAR NOT NULL DEFAULT 'F', MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, IS_CHOSEN_FROM_LIST BOOLEAN_CHAR NOT NULL DEFAULT TRUE, SOURCE_URI CHARACTER VARYING(250)); +CREATE TABLE CONTROLLED_VOCABULARY_TERMS (ID TECH_ID NOT NULL,CODE OBJECT_NAME NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,COVO_ID TECH_ID NOT NULL,PERS_ID_REGISTERER TECH_ID NOT NULL,LABEL COLUMN_LABEL, DESCRIPTION DESCRIPTION_2000, ORDINAL ORDINAL_INT NOT NULL, IS_OFFICIAL BOOLEAN_CHAR NOT NULL DEFAULT 'T'); +CREATE TABLE DATA_ALL (ID TECH_ID NOT NULL,CODE CODE,DATA_SET_KIND DATA_SET_KIND DEFAULT 'PHYSICAL' NOT NULL,DSTY_ID TECH_ID NOT NULL,DAST_ID TECH_ID NOT NULL,EXPE_ID TECH_ID,DATA_PRODUCER_CODE CODE,PRODUCTION_TIMESTAMP TIME_STAMP,SAMP_ID TECH_ID,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,PERS_ID_REGISTERER TECH_ID,IS_VALID BOOLEAN_CHAR DEFAULT 'T', MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, ACCESS_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, IS_DERIVED BOOLEAN_CHAR NOT NULL, DEL_ID TECH_ID, ORIG_DEL TECH_ID, PERS_ID_MODIFIER TECH_ID, VERSION INTEGER DEFAULT 0, FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_CHILDREN BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_PARENTS BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_COMPS BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_CONTS BOOLEAN_CHAR NOT NULL DEFAULT 'F', EXPE_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', SAMP_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', TSVECTOR_DOCUMENT TSVECTOR NOT NULL); +CREATE TABLE DATA_SET_RELATIONSHIPS_ALL (DATA_ID_PARENT TECH_ID NOT NULL,DATA_ID_CHILD TECH_ID NOT NULL, RELATIONSHIP_ID TECH_ID NOT NULL, ORDINAL INTEGER, DEL_ID TECH_ID, PERS_ID_AUTHOR TECH_ID, REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, PARENT_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', CHILD_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', COMP_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', CONT_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE DATA_STORES (ID TECH_ID NOT NULL,UUID CODE NOT NULL,CODE CODE NOT NULL,DOWNLOAD_URL VARCHAR(1024) NOT NULL,REMOTE_URL VARCHAR(250) NOT NULL,SESSION_TOKEN VARCHAR(50) NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, IS_ARCHIVER_CONFIGURED BOOLEAN_CHAR NOT NULL DEFAULT 'F', DATA_SOURCE_DEFINITIONS TEXT_VALUE); +CREATE TABLE DATA_STORE_SERVICES (ID TECH_ID NOT NULL, KEY VARCHAR(256) NOT NULL, LABEL VARCHAR(256) NOT NULL, KIND DATA_STORE_SERVICE_KIND NOT NULL, DATA_STORE_ID TECH_ID NOT NULL, REPORTING_PLUGIN_TYPE DATA_STORE_SERVICE_REPORTING_PLUGIN_TYPE); +CREATE TABLE DATA_STORE_SERVICE_DATA_SET_TYPES (DATA_STORE_SERVICE_ID TECH_ID NOT NULL, DATA_SET_TYPE_ID TECH_ID NOT NULL); +CREATE TABLE DATA_TYPES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000 NOT NULL); +CREATE TABLE EVENTS (ID TECH_ID NOT NULL,EVENT_TYPE EVENT_TYPE NOT NULL,DESCRIPTION TEXT_VALUE,REASON DESCRIPTION_2000,PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, entity_type VARCHAR(80) NOT NULL, identifiers TEXT_VALUE NOT NULL, CONTENT TEXT_VALUE, EXAC_ID TECH_ID); +CREATE TABLE EVENTS_SEARCH (ID TECH_ID NOT NULL, EVENT_TYPE EVENT_TYPE NOT NULL, ENTITY_TYPE TEXT_VALUE NOT NULL, ENTITY_SPACE TEXT_VALUE, ENTITY_SPACE_PERM_ID TEXT_VALUE, ENTITY_PROJECT TEXT_VALUE, ENTITY_PROJECT_PERM_ID TEXT_VALUE, ENTITY_REGISTERER TEXT_VALUE, ENTITY_REGISTRATION_TIMESTAMP TIME_STAMP, IDENTIFIER TEXT_VALUE NOT NULL, DESCRIPTION TEXT_VALUE, REASON TEXT_VALUE, CONTENT TEXT_VALUE, EXAC_ID TECH_ID, PERS_ID_REGISTERER TECH_ID NOT NULL, REGISTRATION_TIMESTAMP TIME_STAMP NOT NULL); +CREATE TABLE EXPERIMENTS_ALL (ID TECH_ID NOT NULL,PERM_ID CODE NOT NULL,CODE CODE NOT NULL,EXTY_ID TECH_ID NOT NULL,PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, PROJ_ID TECH_ID NOT NULL,DEL_ID TECH_ID, ORIG_DEL TECH_ID, IS_PUBLIC BOOLEAN_CHAR NOT NULL DEFAULT 'F', PERS_ID_MODIFIER TECH_ID, VERSION INTEGER DEFAULT 0, FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_SAMP BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_DATA BOOLEAN_CHAR NOT NULL DEFAULT 'F', PROJ_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', TSVECTOR_DOCUMENT TSVECTOR NOT NULL); +CREATE TABLE ATTACHMENTS (ID TECH_ID NOT NULL,EXPE_ID TECH_ID,SAMP_ID TECH_ID,PROJ_ID TECH_ID,EXAC_ID TECH_ID NOT NULL,FILE_NAME FILE_NAME NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,VERSION INTEGER NOT NULL,PERS_ID_REGISTERER TECH_ID NOT NULL, title TITLE_100, description DESCRIPTION_2000, PROJ_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', EXPE_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', SAMP_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE ATTACHMENT_CONTENTS (ID TECH_ID NOT NULL,VALUE FILE NOT NULL); +CREATE TABLE EXPERIMENT_PROPERTIES (ID TECH_ID NOT NULL,EXPE_ID TECH_ID NOT NULL,ETPT_ID TECH_ID NOT NULL,VALUE TEXT_VALUE,CVTE_ID TECH_ID, MATE_PROP_ID TECH_ID, SAMP_PROP_ID TECH_ID, PERS_ID_REGISTERER TECH_ID NOT NULL, REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, PERS_ID_AUTHOR TECH_ID NOT NULL, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, EXPE_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', TSVECTOR_DOCUMENT TSVECTOR NOT NULL, IS_UNIQUE BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE EXPERIMENT_PROPERTIES_HISTORY (ID TECH_ID NOT NULL, EXPE_ID TECH_ID NOT NULL, ETPT_ID TECH_ID NOT NULL, VALUE TEXT_VALUE, VOCABULARY_TERM IDENTIFIER, MATERIAL IDENTIFIER, SAMPLE IDENTIFIER, PERS_ID_AUTHOR TECH_ID NOT NULL, VALID_FROM_TIMESTAMP TIME_STAMP NOT NULL, VALID_UNTIL_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP); +CREATE TABLE EXPERIMENT_TYPES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, VALIDATION_SCRIPT_ID TECH_ID); +CREATE TABLE EXPERIMENT_TYPE_PROPERTY_TYPES (ID TECH_ID NOT NULL,EXTY_ID TECH_ID NOT NULL,PRTY_ID TECH_ID NOT NULL,IS_MANDATORY BOOLEAN_CHAR NOT NULL DEFAULT 'F',IS_MANAGED_INTERNALLY BOOLEAN_CHAR NOT NULL DEFAULT 'F',PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, ORDINAL ORDINAL_INT NOT NULL, SECTION DESCRIPTION_2000,SCRIPT_ID TECH_ID,IS_SHOWN_EDIT BOOLEAN_CHAR NOT NULL DEFAULT 'T',SHOW_RAW_VALUE BOOLEAN_CHAR NOT NULL DEFAULT 'F', IS_UNIQUE BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE EXTERNAL_DATA (ID TECH_ID NOT NULL,SHARE_ID CODE,SIZE ORDINAL_INT,LOCATION VARCHAR(1024) NOT NULL,FFTY_ID TECH_ID NOT NULL,LOTY_ID TECH_ID NOT NULL,CVTE_ID_STOR_FMT TECH_ID NOT NULL,IS_COMPLETE BOOLEAN_CHAR_OR_UNKNOWN NOT NULL DEFAULT 'U',CVTE_ID_STORE TECH_ID, STATUS ARCHIVING_STATUS NOT NULL DEFAULT 'AVAILABLE', PRESENT_IN_ARCHIVE BOOLEAN_CHAR DEFAULT 'F', SPEED_HINT INTEGER NOT NULL DEFAULT -50, STORAGE_CONFIRMATION BOOLEAN_CHAR NOT NULL DEFAULT 'F', H5_FOLDERS BOOLEAN_CHAR NOT NULL, H5AR_FOLDERS BOOLEAN_CHAR NOT NULL, ARCHIVING_REQUESTED BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE FILE_FORMAT_TYPES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000); +CREATE TABLE GRID_CUSTOM_COLUMNS (ID TECH_ID NOT NULL, CODE VARCHAR(200) NOT NULL, LABEL column_label NOT NULL, DESCRIPTION DESCRIPTION_2000,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, PERS_ID_REGISTERER TECH_ID NOT NULL, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, EXPRESSION GRID_EXPRESSION NOT NULL, IS_PUBLIC BOOLEAN NOT NULL, GRID_ID GRID_ID NOT NULL); +CREATE TABLE SPACES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,PERS_ID_REGISTERER TECH_ID NOT NULL, FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_PROJ BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_SAMP BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE DELETIONS (ID TECH_ID NOT NULL,PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,REASON DESCRIPTION_2000 NOT NULL); +CREATE TABLE LOCATOR_TYPES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000); +CREATE TABLE MATERIALS (ID TECH_ID NOT NULL,CODE CODE NOT NULL,MATY_ID TECH_ID NOT NULL,PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, TSVECTOR_DOCUMENT TSVECTOR NOT NULL); +CREATE TABLE MATERIAL_PROPERTIES (ID TECH_ID NOT NULL,MATE_ID TECH_ID NOT NULL,MTPT_ID TECH_ID NOT NULL,VALUE TEXT_VALUE,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, PERS_ID_AUTHOR TECH_ID NOT NULL, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, PERS_ID_REGISTERER TECH_ID NOT NULL,CVTE_ID TECH_ID, MATE_PROP_ID TECH_ID, TSVECTOR_DOCUMENT TSVECTOR NOT NULL, IS_UNIQUE BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE MATERIAL_PROPERTIES_HISTORY (ID TECH_ID NOT NULL, MATE_ID TECH_ID NOT NULL, MTPT_ID TECH_ID NOT NULL, VALUE TEXT_VALUE, VOCABULARY_TERM IDENTIFIER, MATERIAL IDENTIFIER, PERS_ID_AUTHOR TECH_ID NOT NULL, VALID_FROM_TIMESTAMP TIME_STAMP NOT NULL, VALID_UNTIL_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP); +CREATE TABLE MATERIAL_TYPES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, VALIDATION_SCRIPT_ID TECH_ID); +CREATE TABLE MATERIAL_TYPE_PROPERTY_TYPES (ID TECH_ID NOT NULL,MATY_ID TECH_ID NOT NULL,PRTY_ID TECH_ID NOT NULL,IS_MANDATORY BOOLEAN_CHAR NOT NULL DEFAULT 'F',IS_MANAGED_INTERNALLY BOOLEAN_CHAR NOT NULL DEFAULT 'F',REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,PERS_ID_REGISTERER TECH_ID NOT NULL, ORDINAL ORDINAL_INT NOT NULL, SECTION DESCRIPTION_2000,SCRIPT_ID TECH_ID,IS_SHOWN_EDIT BOOLEAN_CHAR NOT NULL DEFAULT 'T',SHOW_RAW_VALUE BOOLEAN_CHAR NOT NULL DEFAULT 'F', IS_UNIQUE BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE DATA_SET_TYPES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, MAIN_DS_PATTERN VARCHAR(300), MAIN_DS_PATH VARCHAR(1000), DELETION_DISALLOW BOOLEAN_CHAR DEFAULT 'F', VALIDATION_SCRIPT_ID TECH_ID); +CREATE TABLE PERSONS (ID TECH_ID NOT NULL,FIRST_NAME VARCHAR(30),LAST_NAME VARCHAR(30),USER_ID USER_ID NOT NULL,EMAIL OBJECT_NAME,SPACE_ID TECH_ID,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,PERS_ID_REGISTERER TECH_ID, DISPLAY_SETTINGS FILE, IS_ACTIVE BOOLEAN DEFAULT TRUE); +CREATE TABLE PROJECTS (ID TECH_ID NOT NULL,PERM_ID CODE NOT NULL,CODE CODE NOT NULL,SPACE_ID TECH_ID NOT NULL,PERS_ID_LEADER TECH_ID,DESCRIPTION TEXT_VALUE,PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, PERS_ID_MODIFIER TECH_ID, VERSION INTEGER DEFAULT 0, FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_EXP BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_SAMP BOOLEAN_CHAR NOT NULL DEFAULT 'F', SPACE_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE PROPERTY_TYPES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000 NOT NULL,LABEL COLUMN_LABEL NOT NULL,DATY_ID TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,PERS_ID_REGISTERER TECH_ID NOT NULL,COVO_ID TECH_ID,IS_MANAGED_INTERNALLY BOOLEAN_CHAR NOT NULL DEFAULT 'F', MATY_PROP_ID TECH_ID, SATY_PROP_ID TECH_ID, SCHEMA TEXT_VALUE, TRANSFORMATION TEXT_VALUE, META_DATA JSONB); +CREATE TABLE ROLE_ASSIGNMENTS (ID TECH_ID NOT NULL,ROLE_CODE AUTHORIZATION_ROLE NOT NULL,SPACE_ID TECH_ID, PROJECT_ID TECH_ID, PERS_ID_GRANTEE TECH_ID, AG_ID_GRANTEE TECH_ID, PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP); +CREATE TABLE SAMPLES_ALL (ID TECH_ID NOT NULL,PERM_ID CODE NOT NULL, sample_identifier sample_identifier, CODE CODE NOT NULL, EXPE_ID TECH_ID,SATY_ID TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP,PERS_ID_REGISTERER TECH_ID NOT NULL,DEL_ID TECH_ID, ORIG_DEL TECH_ID, SPACE_ID TECH_ID, SAMP_ID_PART_OF TECH_ID, PERS_ID_MODIFIER TECH_ID, code_unique_check character varying(300), subcode_unique_check character varying(300), VERSION INTEGER DEFAULT 0, PROJ_ID TECH_ID, FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_COMP BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_CHILDREN BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_PARENTS BOOLEAN_CHAR NOT NULL DEFAULT 'F', FROZEN_FOR_DATA BOOLEAN_CHAR NOT NULL DEFAULT 'F', SPACE_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', PROJ_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', EXPE_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', CONT_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', TSVECTOR_DOCUMENT TSVECTOR NOT NULL); +CREATE TABLE SAMPLE_PROPERTIES (ID TECH_ID NOT NULL,SAMP_ID TECH_ID NOT NULL,STPT_ID TECH_ID NOT NULL,VALUE TEXT_VALUE,CVTE_ID TECH_ID,MATE_PROP_ID TECH_ID,SAMP_PROP_ID TECH_ID,PERS_ID_REGISTERER TECH_ID NOT NULL, REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, PERS_ID_AUTHOR TECH_ID NOT NULL, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, SAMP_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', TSVECTOR_DOCUMENT TSVECTOR NOT NULL, IS_UNIQUE BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE SAMPLE_PROPERTIES_HISTORY (ID TECH_ID NOT NULL, SAMP_ID TECH_ID NOT NULL, STPT_ID TECH_ID NOT NULL, VALUE TEXT_VALUE, VOCABULARY_TERM IDENTIFIER, MATERIAL IDENTIFIER, SAMPLE IDENTIFIER, PERS_ID_AUTHOR TECH_ID NOT NULL, VALID_FROM_TIMESTAMP TIME_STAMP NOT NULL, VALID_UNTIL_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP); +CREATE TABLE SAMPLE_TYPES (ID TECH_ID NOT NULL,CODE CODE NOT NULL,DESCRIPTION DESCRIPTION_2000, IS_LISTABLE BOOLEAN_CHAR NOT NULL DEFAULT 'T', GENERATED_FROM_DEPTH INTEGER NOT NULL DEFAULT 0, PART_OF_DEPTH INTEGER NOT NULL DEFAULT 0, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, is_auto_generated_code BOOLEAN_CHAR NOT NULL DEFAULT 'F', generated_code_prefix CODE NOT NULL DEFAULT 'S', is_subcode_unique BOOLEAN_CHAR NOT NULL DEFAULT 'F', INHERIT_PROPERTIES BOOLEAN_CHAR NOT NULL DEFAULT 'F', VALIDATION_SCRIPT_ID TECH_ID, SHOW_PARENT_METADATA BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE SAMPLE_TYPE_PROPERTY_TYPES (ID TECH_ID NOT NULL,SATY_ID TECH_ID NOT NULL,PRTY_ID TECH_ID NOT NULL,IS_MANDATORY BOOLEAN_CHAR NOT NULL DEFAULT 'F',IS_MANAGED_INTERNALLY BOOLEAN_CHAR NOT NULL DEFAULT 'F',PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, IS_DISPLAYED BOOLEAN_CHAR NOT NULL DEFAULT 'T', ORDINAL ORDINAL_INT NOT NULL, SECTION DESCRIPTION_2000,SCRIPT_ID TECH_ID,IS_SHOWN_EDIT BOOLEAN_CHAR NOT NULL DEFAULT 'T',SHOW_RAW_VALUE BOOLEAN_CHAR NOT NULL DEFAULT 'F', IS_UNIQUE BOOLEAN_CHAR NOT NULL DEFAULT 'F'); + +CREATE TABLE DATA_SET_PROPERTIES (ID TECH_ID NOT NULL,DS_ID TECH_ID NOT NULL,DSTPT_ID TECH_ID NOT NULL,VALUE TEXT_VALUE,CVTE_ID TECH_ID, MATE_PROP_ID TECH_ID, SAMP_PROP_ID TECH_ID, PERS_ID_REGISTERER TECH_ID NOT NULL, REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, PERS_ID_AUTHOR TECH_ID NOT NULL, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, DASE_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', TSVECTOR_DOCUMENT TSVECTOR NOT NULL, IS_UNIQUE BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE DATA_SET_PROPERTIES_HISTORY (ID TECH_ID NOT NULL, DS_ID TECH_ID NOT NULL, DSTPT_ID TECH_ID NOT NULL, VALUE TEXT_VALUE, VOCABULARY_TERM IDENTIFIER, MATERIAL IDENTIFIER, SAMPLE IDENTIFIER, PERS_ID_AUTHOR TECH_ID NOT NULL, VALID_FROM_TIMESTAMP TIME_STAMP NOT NULL, VALID_UNTIL_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP); +CREATE TABLE DATA_SET_TYPE_PROPERTY_TYPES (ID TECH_ID NOT NULL,DSTY_ID TECH_ID NOT NULL,PRTY_ID TECH_ID NOT NULL,IS_MANDATORY BOOLEAN_CHAR NOT NULL DEFAULT 'F',IS_MANAGED_INTERNALLY BOOLEAN_CHAR NOT NULL DEFAULT 'F',PERS_ID_REGISTERER TECH_ID NOT NULL,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, ORDINAL ORDINAL_INT NOT NULL, SECTION DESCRIPTION_2000,SCRIPT_ID TECH_ID, IS_SHOWN_EDIT BOOLEAN_CHAR NOT NULL DEFAULT 'T',SHOW_RAW_VALUE BOOLEAN_CHAR NOT NULL DEFAULT 'F', IS_UNIQUE BOOLEAN_CHAR NOT NULL DEFAULT 'F'); + +CREATE TABLE AUTHORIZATION_GROUPS (ID TECH_ID NOT NULL, CODE CODE NOT NULL, DESCRIPTION DESCRIPTION_2000,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, PERS_ID_REGISTERER TECH_ID NOT NULL, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP); +CREATE TABLE AUTHORIZATION_GROUP_PERSONS (AG_ID TECH_ID NOT NULL, PERS_ID TECH_ID NOT NULL); + +CREATE TABLE FILTERS (ID TECH_ID NOT NULL, NAME VARCHAR(200) NOT NULL, DESCRIPTION DESCRIPTION_2000,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, PERS_ID_REGISTERER TECH_ID NOT NULL, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, EXPRESSION TEXT NOT NULL, IS_PUBLIC BOOLEAN NOT NULL, GRID_ID VARCHAR(200) NOT NULL); +CREATE TABLE QUERIES (ID TECH_ID NOT NULL, NAME VARCHAR(200) NOT NULL, DESCRIPTION DESCRIPTION_2000,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, PERS_ID_REGISTERER TECH_ID NOT NULL, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, EXPRESSION TEXT NOT NULL, IS_PUBLIC BOOLEAN NOT NULL, QUERY_TYPE QUERY_TYPE NOT NULL, ENTITY_TYPE_CODE CODE, DB_KEY CODE NOT NULL DEFAULT '1'); + +CREATE TABLE relationship_types (id TECH_ID NOT NULL, code CODE NOT NULL, label COLUMN_LABEL, parent_label COLUMN_LABEL, child_label COLUMN_LABEL, description DESCRIPTION_2000, registration_timestamp TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, pers_id_registerer TECH_ID NOT NULL, is_managed_internally BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE sample_relationships_all (id TECH_ID NOT NULL, sample_id_parent TECH_ID NOT NULL, relationship_id TECH_ID NOT NULL, sample_id_child TECH_ID NOT NULL, del_id TECH_ID, PERS_ID_AUTHOR TECH_ID, REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, MODIFICATION_TIMESTAMP TIME_STAMP DEFAULT CURRENT_TIMESTAMP, PARENT_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', CHILD_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F', CHILD_ANNOTATIONS JSONB, PARENT_ANNOTATIONS JSONB); + +CREATE TABLE scripts (ID TECH_ID NOT NULL, NAME VARCHAR(200) NOT NULL, SCRIPT_TYPE SCRIPT_TYPE NOT NULL, DESCRIPTION DESCRIPTION_2000,SCRIPT TEXT_VALUE,REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP,PERS_ID_REGISTERER TECH_ID NOT NULL,ENTITY_KIND ENTITY_KIND, PLUGIN_TYPE PLUGIN_TYPE NOT NULL DEFAULT 'JYTHON', IS_AVAILABLE BOOLEAN_CHAR NOT NULL DEFAULT TRUE); + +CREATE TABLE CORE_PLUGINS (ID TECH_ID NOT NULL, NAME VARCHAR(200) NOT NULL, VERSION INTEGER NOT NULL, REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, MASTER_REG_SCRIPT TEXT_VALUE); + +CREATE TABLE POST_REGISTRATION_DATASET_QUEUE (ID TECH_ID NOT NULL, DS_ID TECH_ID NOT NULL); + +CREATE TABLE ENTITY_OPERATIONS_LOG (ID TECH_ID NOT NULL, REGISTRATION_ID TECH_ID NOT NULL); + +CREATE TABLE PROJECT_RELATIONSHIPS_HISTORY (ID TECH_ID NOT NULL, MAIN_PROJ_ID TECH_ID NOT NULL, RELATION_TYPE TEXT_VALUE, EXPE_ID TECH_ID, SAMP_ID TECH_ID, SPACE_ID TECH_ID, ENTITY_KIND TEXT_VALUE, ENTITY_PERM_ID TEXT_VALUE, PERS_ID_AUTHOR TECH_ID, VALID_FROM_TIMESTAMP TIME_STAMP NOT NULL, VALID_UNTIL_TIMESTAMP TIME_STAMP); +CREATE TABLE EXPERIMENT_RELATIONSHIPS_HISTORY (ID TECH_ID NOT NULL, MAIN_EXPE_ID TECH_ID NOT NULL, RELATION_TYPE TEXT_VALUE, SAMP_ID TECH_ID, DATA_ID TECH_ID, ENTITY_KIND TEXT_VALUE, ENTITY_PERM_ID TEXT_VALUE, PERS_ID_AUTHOR TECH_ID, VALID_FROM_TIMESTAMP TIME_STAMP NOT NULL, VALID_UNTIL_TIMESTAMP TIME_STAMP, PROJ_ID TECH_ID); +CREATE TABLE SAMPLE_RELATIONSHIPS_HISTORY (ID TECH_ID NOT NULL, MAIN_SAMP_ID TECH_ID NOT NULL, RELATION_TYPE TEXT_VALUE, EXPE_ID TECH_ID, SAMP_ID TECH_ID, DATA_ID TECH_ID, ENTITY_KIND TEXT_VALUE, ENTITY_PERM_ID TEXT_VALUE, PERS_ID_AUTHOR TECH_ID, VALID_FROM_TIMESTAMP TIME_STAMP NOT NULL, VALID_UNTIL_TIMESTAMP TIME_STAMP, SPACE_ID TECH_ID, PROJ_ID TECH_ID, ANNOTATIONS JSONB); +CREATE TABLE DATA_SET_RELATIONSHIPS_HISTORY (ID TECH_ID NOT NULL, MAIN_DATA_ID TECH_ID NOT NULL, RELATION_TYPE TEXT_VALUE, ORDINAL INTEGER, EXPE_ID TECH_ID, SAMP_ID TECH_ID, DATA_ID TECH_ID, ENTITY_KIND TEXT_VALUE, ENTITY_PERM_ID TEXT_VALUE, PERS_ID_AUTHOR TECH_ID, VALID_FROM_TIMESTAMP TIME_STAMP NOT NULL, VALID_UNTIL_TIMESTAMP TIME_STAMP); + +CREATE TABLE EXTERNAL_DATA_MANAGEMENT_SYSTEMS (ID TECH_ID, CODE CODE NOT NULL, LABEL TEXT_VALUE, ADDRESS TEXT_VALUE NOT NULL, ADDRESS_TYPE EDMS_ADDRESS_TYPE NOT NULL); +CREATE TABLE LINK_DATA(ID TECH_ID NOT NULL, DATA_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F'); +CREATE TABLE CONTENT_COPIES (ID TECH_ID NOT NULL, LOCATION_TYPE LOCATION_TYPE NOT NULL, DATA_ID TECH_ID NOT NULL, EDMS_ID TECH_ID NOT NULL, EXTERNAL_CODE TEXT_VALUE, PATH TEXT_VALUE, GIT_COMMIT_HASH TEXT_VALUE, GIT_REPOSITORY_ID TEXT_VALUE, LOCATION_UNIQUE_CHECK TEXT_VALUE NOT NULL, PERS_ID_REGISTERER TECH_ID, REGISTRATION_TIMESTAMP TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP, DATA_FROZEN BOOLEAN_CHAR NOT NULL DEFAULT 'F'); + +CREATE TABLE METAPROJECTS (ID TECH_ID NOT NULL, NAME CODE NOT NULL, DESCRIPTION DESCRIPTION_2000, OWNER TECH_ID NOT NULL, PRIVATE BOOLEAN_CHAR NOT NULL DEFAULT TRUE, CREATION_DATE TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP); +CREATE TABLE METAPROJECT_ASSIGNMENTS_ALL (ID TECH_ID NOT NULL, MEPR_ID TECH_ID NOT NULL, EXPE_ID TECH_ID, SAMP_ID TECH_ID, DATA_ID TECH_ID, MATE_ID TECH_ID, DEL_ID TECH_ID, CREATION_DATE TIME_STAMP_DFL NOT NULL DEFAULT CURRENT_TIMESTAMP); + +CREATE TABLE OPERATION_EXECUTIONS ( + ID TECH_ID NOT NULL, + CODE CODE NOT NULL, + STATE OPERATION_EXECUTION_STATE NOT NULL DEFAULT 'NEW', + OWNER TECH_ID NOT NULL, + DESCRIPTION TEXT_VALUE, + NOTIFICATION TEXT_VALUE, + AVAILABILITY OPERATION_EXECUTION_AVAILABILITY NOT NULL DEFAULT 'AVAILABLE', + AVAILABILITY_TIME BIGINT NOT NULL DEFAULT 1, + SUMMARY_OPERATIONS TEXT_VALUE, + SUMMARY_PROGRESS TEXT_VALUE, + SUMMARY_ERROR TEXT_VALUE, + SUMMARY_RESULTS TEXT_VALUE, + SUMMARY_AVAILABILITY OPERATION_EXECUTION_AVAILABILITY NOT NULL DEFAULT 'AVAILABLE', + SUMMARY_AVAILABILITY_TIME BIGINT NOT NULL DEFAULT 1, + DETAILS_PATH VARCHAR(1000), + DETAILS_AVAILABILITY OPERATION_EXECUTION_AVAILABILITY NOT NULL DEFAULT 'AVAILABLE', + DETAILS_AVAILABILITY_TIME BIGINT NOT NULL DEFAULT 1, + CREATION_DATE TIME_STAMP_DFL NOT NULL, + START_DATE TIME_STAMP, + FINISH_DATE TIME_STAMP +); + +CREATE TABLE data_set_copies_history ( + id TECH_ID NOT NULL, + cc_id TECH_ID NOT NULL, + data_id TECH_ID NOT NULL, + external_code TEXT_VALUE, + path TEXT_VALUE, + git_commit_hash TEXT_VALUE, + git_repository_id TEXT_VALUE, + edms_id TECH_ID NOT NULL, + edms_code CODE, + edms_label TEXT_VALUE, + edms_address TEXT_VALUE, + pers_id_author TECH_ID, + valid_from_timestamp TIME_STAMP NOT NULL, + valid_until_timestamp TIME_STAMP); + +CREATE TABLE SEMANTIC_ANNOTATIONS (ID TECH_ID NOT NULL, + PERM_ID CODE NOT NULL, + SATY_ID TECH_ID, + STPT_ID TECH_ID, + PRTY_ID TECH_ID, + PREDICATE_ONTOLOGY_ID TEXT, + PREDICATE_ONTOLOGY_VERSION TEXT, + PREDICATE_ACCESSION_ID TEXT, + DESCRIPTOR_ONTOLOGY_ID TEXT, + DESCRIPTOR_ONTOLOGY_VERSION TEXT, + DESCRIPTOR_ACCESSION_ID TEXT, + CREATION_DATE time_stamp_dfl NOT NULL + ); + +-- Creating views - copied from schema generated for tests, '*' can't be used because of PgDiffViews limitation in view comparison + +CREATE VIEW data AS + SELECT id, code, dsty_id, dast_id, expe_id, expe_frozen, data_producer_code, production_timestamp, samp_id, samp_frozen, + registration_timestamp, access_timestamp, pers_id_registerer, pers_id_modifier, is_valid, modification_timestamp, + is_derived, del_id, orig_del, version, data_set_kind, + frozen, frozen_for_children, frozen_for_parents, frozen_for_comps, frozen_for_conts, tsvector_document + FROM data_all + WHERE del_id IS NULL; + +CREATE VIEW data_deleted AS + SELECT id, code, dsty_id, dast_id, expe_id, data_producer_code, production_timestamp, samp_id, registration_timestamp, access_timestamp, pers_id_registerer, pers_id_modifier, is_valid, modification_timestamp, is_derived, del_id, orig_del, version, data_set_kind + FROM data_all + WHERE del_id IS NOT NULL; + +CREATE VIEW experiments AS + SELECT id, perm_id, code, exty_id, pers_id_registerer, pers_id_modifier, registration_timestamp, modification_timestamp, + proj_id, proj_frozen, del_id, orig_del, is_public, version, frozen, frozen_for_samp, frozen_for_data, tsvector_document + FROM experiments_all + WHERE del_id IS NULL; + +CREATE VIEW experiments_deleted AS + SELECT id, perm_id, code, exty_id, pers_id_registerer, pers_id_modifier, registration_timestamp, modification_timestamp, proj_id, del_id, orig_del, is_public, version + FROM experiments_all + WHERE del_id IS NOT NULL; + +CREATE VIEW samples AS + SELECT id, perm_id, code, proj_id, proj_frozen, expe_id, expe_frozen, saty_id, registration_timestamp, + modification_timestamp, pers_id_registerer, pers_id_modifier, del_id, orig_del, space_id, space_frozen, + samp_id_part_of, cont_frozen, version, frozen, frozen_for_comp, frozen_for_children, frozen_for_parents, frozen_for_data, tsvector_document, sample_identifier + FROM samples_all + WHERE del_id IS NULL; + +CREATE VIEW samples_deleted AS + SELECT id, perm_id, code, expe_id, saty_id, registration_timestamp, modification_timestamp, pers_id_registerer, pers_id_modifier, del_id, orig_del, space_id, proj_id, samp_id_part_of, version + FROM samples_all + WHERE del_id IS NOT NULL; + +CREATE VIEW data_set_relationships AS + SELECT data_id_parent, parent_frozen, cont_frozen, data_id_child, child_frozen, comp_frozen, + relationship_id, ordinal, del_id, pers_id_author, registration_timestamp, modification_timestamp + FROM data_set_relationships_all + WHERE del_id IS NULL; + +CREATE VIEW sample_relationships AS + SELECT id, sample_id_parent, parent_frozen, relationship_id, sample_id_child, child_frozen, del_id, pers_id_author, registration_timestamp, modification_timestamp, child_annotations, parent_annotations + FROM sample_relationships_all + WHERE del_id IS NULL; + +CREATE VIEW METAPROJECT_ASSIGNMENTS AS + SELECT ID, MEPR_ID, EXPE_ID, SAMP_ID, DATA_ID, MATE_ID, DEL_ID, CREATION_DATE + FROM METAPROJECT_ASSIGNMENTS_ALL + WHERE DEL_ID IS NULL; + +CREATE VIEW sample_history_view AS ( + SELECT + 2*id as id, + main_samp_id, + relation_type, + space_id, + expe_id, + samp_id, + proj_id, + data_id, + entity_kind, + entity_perm_id, + annotations, + null as stpt_id, + null as value, + null as vocabulary_term, + null as material, + null as sample, + pers_id_author, + valid_from_timestamp, + valid_until_timestamp + FROM + SAMPLE_RELATIONSHIPS_HISTORY + WHERE + valid_until_timestamp IS NOT NULL) +UNION + SELECT + 2*id+1 as id, + samp_id as main_samp_id, + null as relation_type, + null as space_id, + null as expe_id, + null as samp_id, + null as proj_id, + null as data_id, + null as entity_kind, + null as entity_perm_id, + null as annotations, + stpt_id, + value, + vocabulary_term, + material, + sample, + pers_id_author, + valid_from_timestamp, + valid_until_timestamp + FROM + SAMPLE_PROPERTIES_HISTORY; + +CREATE VIEW data_set_history_view AS ( + SELECT + 3*id as id, + main_data_id, + relation_type, + ordinal, + expe_id, + samp_id, + data_id, + entity_kind, + entity_perm_id, + null as dstpt_id, + null as value, + null as vocabulary_term, + null as material, + null as sample, + null as external_code, + null as path, + null as git_commit_hash, + null as git_repository_id, + null::TECH_ID as edms_id, + null as edms_code, + null as edms_label, + null as edms_address, + pers_id_author, + valid_from_timestamp, + valid_until_timestamp + FROM + data_set_relationships_history + WHERE + valid_until_timestamp IS NOT NULL) +UNION + SELECT + 3*id+1 as id, + ds_id as main_data_id, + null as relation_type, + null as ordinal, + null as expe_id, + null as samp_id, + null as data_id, + null as entity_kind, + null as entity_perm_id, + dstpt_id, + value, + vocabulary_term, + material, + sample, + null as external_code, + null as path, + null as git_commit_hash, + null as git_repository_id, + null as edms_id, + null as edms_code, + null as edms_label, + null as edms_address, + pers_id_author, + valid_from_timestamp, + valid_until_timestamp + FROM + data_set_properties_history + UNION + (SELECT + 3*id+2 as id, + data_id as main_data_id, + null as relation_type, + null as ordinal, + null as expe_id, + null as samp_id, + null as data_id, + null as entity_kind, + null as entity_perm_id, + null as dstpt_id, + null as value, + null as vocabulary_term, + null as material, + null as sample, + external_code, + path, + git_commit_hash, + git_repository_id, + edms_id, + edms_code, + edms_label, + edms_address, + pers_id_author, + valid_from_timestamp, + valid_until_timestamp + FROM + data_set_copies_history + WHERE + valid_until_timestamp IS NOT NULL); + +CREATE VIEW experiment_history_view AS ( + SELECT + 2*id as id, + main_expe_id, + relation_type, + proj_id, + samp_id, + data_id, + entity_kind, + entity_perm_id, + null as etpt_id, + null as value, + null as vocabulary_term, + null as material, + null as sample, + pers_id_author, + valid_from_timestamp, + valid_until_timestamp + FROM + EXPERIMENT_RELATIONSHIPS_HISTORY + WHERE valid_until_timestamp IS NOT NULL) +UNION + SELECT + 2*id+1 as id, + expe_id as main_expe_id, + null as relation_type, + null as proj_id, + null as samp_id, + null as data_id, + null as entity_kind, + null as entity_perm_id, + etpt_id, + value, + vocabulary_term, + material, + sample, + pers_id_author, + valid_from_timestamp, + valid_until_timestamp + FROM + EXPERIMENT_PROPERTIES_HISTORY; + +-- Creating sequences + +CREATE SEQUENCE CONTROLLED_VOCABULARY_ID_SEQ; +CREATE SEQUENCE CVTE_ID_SEQ; +CREATE SEQUENCE DATABASE_INSTANCE_ID_SEQ; +CREATE SEQUENCE DATA_ID_SEQ; +CREATE SEQUENCE DATA_SET_RELATIONSHIP_ID_SEQ; +CREATE SEQUENCE DATA_STORE_ID_SEQ; +CREATE SEQUENCE DATA_STORE_SERVICES_ID_SEQ; +CREATE SEQUENCE DATA_TYPE_ID_SEQ; +CREATE SEQUENCE ETPT_ID_SEQ; +CREATE SEQUENCE EVENT_ID_SEQ; +CREATE SEQUENCE EVENTS_SEARCH_ID_SEQ; +CREATE SEQUENCE ATTACHMENT_ID_SEQ; +CREATE SEQUENCE ATTACHMENT_CONTENT_ID_SEQ; +CREATE SEQUENCE EXPERIMENT_ID_SEQ; +CREATE SEQUENCE EXPERIMENT_PROPERTY_ID_SEQ; +CREATE SEQUENCE EXPERIMENT_TYPE_ID_SEQ; +CREATE SEQUENCE FILE_FORMAT_TYPE_ID_SEQ; +CREATE SEQUENCE SPACE_ID_SEQ; +CREATE SEQUENCE DELETION_ID_SEQ; +CREATE SEQUENCE LOCATOR_TYPE_ID_SEQ; +CREATE SEQUENCE MATERIAL_ID_SEQ; +CREATE SEQUENCE MATERIAL_PROPERTY_ID_SEQ; +CREATE SEQUENCE MATERIAL_TYPE_ID_SEQ; +CREATE SEQUENCE MTPT_ID_SEQ; +CREATE SEQUENCE DATA_SET_TYPE_ID_SEQ; +CREATE SEQUENCE PERSON_ID_SEQ; +CREATE SEQUENCE PROJECT_ID_SEQ; +CREATE SEQUENCE PROPERTY_TYPE_ID_SEQ; +CREATE SEQUENCE ROLE_ASSIGNMENT_ID_SEQ; +CREATE SEQUENCE SAMPLE_ID_SEQ; +CREATE SEQUENCE SAMPLE_PROPERTY_ID_SEQ; +CREATE SEQUENCE SAMPLE_TYPE_ID_SEQ; +CREATE SEQUENCE STPT_ID_SEQ; +CREATE SEQUENCE DATA_SET_PROPERTY_ID_SEQ; +CREATE SEQUENCE DSTPT_ID_SEQ; +CREATE SEQUENCE CODE_SEQ; +CREATE SEQUENCE EXPERIMENT_CODE_SEQ; +CREATE SEQUENCE SAMPLE_CODE_SEQ; +CREATE SEQUENCE PERM_ID_SEQ; +CREATE SEQUENCE AUTHORIZATION_GROUP_ID_SEQ; +CREATE SEQUENCE FILTER_ID_SEQ; +CREATE SEQUENCE GRID_CUSTOM_COLUMNS_ID_SEQ; +CREATE SEQUENCE QUERY_ID_SEQ; +CREATE SEQUENCE RELATIONSHIP_TYPE_ID_SEQ; +CREATE SEQUENCE SAMPLE_RELATIONSHIP_ID_SEQ; +CREATE SEQUENCE SCRIPT_ID_SEQ; +CREATE SEQUENCE CORE_PLUGIN_ID_SEQ; +CREATE SEQUENCE POST_REGISTRATION_DATASET_QUEUE_ID_SEQ; +CREATE SEQUENCE ENTITY_OPERATIONS_LOG_ID_SEQ; +CREATE SEQUENCE EXPERIMENT_RELATIONSHIPS_HISTORY_ID_SEQ; +CREATE SEQUENCE SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ; +CREATE SEQUENCE DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ; +CREATE SEQUENCE PROJECT_RELATIONSHIPS_HISTORY_ID_SEQ; +CREATE SEQUENCE EXTERNAL_DATA_MANAGEMENT_SYSTEM_ID_SEQ; +CREATE SEQUENCE METAPROJECT_ID_SEQ; +CREATE SEQUENCE METAPROJECT_ASSIGNMENT_ID_SEQ; +CREATE SEQUENCE OPERATION_EXECUTIONS_ID_SEQ; +CREATE SEQUENCE CONTENT_COPIES_ID_SEQ; +CREATE SEQUENCE DATA_SET_COPIES_HISTORY_ID_SEQ; +CREATE SEQUENCE SEMANTIC_ANNOTATION_ID_SEQ; + +-- Creating primary key constraints + +ALTER TABLE CONTROLLED_VOCABULARIES ADD CONSTRAINT COVO_PK PRIMARY KEY(ID); +ALTER TABLE CONTROLLED_VOCABULARY_TERMS ADD CONSTRAINT CVTE_PK PRIMARY KEY(ID); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_PK PRIMARY KEY(ID); +ALTER TABLE DATA_STORES ADD CONSTRAINT DAST_PK PRIMARY KEY(ID); +ALTER TABLE DATA_STORE_SERVICES ADD CONSTRAINT DSSE_PK PRIMARY KEY(ID); +ALTER TABLE DATA_TYPES ADD CONSTRAINT DATY_PK PRIMARY KEY(ID); +ALTER TABLE EVENTS ADD CONSTRAINT EVNT_PK PRIMARY KEY(ID); +ALTER TABLE EVENTS_SEARCH ADD CONSTRAINT EVENTS_SEARCH_PK PRIMARY KEY(ID); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_PK PRIMARY KEY(ID); +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_PK PRIMARY KEY(ID); +ALTER TABLE ATTACHMENT_CONTENTS ADD CONSTRAINT EXAC_PK PRIMARY KEY(ID); +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_PK PRIMARY KEY(ID); +ALTER TABLE EXPERIMENT_PROPERTIES_HISTORY ADD CONSTRAINT EXPRH_PK PRIMARY KEY(ID); +ALTER TABLE EXPERIMENT_TYPES ADD CONSTRAINT EXTY_PK PRIMARY KEY(ID); +ALTER TABLE EXPERIMENT_TYPE_PROPERTY_TYPES ADD CONSTRAINT ETPT_PK PRIMARY KEY(ID); +ALTER TABLE EXTERNAL_DATA ADD CONSTRAINT EXDA_PK PRIMARY KEY(ID); +ALTER TABLE FILE_FORMAT_TYPES ADD CONSTRAINT FFTY_PK PRIMARY KEY(ID); +ALTER TABLE SPACES ADD CONSTRAINT SPACE_PK PRIMARY KEY(ID); +ALTER TABLE DELETIONS ADD CONSTRAINT DEL_PK PRIMARY KEY(ID); +ALTER TABLE LOCATOR_TYPES ADD CONSTRAINT LOTY_PK PRIMARY KEY(ID); +ALTER TABLE MATERIALS ADD CONSTRAINT MATE_PK PRIMARY KEY(ID); +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_PK PRIMARY KEY(ID); +ALTER TABLE MATERIAL_PROPERTIES_HISTORY ADD CONSTRAINT MAPRH_PK PRIMARY KEY(ID); +ALTER TABLE MATERIAL_TYPES ADD CONSTRAINT MATY_PK PRIMARY KEY(ID); +ALTER TABLE MATERIAL_TYPE_PROPERTY_TYPES ADD CONSTRAINT MTPT_PK PRIMARY KEY(ID); +ALTER TABLE DATA_SET_TYPES ADD CONSTRAINT DSTY_PK PRIMARY KEY(ID); +ALTER TABLE PERSONS ADD CONSTRAINT PERS_PK PRIMARY KEY(ID); +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_PK PRIMARY KEY(ID); +ALTER TABLE PROPERTY_TYPES ADD CONSTRAINT PRTY_PK PRIMARY KEY(ID); +ALTER TABLE ROLE_ASSIGNMENTS ADD CONSTRAINT ROAS_PK PRIMARY KEY(ID); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_PK PRIMARY KEY(ID); +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_PK PRIMARY KEY(ID); +ALTER TABLE SAMPLE_PROPERTIES_HISTORY ADD CONSTRAINT SAPRH_PK PRIMARY KEY(ID); +ALTER TABLE SAMPLE_TYPES ADD CONSTRAINT SATY_PK PRIMARY KEY(ID); +ALTER TABLE SAMPLE_TYPE_PROPERTY_TYPES ADD CONSTRAINT STPT_PK PRIMARY KEY(ID); +ALTER TABLE DATA_SET_TYPE_PROPERTY_TYPES ADD CONSTRAINT DSTPT_PK PRIMARY KEY(ID); +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_PK PRIMARY KEY(ID); +ALTER TABLE DATA_SET_PROPERTIES_HISTORY ADD CONSTRAINT DSPRH_PK PRIMARY KEY(ID); +ALTER TABLE AUTHORIZATION_GROUPS ADD CONSTRAINT AG_PK PRIMARY KEY(ID); +ALTER TABLE AUTHORIZATION_GROUP_PERSONS ADD CONSTRAINT AGP_PK PRIMARY KEY(PERS_ID,AG_ID); +ALTER TABLE FILTERS ADD CONSTRAINT FILT_PK PRIMARY KEY(ID); +ALTER TABLE GRID_CUSTOM_COLUMNS ADD CONSTRAINT GRID_CUSTOM_COLUMNS_PK PRIMARY KEY(ID); +ALTER TABLE QUERIES ADD CONSTRAINT QUER_PK PRIMARY KEY(ID); +ALTER TABLE relationship_types ADD CONSTRAINT rety_pk PRIMARY KEY (id); +ALTER TABLE sample_relationships_all ADD CONSTRAINT sare_pk PRIMARY KEY (id); +ALTER TABLE SCRIPTS ADD CONSTRAINT SCRI_PK PRIMARY KEY(ID); +ALTER TABLE POST_REGISTRATION_DATASET_QUEUE ADD CONSTRAINT PRDQ_PK PRIMARY KEY(ID); +ALTER TABLE ENTITY_OPERATIONS_LOG ADD CONSTRAINT EOL_PK PRIMARY KEY(ID); +ALTER TABLE EXPERIMENT_RELATIONSHIPS_HISTORY ADD CONSTRAINT EXRELH_PK PRIMARY KEY(ID); +ALTER TABLE SAMPLE_RELATIONSHIPS_HISTORY ADD CONSTRAINT SAMPRELH_PK PRIMARY KEY(ID); +ALTER TABLE DATA_SET_RELATIONSHIPS_HISTORY ADD CONSTRAINT DATARELH_PK PRIMARY KEY(ID); +ALTER TABLE PROJECT_RELATIONSHIPS_HISTORY ADD CONSTRAINT PRRELH_PK PRIMARY KEY(ID); +ALTER TABLE EXTERNAL_DATA_MANAGEMENT_SYSTEMS ADD CONSTRAINT EDMS_PK PRIMARY KEY(ID); +ALTER TABLE CONTENT_COPIES ADD CONSTRAINT COCO_PK PRIMARY KEY(ID); +ALTER TABLE LINK_DATA ADD CONSTRAINT lnda_pk PRIMARY KEY(id); +ALTER TABLE METAPROJECTS ADD CONSTRAINT METAPROJECTS_PK PRIMARY KEY(ID); +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_PK PRIMARY KEY(ID); +ALTER TABLE OPERATION_EXECUTIONS ADD CONSTRAINT OPERATION_EXECUTIONS_PK PRIMARY KEY(ID); +ALTER TABLE DATA_SET_COPIES_HISTORY ADD CONSTRAINT DSCH_PK PRIMARY KEY(ID); +ALTER TABLE SEMANTIC_ANNOTATIONS ADD CONSTRAINT SEMANTIC_ANNOTATIONS_PK PRIMARY KEY(ID); + +-- Creating unique constraints + +ALTER TABLE CONTROLLED_VOCABULARIES ADD CONSTRAINT COVO_BK_UK UNIQUE(CODE,IS_MANAGED_INTERNALLY); +ALTER TABLE CONTROLLED_VOCABULARY_TERMS ADD CONSTRAINT CVTE_BK_UK UNIQUE(CODE,COVO_ID); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_IDFRZ_UK UNIQUE(ID, FROZEN); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_IDFRZ_CH_UK UNIQUE(ID, FROZEN_FOR_CHILDREN); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_IDFRZ_P_UK UNIQUE(ID, FROZEN_FOR_PARENTS); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_IDFRZ_COMP_UK UNIQUE(ID, FROZEN_FOR_COMPS); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_IDFRZ_CONT_UK UNIQUE(ID, FROZEN_FOR_CONTS); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_BK_UK UNIQUE(CODE); +ALTER TABLE DATA_SET_RELATIONSHIPS_ALL ADD CONSTRAINT DSRE_BK_UK UNIQUE(DATA_ID_CHILD,DATA_ID_PARENT,RELATIONSHIP_ID); +ALTER TABLE DATA_STORE_SERVICES ADD CONSTRAINT DSSE_BK_UK UNIQUE(KEY, DATA_STORE_ID); +ALTER TABLE DATA_STORE_SERVICE_DATA_SET_TYPES ADD CONSTRAINT DSSDST_BK_UK UNIQUE(DATA_STORE_SERVICE_ID, DATA_SET_TYPE_ID); +ALTER TABLE DATA_STORES ADD CONSTRAINT DAST_BK_UK UNIQUE(CODE,UUID); +ALTER TABLE DATA_TYPES ADD CONSTRAINT DATY_BK_UK UNIQUE(CODE); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_IDFRZ_UK UNIQUE(ID, FROZEN); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_IDFRZ_S_UK UNIQUE(ID, FROZEN_FOR_SAMP); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_IDFRZ_D_UK UNIQUE(ID, FROZEN_FOR_DATA); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_BK_UK UNIQUE(CODE,PROJ_ID); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_PI_UK UNIQUE(PERM_ID); +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_BK_UK UNIQUE(EXPE_ID,ETPT_ID); +ALTER TABLE EXPERIMENT_TYPE_PROPERTY_TYPES ADD CONSTRAINT ETPT_BK_UK UNIQUE(EXTY_ID,PRTY_ID); +ALTER TABLE EXTERNAL_DATA ADD CONSTRAINT EXDA_BK_UK UNIQUE(LOCATION,LOTY_ID); +ALTER TABLE FILE_FORMAT_TYPES ADD CONSTRAINT FFTY_BK_UK UNIQUE(CODE); +ALTER TABLE LOCATOR_TYPES ADD CONSTRAINT LOTY_BK_UK UNIQUE(CODE); +ALTER TABLE MATERIALS ADD CONSTRAINT MATE_BK_UK UNIQUE(CODE,MATY_ID); +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_BK_UK UNIQUE(MATE_ID,MTPT_ID); +ALTER TABLE MATERIAL_TYPE_PROPERTY_TYPES ADD CONSTRAINT MTPT_BK_UK UNIQUE(MATY_ID,PRTY_ID); +ALTER TABLE PERSONS ADD CONSTRAINT PERS_BK_UK UNIQUE(USER_ID); +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_IDFRZ_UK UNIQUE(ID, FROZEN); +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_IDFRZ_E_UK UNIQUE(ID, FROZEN_FOR_EXP); +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_IDFRZ_S_UK UNIQUE(ID, FROZEN_FOR_SAMP); +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_BK_UK UNIQUE(CODE,SPACE_ID); +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_PI_UK UNIQUE(PERM_ID); +ALTER TABLE PROPERTY_TYPES ADD CONSTRAINT PRTY_BK_UK UNIQUE(CODE,IS_MANAGED_INTERNALLY); +CREATE UNIQUE INDEX ROAS_PE_SPACE_PROJECT_BK_UK ON ROLE_ASSIGNMENTS (PERS_ID_GRANTEE, ROLE_CODE, coalesce(SPACE_ID,-1), coalesce(PROJECT_ID,-1)); +CREATE UNIQUE INDEX ROAS_AG_SPACE_PROJECT_BK_UK ON ROLE_ASSIGNMENTS (AG_ID_GRANTEE, ROLE_CODE, coalesce(SPACE_ID,-1), coalesce(PROJECT_ID,-1)); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_IDFRZ_UK UNIQUE(ID, FROZEN); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_IDFRZ_C_UK UNIQUE(ID, FROZEN_FOR_COMP); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_IDFRZ_CH_UK UNIQUE(ID, FROZEN_FOR_CHILDREN); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_IDFRZ_P_UK UNIQUE(ID, FROZEN_FOR_PARENTS); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_IDFRZ_D_UK UNIQUE(ID, FROZEN_FOR_DATA); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_PI_UK UNIQUE(PERM_ID); +ALTER TABLE samples_all ADD CONSTRAINT samp_code_unique_check_uk UNIQUE(code_unique_check); +ALTER TABLE samples_all ADD CONSTRAINT samp_subcode_unique_check_uk UNIQUE(subcode_unique_check); +ALTER TABLE samples_all ADD CONSTRAINT samp_identifier_uk UNIQUE(sample_identifier); +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_BK_UK UNIQUE(SAMP_ID,STPT_ID); +ALTER TABLE SAMPLE_TYPE_PROPERTY_TYPES ADD CONSTRAINT STPT_BK_UK UNIQUE(SATY_ID,PRTY_ID); +ALTER TABLE SPACES ADD CONSTRAINT SPACE_IDFRZ_UK UNIQUE(ID, FROZEN); +ALTER TABLE SPACES ADD CONSTRAINT SPACE_IDFRZ_P_UK UNIQUE(ID, FROZEN_FOR_PROJ); +ALTER TABLE SPACES ADD CONSTRAINT SPACE_IDFRZ_S_UK UNIQUE(ID, FROZEN_FOR_SAMP); +ALTER TABLE DATA_SET_TYPE_PROPERTY_TYPES ADD CONSTRAINT DSTPT_BK_UK UNIQUE(DSTY_ID,PRTY_ID); +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_BK_UK UNIQUE(DS_ID,DSTPT_ID); +-- NOTE: following uniqueness constraints for attachments work, because (null != null) in Postgres +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_EXPE_BK_UK UNIQUE(EXPE_ID,FILE_NAME,VERSION); +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_PROJ_BK_UK UNIQUE(PROJ_ID,FILE_NAME,VERSION); +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_SAMP_BK_UK UNIQUE(SAMP_ID,FILE_NAME,VERSION); +ALTER TABLE AUTHORIZATION_GROUPS ADD CONSTRAINT AG_BK_UK UNIQUE(CODE); +ALTER TABLE FILTERS ADD CONSTRAINT FILT_BK_UK UNIQUE(NAME, GRID_ID); +ALTER TABLE GRID_CUSTOM_COLUMNS ADD CONSTRAINT GRID_CUSTOM_COLUMNS_BK_UK UNIQUE(CODE, GRID_ID); +ALTER TABLE QUERIES ADD CONSTRAINT QUER_BK_UK UNIQUE(NAME); +ALTER TABLE sample_relationships_all ADD CONSTRAINT sare_bk_uk UNIQUE(sample_id_child,sample_id_parent,relationship_id); +ALTER TABLE relationship_types ADD CONSTRAINT rety_uk UNIQUE(code); +ALTER TABLE SCRIPTS ADD CONSTRAINT SCRI_UK UNIQUE(NAME); +ALTER TABLE CORE_PLUGINS ADD CONSTRAINT COPL_NAME_VER_UK UNIQUE(NAME,VERSION); +ALTER TABLE ENTITY_OPERATIONS_LOG ADD CONSTRAINT EOL_REG_ID_UK UNIQUE(REGISTRATION_ID); +ALTER TABLE EXTERNAL_DATA_MANAGEMENT_SYSTEMS ADD CONSTRAINT EDMS_CODE_UK UNIQUE(CODE); +ALTER TABLE SAMPLE_TYPE_PROPERTY_TYPES ADD CONSTRAINT SAMPLE_TYPE_PROPERTY_TYPES_UNIQUE UNIQUE (ID, IS_UNIQUE); +ALTER TABLE EXPERIMENT_TYPE_PROPERTY_TYPES ADD CONSTRAINT EXPERIMENT_TYPE_PROPERTY_TYPES_UNIQUE UNIQUE (ID, IS_UNIQUE); +ALTER TABLE DATA_SET_TYPE_PROPERTY_TYPES ADD CONSTRAINT DATA_SET_TYPE_PROPERTY_TYPES_UNIQUE UNIQUE (ID, IS_UNIQUE); +ALTER TABLE MATERIAL_TYPE_PROPERTY_TYPES ADD CONSTRAINT MATERIAL_TYPE_PROPERTY_TYPES_UNIQUE UNIQUE (ID, IS_UNIQUE); +-- NOTE: following uniqueness constraints for metaproject assignments work, because (null != null) in Postgres +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_MEPR_ID_EXPE_ID_UK UNIQUE (MEPR_ID, EXPE_ID); +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_MEPR_ID_SAMP_ID_UK UNIQUE (MEPR_ID, SAMP_ID); +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_MEPR_ID_DATA_ID_UK UNIQUE (MEPR_ID, DATA_ID); +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_MEPR_ID_MATE_ID_UK UNIQUE (MEPR_ID, MATE_ID); +ALTER TABLE OPERATION_EXECUTIONS ADD CONSTRAINT OPERATION_EXECUTIONS_CODE_UK UNIQUE (CODE); +ALTER TABLE CONTENT_COPIES ADD CONSTRAINT content_copies_unique_check_uk UNIQUE(location_unique_check); +ALTER TABLE SEMANTIC_ANNOTATIONS ADD CONSTRAINT SEMANTIC_ANNOTATIONS_PERM_ID_UK UNIQUE (PERM_ID); + +-- Creating foreign key constraints + +ALTER TABLE CONTROLLED_VOCABULARIES ADD CONSTRAINT COVO_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE CONTROLLED_VOCABULARY_TERMS ADD CONSTRAINT CVTE_COVO_FK FOREIGN KEY (COVO_ID) REFERENCES CONTROLLED_VOCABULARIES(ID); +ALTER TABLE CONTROLLED_VOCABULARY_TERMS ADD CONSTRAINT CVTE_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_DSTY_FK FOREIGN KEY (DSTY_ID) REFERENCES DATA_SET_TYPES(ID); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_EXPE_FK FOREIGN KEY (EXPE_ID, EXPE_FROZEN) REFERENCES EXPERIMENTS_ALL(ID, FROZEN_FOR_DATA) ON UPDATE CASCADE; +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_SAMP_FK FOREIGN KEY (SAMP_ID, SAMP_FROZEN) REFERENCES SAMPLES_ALL(ID, FROZEN_FOR_DATA) ON UPDATE CASCADE; +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_DAST_FK FOREIGN KEY (DAST_ID) REFERENCES DATA_STORES(ID); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_DEL_FK FOREIGN KEY (DEL_ID) REFERENCES DELETIONS(ID); +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_PERS_FK_MOD FOREIGN KEY (PERS_ID_MODIFIER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DATA_SET_RELATIONSHIPS_ALL ADD CONSTRAINT DSRE_DATA_FK_CHILD FOREIGN KEY (DATA_ID_CHILD, CHILD_FROZEN) REFERENCES DATA_ALL(ID, FROZEN_FOR_PARENTS) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE DATA_SET_RELATIONSHIPS_ALL ADD CONSTRAINT DSRE_DATA_FK_PARENT FOREIGN KEY (DATA_ID_PARENT, PARENT_FROZEN) REFERENCES DATA_ALL(ID, FROZEN_FOR_CHILDREN) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE DATA_SET_RELATIONSHIPS_ALL ADD CONSTRAINT DSRE_DATA_FK_COMP FOREIGN KEY (DATA_ID_CHILD, COMP_FROZEN) REFERENCES DATA_ALL(ID, FROZEN_FOR_CONTS) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE DATA_SET_RELATIONSHIPS_ALL ADD CONSTRAINT DSRE_DATA_FK_CONT FOREIGN KEY (DATA_ID_PARENT, CONT_FROZEN) REFERENCES DATA_ALL(ID, FROZEN_FOR_COMPS) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE DATA_SET_RELATIONSHIPS_ALL ADD CONSTRAINT DSRE_DATA_FK_RELATIONSHIP FOREIGN KEY (RELATIONSHIP_ID) REFERENCES RELATIONSHIP_TYPES(ID); +ALTER TABLE DATA_SET_RELATIONSHIPS_ALL ADD CONSTRAINT DSRE_DEL_FK FOREIGN KEY (DEL_ID) REFERENCES DELETIONS(ID); +ALTER TABLE DATA_SET_RELATIONSHIPS_ALL ADD CONSTRAINT DATA_SET_RELATIONSHIPS_PERS_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE sample_relationships_all ADD CONSTRAINT sare_data_fk_child FOREIGN KEY (sample_id_child, CHILD_FROZEN) REFERENCES SAMPLES_ALL(id, FROZEN_FOR_PARENTS) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE sample_relationships_all ADD CONSTRAINT sare_data_fk_parent FOREIGN KEY (sample_id_parent, PARENT_FROZEN) REFERENCES SAMPLES_ALL(id, FROZEN_FOR_CHILDREN) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE sample_relationships_all ADD CONSTRAINT sare_data_fk_relationship FOREIGN KEY (relationship_id) REFERENCES relationship_types(id); +ALTER TABLE sample_relationships_all ADD CONSTRAINT sare_del_fk FOREIGN KEY (del_id) REFERENCES deletions(id); +ALTER TABLE SAMPLE_RELATIONSHIPS_ALL ADD CONSTRAINT SAMPLE_RELATIONSHIPS_PERS_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DATA_STORE_SERVICES ADD CONSTRAINT DSSE_DS_FK FOREIGN KEY (DATA_STORE_ID) REFERENCES DATA_STORES(ID) ON DELETE CASCADE; +ALTER TABLE DATA_STORE_SERVICE_DATA_SET_TYPES ADD CONSTRAINT DSSDST_DS_FK FOREIGN KEY (DATA_STORE_SERVICE_ID) REFERENCES DATA_STORE_SERVICES(ID) ON DELETE CASCADE; +ALTER TABLE DATA_STORE_SERVICE_DATA_SET_TYPES ADD CONSTRAINT DSSDST_DST_FK FOREIGN KEY (DATA_SET_TYPE_ID) REFERENCES DATA_SET_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE EVENTS ADD CONSTRAINT EVNT_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE EVENTS ADD CONSTRAINT EVNT_EXAC_FK FOREIGN KEY (EXAC_ID) REFERENCES ATTACHMENT_CONTENTS(ID); +ALTER TABLE EVENTS_SEARCH ADD CONSTRAINT EVENTS_SEARCH_PERS_ID_REGISTERER_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE EVENTS_SEARCH ADD CONSTRAINT EVENTS_SEARCH_EXAC_ID_FK FOREIGN KEY (EXAC_ID) REFERENCES ATTACHMENT_CONTENTS(ID); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_EXTY_FK FOREIGN KEY (EXTY_ID) REFERENCES EXPERIMENT_TYPES(ID); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_DEL_FK FOREIGN KEY (DEL_ID) REFERENCES DELETIONS(ID); +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_PROJ_FK FOREIGN KEY (PROJ_ID, PROJ_FROZEN) REFERENCES PROJECTS(ID, FROZEN_FOR_EXP) ON UPDATE CASCADE; +ALTER TABLE EXPERIMENTS_ALL ADD CONSTRAINT EXPE_PERS_FK_MOD FOREIGN KEY (PERS_ID_MODIFIER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_EXPE_FK FOREIGN KEY (EXPE_ID, EXPE_FROZEN) REFERENCES EXPERIMENTS_ALL(ID, FROZEN) ON UPDATE CASCADE; +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_PROJ_FK FOREIGN KEY (PROJ_ID, PROJ_FROZEN) REFERENCES PROJECTS(ID, FROZEN) ON UPDATE CASCADE; +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_SAMP_FK FOREIGN KEY (SAMP_ID, SAMP_FROZEN) REFERENCES SAMPLES_ALL(ID, FROZEN) ON UPDATE CASCADE; +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_CONT_FK FOREIGN KEY (EXAC_ID) REFERENCES ATTACHMENT_CONTENTS(ID); +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_CVTE_FK FOREIGN KEY (CVTE_ID) REFERENCES CONTROLLED_VOCABULARY_TERMS(ID); +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_ETPT_FK FOREIGN KEY (ETPT_ID) REFERENCES EXPERIMENT_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_EXPE_FK FOREIGN KEY (EXPE_ID, EXPE_FROZEN) REFERENCES EXPERIMENTS_ALL(ID, FROZEN) ON UPDATE CASCADE; +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_MAPR_FK FOREIGN KEY (MATE_PROP_ID) REFERENCES MATERIALS(ID); +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE EXPERIMENT_PROPERTIES_HISTORY ADD CONSTRAINT EXPRH_ETPT_FK FOREIGN KEY (ETPT_ID) REFERENCES EXPERIMENT_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE EXPERIMENT_PROPERTIES_HISTORY ADD CONSTRAINT EXPRH_EXPE_FK FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS_ALL(ID) ON DELETE CASCADE; +ALTER TABLE EXPERIMENT_PROPERTIES_HISTORY ADD CONSTRAINT EXPRH_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE EXPERIMENT_TYPES ADD CONSTRAINT EXTY_SCRIPT_FK FOREIGN KEY (VALIDATION_SCRIPT_ID) REFERENCES SCRIPTS(ID); +ALTER TABLE EXPERIMENT_TYPE_PROPERTY_TYPES ADD CONSTRAINT ETPT_EXTY_FK FOREIGN KEY (EXTY_ID) REFERENCES EXPERIMENT_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE EXPERIMENT_TYPE_PROPERTY_TYPES ADD CONSTRAINT ETPT_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE EXPERIMENT_TYPE_PROPERTY_TYPES ADD CONSTRAINT ETPT_PRTY_FK FOREIGN KEY (PRTY_ID) REFERENCES PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE EXTERNAL_DATA ADD CONSTRAINT EXDA_CVTE_FK FOREIGN KEY (CVTE_ID_STOR_FMT) REFERENCES CONTROLLED_VOCABULARY_TERMS(ID); +ALTER TABLE EXTERNAL_DATA ADD CONSTRAINT EXDA_CVTE_STORED_ON_FK FOREIGN KEY (CVTE_ID_STORE) REFERENCES CONTROLLED_VOCABULARY_TERMS(ID); +ALTER TABLE EXTERNAL_DATA ADD CONSTRAINT EXDA_DATA_FK FOREIGN KEY (ID) REFERENCES DATA_ALL(ID); +ALTER TABLE EXTERNAL_DATA ADD CONSTRAINT EXDA_FFTY_FK FOREIGN KEY (FFTY_ID) REFERENCES FILE_FORMAT_TYPES(ID); +ALTER TABLE EXTERNAL_DATA ADD CONSTRAINT EXDA_LOTY_FK FOREIGN KEY (LOTY_ID) REFERENCES LOCATOR_TYPES(ID); +ALTER TABLE SPACES ADD CONSTRAINT SPACE_PERS_FK_REGISTERER FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DELETIONS ADD CONSTRAINT DEL_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE MATERIALS ADD CONSTRAINT MATE_MATY_FK FOREIGN KEY (MATY_ID) REFERENCES MATERIAL_TYPES(ID); +ALTER TABLE MATERIALS ADD CONSTRAINT MATE_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_CVTE_FK FOREIGN KEY (CVTE_ID) REFERENCES CONTROLLED_VOCABULARY_TERMS(ID); +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_MAPR_FK FOREIGN KEY (MATE_PROP_ID) REFERENCES MATERIALS(ID); +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_MATE_FK FOREIGN KEY (MATE_ID) REFERENCES MATERIALS(ID); +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_MTPT_FK FOREIGN KEY (MTPT_ID) REFERENCES MATERIAL_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE MATERIAL_PROPERTIES_HISTORY ADD CONSTRAINT MAPRH_MATE_FK FOREIGN KEY (MATE_ID) REFERENCES MATERIALS(ID) ON DELETE CASCADE; +ALTER TABLE MATERIAL_PROPERTIES_HISTORY ADD CONSTRAINT MAPRH_MTPT_FK FOREIGN KEY (MTPT_ID) REFERENCES MATERIAL_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE MATERIAL_PROPERTIES_HISTORY ADD CONSTRAINT MAPRH_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE MATERIAL_TYPES ADD CONSTRAINT MATY_SCRIPT_FK FOREIGN KEY (VALIDATION_SCRIPT_ID) REFERENCES SCRIPTS(ID); +ALTER TABLE MATERIAL_TYPE_PROPERTY_TYPES ADD CONSTRAINT MTPT_MATY_FK FOREIGN KEY (MATY_ID) REFERENCES MATERIAL_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE MATERIAL_TYPE_PROPERTY_TYPES ADD CONSTRAINT MTPT_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE MATERIAL_TYPE_PROPERTY_TYPES ADD CONSTRAINT MTPT_PRTY_FK FOREIGN KEY (PRTY_ID) REFERENCES PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE DATA_SET_TYPES ADD CONSTRAINT DSTY_SCRIPT_FK FOREIGN KEY (VALIDATION_SCRIPT_ID) REFERENCES SCRIPTS(ID); +ALTER TABLE PERSONS ADD CONSTRAINT PERS_SPACE_FK FOREIGN KEY (SPACE_ID) REFERENCES SPACES(ID) ON DELETE SET NULL; +ALTER TABLE PERSONS ADD CONSTRAINT PERS_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_SPACE_FK FOREIGN KEY (SPACE_ID, SPACE_FROZEN) REFERENCES SPACES(ID, FROZEN_FOR_PROJ) ON UPDATE CASCADE; +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_PERS_FK_LEADER FOREIGN KEY (PERS_ID_LEADER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_PERS_FK_REGISTERER FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE PROJECTS ADD CONSTRAINT PROJ_PERS_FK_MOD FOREIGN KEY (PERS_ID_MODIFIER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE PROPERTY_TYPES ADD CONSTRAINT PRTY_COVO_FK FOREIGN KEY (COVO_ID) REFERENCES CONTROLLED_VOCABULARIES(ID); +ALTER TABLE PROPERTY_TYPES ADD CONSTRAINT PRTY_DATY_FK FOREIGN KEY (DATY_ID) REFERENCES DATA_TYPES(ID); +ALTER TABLE PROPERTY_TYPES ADD CONSTRAINT PRTY_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE PROPERTY_TYPES ADD CONSTRAINT PRTY_MATY_FK FOREIGN KEY (MATY_PROP_ID) REFERENCES MATERIAL_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE PROPERTY_TYPES ADD CONSTRAINT PRTY_SATY_FK FOREIGN KEY (SATY_PROP_ID) REFERENCES SAMPLE_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE ROLE_ASSIGNMENTS ADD CONSTRAINT ROAS_SPACE_FK FOREIGN KEY (SPACE_ID) REFERENCES SPACES(ID) ON DELETE CASCADE; +ALTER TABLE ROLE_ASSIGNMENTS ADD CONSTRAINT ROAS_PROJECT_FK FOREIGN KEY (PROJECT_ID) REFERENCES PROJECTS(ID) ON DELETE CASCADE; +ALTER TABLE ROLE_ASSIGNMENTS ADD CONSTRAINT ROAS_PERS_FK_GRANTEE FOREIGN KEY (PERS_ID_GRANTEE) REFERENCES PERSONS(ID) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE ROLE_ASSIGNMENTS ADD CONSTRAINT ROAS_AG_FK_GRANTEE FOREIGN KEY (AG_ID_GRANTEE) REFERENCES AUTHORIZATION_GROUPS(ID) ON DELETE CASCADE; +ALTER TABLE ROLE_ASSIGNMENTS ADD CONSTRAINT ROAS_PERS_FK_REGISTERER FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_SPACE_FK FOREIGN KEY (SPACE_ID, SPACE_FROZEN) REFERENCES SPACES(ID, FROZEN_FOR_SAMP) ON UPDATE CASCADE; +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_PROJ_FK FOREIGN KEY (PROJ_ID, PROJ_FROZEN) REFERENCES PROJECTS(ID, FROZEN_FOR_SAMP) ON UPDATE CASCADE; +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_DEL_FK FOREIGN KEY (DEL_ID) REFERENCES DELETIONS(ID); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_SAMP_FK_PART_OF FOREIGN KEY (SAMP_ID_PART_OF, CONT_FROZEN) REFERENCES SAMPLES_ALL(ID, FROZEN_FOR_COMP) ON UPDATE CASCADE; +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_EXPE_FK FOREIGN KEY (EXPE_ID, EXPE_FROZEN) REFERENCES EXPERIMENTS_ALL(ID, FROZEN_FOR_SAMP) ON UPDATE CASCADE; +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_SATY_FK FOREIGN KEY (SATY_ID) REFERENCES SAMPLE_TYPES(ID); +ALTER TABLE SAMPLES_ALL ADD CONSTRAINT SAMP_PERS_FK_MOD FOREIGN KEY (PERS_ID_MODIFIER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_CVTE_FK FOREIGN KEY (CVTE_ID) REFERENCES CONTROLLED_VOCABULARY_TERMS(ID); +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_MAPR_FK FOREIGN KEY (MATE_PROP_ID) REFERENCES MATERIALS(ID); +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_SAMP_FK FOREIGN KEY (SAMP_ID, SAMP_FROZEN) REFERENCES SAMPLES_ALL(ID, FROZEN) ON UPDATE CASCADE; +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_STPT_FK FOREIGN KEY (STPT_ID) REFERENCES SAMPLE_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SAMPLE_PROPERTIES_HISTORY ADD CONSTRAINT SAPRH_SAMP_FK FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES_ALL(ID) ON DELETE CASCADE; +ALTER TABLE SAMPLE_PROPERTIES_HISTORY ADD CONSTRAINT SAPRH_STPT_FK FOREIGN KEY (STPT_ID) REFERENCES SAMPLE_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE SAMPLE_PROPERTIES_HISTORY ADD CONSTRAINT SAPRH_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SAMPLE_TYPES ADD CONSTRAINT SATY_SCRIPT_FK FOREIGN KEY (VALIDATION_SCRIPT_ID) REFERENCES SCRIPTS(ID); +ALTER TABLE SAMPLE_TYPE_PROPERTY_TYPES ADD CONSTRAINT STPT_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SAMPLE_TYPE_PROPERTY_TYPES ADD CONSTRAINT STPT_PRTY_FK FOREIGN KEY (PRTY_ID) REFERENCES PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE SAMPLE_TYPE_PROPERTY_TYPES ADD CONSTRAINT STPT_SATY_FK FOREIGN KEY (SATY_ID) REFERENCES SAMPLE_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE DATA_SET_TYPE_PROPERTY_TYPES ADD CONSTRAINT DSTPT_DSTY_FK FOREIGN KEY (DSTY_ID) REFERENCES DATA_SET_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE DATA_SET_TYPE_PROPERTY_TYPES ADD CONSTRAINT DSTPT_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DATA_SET_TYPE_PROPERTY_TYPES ADD CONSTRAINT DSTPT_PRTY_FK FOREIGN KEY (PRTY_ID) REFERENCES PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_CVTE_FK FOREIGN KEY (CVTE_ID) REFERENCES CONTROLLED_VOCABULARY_TERMS(ID); +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_DSTPT_FK FOREIGN KEY (DSTPT_ID) REFERENCES DATA_SET_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_DS_FK FOREIGN KEY (DS_ID, DASE_FROZEN) REFERENCES DATA_ALL(ID, FROZEN) ON UPDATE CASCADE; +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_MAPR_FK FOREIGN KEY (MATE_PROP_ID) REFERENCES MATERIALS(ID); +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DATA_SET_PROPERTIES_HISTORY ADD CONSTRAINT DSPRH_DSTPT_FK FOREIGN KEY (DSTPT_ID) REFERENCES DATA_SET_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE; +ALTER TABLE DATA_SET_PROPERTIES_HISTORY ADD CONSTRAINT DSPRH_DS_FK FOREIGN KEY (DS_ID) REFERENCES DATA_ALL(ID) ON DELETE CASCADE; +ALTER TABLE DATA_SET_PROPERTIES_HISTORY ADD CONSTRAINT DSPRH_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE AUTHORIZATION_GROUP_PERSONS ADD CONSTRAINT AGP_AG_FK FOREIGN KEY (AG_ID) REFERENCES AUTHORIZATION_GROUPS(ID); +ALTER TABLE AUTHORIZATION_GROUP_PERSONS ADD CONSTRAINT AGP_PERS_FK FOREIGN KEY (PERS_ID) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE AUTHORIZATION_GROUPS ADD CONSTRAINT AG_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE FILTERS ADD CONSTRAINT FILT_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE GRID_CUSTOM_COLUMNS ADD CONSTRAINT GRID_CUSTOM_COLUMNS_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE QUERIES ADD CONSTRAINT QUER_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE SCRIPTS ADD CONSTRAINT SCRI_PERS_FK FOREIGN KEY (PERS_ID_REGISTERER) REFERENCES PERSONS(ID) DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE MATERIAL_TYPE_PROPERTY_TYPES ADD CONSTRAINT MTPT_SCRIPT_FK FOREIGN KEY (SCRIPT_ID) REFERENCES SCRIPTS(ID); +ALTER TABLE SAMPLE_TYPE_PROPERTY_TYPES ADD CONSTRAINT STPT_SCRIPT_FK FOREIGN KEY (SCRIPT_ID) REFERENCES SCRIPTS(ID); +ALTER TABLE EXPERIMENT_TYPE_PROPERTY_TYPES ADD CONSTRAINT ETPT_SCRIPT_FK FOREIGN KEY (SCRIPT_ID) REFERENCES SCRIPTS(ID); +ALTER TABLE DATA_SET_TYPE_PROPERTY_TYPES ADD CONSTRAINT DSTPT_SCRIPT_FK FOREIGN KEY (SCRIPT_ID) REFERENCES SCRIPTS(ID); +ALTER TABLE ONLY POST_REGISTRATION_DATASET_QUEUE ADD CONSTRAINT prdq_ds_fk FOREIGN KEY (ds_id) REFERENCES data_all(id) ON DELETE CASCADE; + +ALTER TABLE EXPERIMENT_RELATIONSHIPS_HISTORY ADD CONSTRAINT EXRELH_MAIN_EXPE_FK FOREIGN KEY (MAIN_EXPE_ID) REFERENCES EXPERIMENTS_ALL(ID) ON DELETE CASCADE; +ALTER TABLE EXPERIMENT_RELATIONSHIPS_HISTORY ADD CONSTRAINT EXRELH_SAMP_FK FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES_ALL(ID) ON DELETE SET NULL; +ALTER TABLE EXPERIMENT_RELATIONSHIPS_HISTORY ADD CONSTRAINT EXRELH_DATA_FK FOREIGN KEY (DATA_ID) REFERENCES DATA_ALL(ID) ON DELETE SET NULL; +ALTER TABLE EXPERIMENT_RELATIONSHIPS_HISTORY ADD CONSTRAINT EXRELH_PROJ_FK FOREIGN KEY (PROJ_ID) REFERENCES PROJECTS(ID) ON DELETE SET NULL; +ALTER TABLE EXPERIMENT_RELATIONSHIPS_HISTORY ADD CONSTRAINT EXRELH_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SAMPLE_RELATIONSHIPS_HISTORY ADD CONSTRAINT SAMPRELH_MAIN_SAMP_FK FOREIGN KEY (MAIN_SAMP_ID) REFERENCES SAMPLES_ALL(ID) ON DELETE CASCADE; +ALTER TABLE SAMPLE_RELATIONSHIPS_HISTORY ADD CONSTRAINT SAMPRELH_EXPE_FK FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS_ALL(ID) ON DELETE SET NULL; +ALTER TABLE SAMPLE_RELATIONSHIPS_HISTORY ADD CONSTRAINT SAMPRELH_SAMP_FK FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES_ALL(ID) ON DELETE SET NULL; +ALTER TABLE SAMPLE_RELATIONSHIPS_HISTORY ADD CONSTRAINT SAMPRELH_DATA_FK FOREIGN KEY (DATA_ID) REFERENCES DATA_ALL(ID) ON DELETE SET NULL; +ALTER TABLE SAMPLE_RELATIONSHIPS_HISTORY ADD CONSTRAINT SAMPRELH_SPACE_FK FOREIGN KEY (SPACE_ID) REFERENCES SPACES(ID) ON DELETE SET NULL; +ALTER TABLE SAMPLE_RELATIONSHIPS_HISTORY ADD CONSTRAINT SAMPRELH_PROJECT_FK FOREIGN KEY (PROJ_ID) REFERENCES PROJECTS(ID) ON DELETE SET NULL; +ALTER TABLE SAMPLE_RELATIONSHIPS_HISTORY ADD CONSTRAINT SAMPRELH_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE DATA_SET_RELATIONSHIPS_HISTORY ADD CONSTRAINT DATARELH_MAIN_DATA_FK FOREIGN KEY (MAIN_DATA_ID) REFERENCES DATA_ALL(ID) ON DELETE CASCADE; +ALTER TABLE DATA_SET_RELATIONSHIPS_HISTORY ADD CONSTRAINT DATARELH_EXPE_FK FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS_ALL(ID) ON DELETE SET NULL; +ALTER TABLE DATA_SET_RELATIONSHIPS_HISTORY ADD CONSTRAINT DATARELH_SAMP_FK FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES_ALL(ID) ON DELETE SET NULL; +ALTER TABLE DATA_SET_RELATIONSHIPS_HISTORY ADD CONSTRAINT DATARELH_DATA_FK FOREIGN KEY (DATA_ID) REFERENCES DATA_ALL(ID) ON DELETE SET NULL; +ALTER TABLE DATA_SET_RELATIONSHIPS_HISTORY ADD CONSTRAINT DATARELH_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE PROJECT_RELATIONSHIPS_HISTORY ADD CONSTRAINT PRRELH_MAIN_PROJ_FK FOREIGN KEY (MAIN_PROJ_ID) REFERENCES PROJECTS(ID) ON DELETE CASCADE; +ALTER TABLE PROJECT_RELATIONSHIPS_HISTORY ADD CONSTRAINT PRRELH_EXPE_FK FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS_ALL(ID) ON DELETE SET NULL; +ALTER TABLE PROJECT_RELATIONSHIPS_HISTORY ADD CONSTRAINT PRRELH_SAMP_FK FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES_ALL(ID) ON DELETE SET NULL; +ALTER TABLE PROJECT_RELATIONSHIPS_HISTORY ADD CONSTRAINT PRRELH_SPACE_FK FOREIGN KEY (SPACE_ID) REFERENCES SPACES(ID) ON DELETE SET NULL; +ALTER TABLE PROJECT_RELATIONSHIPS_HISTORY ADD CONSTRAINT PRRELH_AUTH_FK FOREIGN KEY (PERS_ID_AUTHOR) REFERENCES PERSONS(ID) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE LINK_DATA ADD CONSTRAINT lnda_data_fk FOREIGN KEY (ID, DATA_FROZEN) REFERENCES data_all(ID, FROZEN) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE LINK_DATA ADD CONSTRAINT LINK_DATA_IDFRZ_UK UNIQUE(ID, DATA_FROZEN); + +ALTER TABLE CONTENT_COPIES ADD CONSTRAINT COCO_DATA_FK FOREIGN KEY (DATA_ID, DATA_FROZEN) REFERENCES LINK_DATA(ID, DATA_FROZEN) ON UPDATE CASCADE; +ALTER TABLE CONTENT_COPIES ADD CONSTRAINT COCO_EDMS_FK FOREIGN KEY (EDMS_ID) REFERENCES EXTERNAL_DATA_MANAGEMENT_SYSTEMS(ID); + +ALTER TABLE METAPROJECTS ADD CONSTRAINT METAPROJECTS_OWNER_FK FOREIGN KEY (OWNER) REFERENCES PERSONS(ID) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_MEPR_ID_FK FOREIGN KEY (MEPR_ID) REFERENCES METAPROJECTS(ID) ON DELETE CASCADE; +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_EXPE_ID_FK FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS_ALL(ID) ON DELETE CASCADE; +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_SAMP_ID_FK FOREIGN KEY (SAMP_ID) REFERENCES SAMPLES_ALL(ID) ON DELETE CASCADE; +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_DATA_ID_FK FOREIGN KEY (DATA_ID) REFERENCES DATA_ALL(ID) ON DELETE CASCADE; +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_MATE_ID_FK FOREIGN KEY (MATE_ID) REFERENCES MATERIALS(ID) ON DELETE CASCADE; +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_DEL_ID_FK FOREIGN KEY (DEL_ID) REFERENCES DELETIONS(ID); + +ALTER TABLE OPERATION_EXECUTIONS ADD CONSTRAINT OPERATION_EXECUTIONS_OWNER_FK FOREIGN KEY (OWNER) REFERENCES PERSONS(ID) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE SEMANTIC_ANNOTATIONS ADD CONSTRAINT SEMANTIC_ANNOTATIONS_SATY_ID_FK FOREIGN KEY (SATY_ID) REFERENCES SAMPLE_TYPES(ID) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SEMANTIC_ANNOTATIONS ADD CONSTRAINT SEMANTIC_ANNOTATIONS_STPT_ID_FK FOREIGN KEY (STPT_ID) REFERENCES SAMPLE_TYPE_PROPERTY_TYPES(ID) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE SEMANTIC_ANNOTATIONS ADD CONSTRAINT SEMANTIC_ANNOTATIONS_PRTY_ID_FK FOREIGN KEY (PRTY_ID) REFERENCES PROPERTY_TYPES(ID) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAMPLE_PROPERTIES_UNIQUE_FK FOREIGN KEY (STPT_ID, IS_UNIQUE) REFERENCES SAMPLE_TYPE_PROPERTY_TYPES(ID, IS_UNIQUE); +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPERIMENT_PROPERTIES_UNIQUE_FK FOREIGN KEY (ETPT_ID, IS_UNIQUE) REFERENCES EXPERIMENT_TYPE_PROPERTY_TYPES(ID, IS_UNIQUE); +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DATA_SET_PROPERTIES_UNIQUE_FK FOREIGN KEY (DSTPT_ID, IS_UNIQUE) REFERENCES DATA_SET_TYPE_PROPERTY_TYPES(ID, IS_UNIQUE); +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MATERIAL_PROPERTIES_UNIQUE_FK FOREIGN KEY (MTPT_ID, IS_UNIQUE) REFERENCES MATERIAL_TYPE_PROPERTY_TYPES(ID, IS_UNIQUE); + +-- Creating check constraints + +ALTER TABLE DATA_ALL ADD CONSTRAINT DATA_CK CHECK (EXPE_ID IS NOT NULL OR SAMP_ID IS NOT NULL); +ALTER TABLE EXPERIMENT_PROPERTIES ADD CONSTRAINT EXPR_CK CHECK + ((VALUE IS NOT NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NOT NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NOT NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NOT NULL) + ); +ALTER TABLE EXPERIMENT_PROPERTIES_HISTORY ADD CONSTRAINT EXPRH_CK CHECK + ((VALUE IS NOT NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NOT NULL AND MATERIAL IS NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NOT NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NULL AND SAMPLE IS NOT NULL) + ); + +ALTER TABLE SAMPLE_PROPERTIES ADD CONSTRAINT SAPR_CK CHECK + ((VALUE IS NOT NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NOT NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NOT NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NOT NULL) + ); +ALTER TABLE SAMPLE_PROPERTIES_HISTORY ADD CONSTRAINT SAPRH_CK CHECK + ((VALUE IS NOT NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NOT NULL AND MATERIAL IS NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NOT NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NULL AND SAMPLE IS NOT NULL) + ); +ALTER TABLE MATERIAL_PROPERTIES ADD CONSTRAINT MAPR_CK CHECK + ((VALUE IS NOT NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NOT NULL AND MATE_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NOT NULL) + ); +ALTER TABLE MATERIAL_PROPERTIES_HISTORY ADD CONSTRAINT MAPRH_CK CHECK + ((VALUE IS NOT NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NOT NULL AND MATERIAL IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NOT NULL) + ); +ALTER TABLE DATA_SET_PROPERTIES ADD CONSTRAINT DSPR_CK CHECK + ((VALUE IS NOT NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NOT NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NOT NULL AND SAMP_PROP_ID IS NULL) OR + (VALUE IS NULL AND CVTE_ID IS NULL AND MATE_PROP_ID IS NULL AND SAMP_PROP_ID IS NOT NULL) + ); +ALTER TABLE DATA_SET_PROPERTIES_HISTORY ADD CONSTRAINT DSPRH_CK CHECK + ((VALUE IS NOT NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NOT NULL AND MATERIAL IS NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NOT NULL AND SAMPLE IS NULL) OR + (VALUE IS NULL AND VOCABULARY_TERM IS NULL AND MATERIAL IS NULL AND SAMPLE IS NOT NULL) + ); +ALTER TABLE ATTACHMENTS ADD CONSTRAINT ATTA_ARC_CK CHECK + ((EXPE_ID IS NOT NULL AND PROJ_ID IS NULL AND SAMP_ID IS NULL) OR + (EXPE_ID IS NULL AND PROJ_ID IS NOT NULL AND SAMP_ID IS NULL) OR + (EXPE_ID IS NULL AND PROJ_ID IS NULL AND SAMP_ID IS NOT NULL) + ); +ALTER TABLE events ADD CONSTRAINT evnt_et_enum_ck CHECK + (entity_type IN ('ATTACHMENT', 'DATASET', 'EXPERIMENT', 'SPACE', 'MATERIAL', 'PROJECT', 'PROPERTY_TYPE', 'SAMPLE', 'VOCABULARY', 'AUTHORIZATION_GROUP', 'METAPROJECT')); + +ALTER TABLE EVENTS_SEARCH ADD CONSTRAINT EVENTS_SEARCH_ENTITY_TYPE_CK CHECK + (ENTITY_TYPE IN ('ATTACHMENT', 'DATASET', 'EXPERIMENT', 'SPACE', 'MATERIAL', 'PROJECT', 'PROPERTY_TYPE', 'SAMPLE', 'VOCABULARY', 'AUTHORIZATION_GROUP', 'METAPROJECT')); + +ALTER TABLE controlled_vocabulary_terms ADD CONSTRAINT cvte_ck CHECK (ordinal > 0); + +ALTER TABLE METAPROJECT_ASSIGNMENTS_ALL ADD CONSTRAINT METAPROJECT_ASSIGNMENTS_ALL_CHECK_NN CHECK ( + (EXPE_ID IS NOT NULL AND SAMP_ID IS NULL AND DATA_ID IS NULL AND MATE_ID IS NULL) OR + (EXPE_ID IS NULL AND SAMP_ID IS NOT NULL AND DATA_ID IS NULL AND MATE_ID IS NULL) OR + (EXPE_ID IS NULL AND SAMP_ID IS NULL AND DATA_ID IS NOT NULL AND MATE_ID IS NULL) OR + (EXPE_ID IS NULL AND SAMP_ID IS NULL AND DATA_ID IS NULL AND MATE_ID IS NOT NULL)); + +ALTER TABLE SCRIPTS ADD CONSTRAINT SCRIPT_NN_CK CHECK + (PLUGIN_TYPE = 'PREDEPLOYED' OR SCRIPT IS NOT NULL); + +ALTER TABLE OPERATION_EXECUTIONS ADD CONSTRAINT OPERATION_EXECUTIONS_STATE_START_DATE_CHECK CHECK ( + (STATE IN ('NEW','SCHEDULED') AND START_DATE IS NULL) OR + (STATE IN ('RUNNING','FINISHED','FAILED') AND START_DATE IS NOT NULL) +); + +ALTER TABLE OPERATION_EXECUTIONS ADD CONSTRAINT OPERATION_EXECUTIONS_STATE_FINISH_DATE_CHECK CHECK ( + (STATE IN ('NEW','SCHEDULED','RUNNING') AND FINISH_DATE IS NULL) OR + (STATE IN ('FINISHED','FAILED') AND FINISH_DATE IS NOT NULL) +); + +ALTER TABLE SEMANTIC_ANNOTATIONS ADD CONSTRAINT SEMANTIC_ANNOTATIONS_SSP_CK CHECK + ((SATY_ID IS NOT NULL AND STPT_ID IS NULL AND PRTY_ID IS NULL) OR + (SATY_ID IS NULL AND STPT_ID IS NOT NULL AND PRTY_ID IS NULL) OR + (SATY_ID IS NULL AND STPT_ID IS NULL AND PRTY_ID IS NOT NULL) + ); + +-- Creating indices + +CREATE INDEX COVO_PERS_FK_I ON CONTROLLED_VOCABULARIES (PERS_ID_REGISTERER); +CREATE INDEX CVTE_COVO_FK_I ON CONTROLLED_VOCABULARY_TERMS (COVO_ID); +CREATE INDEX CVTE_PERS_FK_I ON CONTROLLED_VOCABULARY_TERMS (PERS_ID_REGISTERER); +CREATE INDEX DATA_IDFRZ_PK_I ON DATA_ALL (id, frozen); +CREATE INDEX DATA_IDFRZ_CH_PK_I ON DATA_ALL (id, frozen_for_children); +CREATE INDEX DATA_IDFRZ_P_PK_I ON DATA_ALL (id, frozen_for_parents); +CREATE INDEX DATA_IDFRZ_COMP_PK_I ON DATA_ALL (id, frozen_for_comps); +CREATE INDEX DATA_IDFRZ_CONT_PK_I ON DATA_ALL (id, frozen_for_conts); +CREATE INDEX DATA_DSTY_FK_I ON DATA_ALL (DSTY_ID); +CREATE INDEX DATA_SAMP_FK_I ON DATA_ALL (SAMP_ID); +CREATE INDEX DATA_EXPE_FK_I ON DATA_ALL (EXPE_ID); +CREATE INDEX DATA_DEL_FK_I ON DATA_ALL (DEL_ID); +CREATE INDEX DATA_ACCT_I ON DATA_ALL (ACCESS_TIMESTAMP); +CREATE INDEX LINK_DATA_IDFRZ_PK_I ON LINK_DATA (ID, DATA_FROZEN); +CREATE INDEX DSRE_DATA_FK_I_CHILD ON DATA_SET_RELATIONSHIPS_ALL (DATA_ID_CHILD); +CREATE INDEX DSRE_DATA_FK_I_PARENT ON DATA_SET_RELATIONSHIPS_ALL (DATA_ID_PARENT); +CREATE INDEX DSRE_DEL_FK_I ON DATA_SET_RELATIONSHIPS_ALL (DEL_ID); +CREATE INDEX sare_data_fk_i_child ON sample_relationships_all (sample_id_child); +CREATE INDEX sare_data_fk_i_parent ON sample_relationships_all (sample_id_parent); +CREATE INDEX sare_data_fk_i_relationship ON sample_relationships_all (relationship_id); +CREATE INDEX sare_del_fk_i ON sample_relationships_all (del_id); +CREATE INDEX DSSE_DS_FK_I ON DATA_STORE_SERVICES (DATA_STORE_ID); +CREATE INDEX DSSDST_DS_FK_I ON DATA_STORE_SERVICE_DATA_SET_TYPES (DATA_STORE_SERVICE_ID); +CREATE INDEX DSSDST_DST_FK_I ON DATA_STORE_SERVICE_DATA_SET_TYPES (DATA_SET_TYPE_ID); +CREATE INDEX ETPT_EXTY_FK_I ON EXPERIMENT_TYPE_PROPERTY_TYPES (EXTY_ID); +CREATE INDEX ETPT_PERS_FK_I ON EXPERIMENT_TYPE_PROPERTY_TYPES (PERS_ID_REGISTERER); +CREATE INDEX ETPT_PRTY_FK_I ON EXPERIMENT_TYPE_PROPERTY_TYPES (PRTY_ID); +CREATE INDEX EVNT_PERS_FK_I ON EVENTS (PERS_ID_REGISTERER); +CREATE INDEX EVNT_FR_ID_FK_I ON EVENTS (EVENT_TYPE, IDENTIFIERS) WHERE EVENT_TYPE = 'FREEZING'; +CREATE INDEX EVNT_EXAC_FK_I ON EVENTS (EXAC_ID); +CREATE INDEX EVENTS_SEARCH_ENTITY_SPACE_I ON EVENTS_SEARCH (ENTITY_SPACE); +CREATE INDEX EVENTS_SEARCH_ENTITY_SPACE_PERM_ID_I ON EVENTS_SEARCH (ENTITY_SPACE_PERM_ID); +CREATE INDEX EVENTS_SEARCH_ENTITY_PROJECT_I ON EVENTS_SEARCH (ENTITY_PROJECT); +CREATE INDEX EVENTS_SEARCH_ENTITY_PROJECT_PERM_ID_I ON EVENTS_SEARCH (ENTITY_PROJECT_PERM_ID); +CREATE INDEX EVENTS_SEARCH_ENTITY_REGISTERER_I ON EVENTS_SEARCH (ENTITY_REGISTERER); +CREATE INDEX EVENTS_SEARCH_ENTITY_REGISTRATION_TIMESTAMP_I ON EVENTS_SEARCH (ENTITY_REGISTRATION_TIMESTAMP); +CREATE INDEX EVENTS_SEARCH_PERS_ID_REGISTERER_I ON EVENTS_SEARCH (PERS_ID_REGISTERER); +CREATE INDEX EVENTS_SEARCH_REGISTRATION_TIMESTAMP_I ON EVENTS_SEARCH (REGISTRATION_TIMESTAMP); +CREATE INDEX EVENTS_SEARCH_EXAC_ID_I ON EVENTS_SEARCH (EXAC_ID); +CREATE INDEX ATTA_EXPE_FK_I ON ATTACHMENTS (EXPE_ID); +CREATE INDEX ATTA_SAMP_FK_I ON ATTACHMENTS (SAMP_ID); +CREATE INDEX ATTA_PROJ_FK_I ON ATTACHMENTS (PROJ_ID); +CREATE INDEX ATTA_PERS_FK_I ON ATTACHMENTS (PERS_ID_REGISTERER); +CREATE INDEX ATTA_EXAC_FK_I ON ATTACHMENTS (EXAC_ID); +CREATE INDEX EXDA_CVTE_FK_I ON EXTERNAL_DATA (CVTE_ID_STOR_FMT); +CREATE INDEX EXDA_CVTE_STORED_ON_FK_I ON EXTERNAL_DATA (CVTE_ID_STORE); +CREATE INDEX EXDA_FFTY_FK_I ON EXTERNAL_DATA (FFTY_ID); +CREATE INDEX EXDA_LOTY_FK_I ON EXTERNAL_DATA (LOTY_ID); +CREATE INDEX EXPE_IDFRZ_PK_I ON EXPERIMENTS_ALL (id, frozen); +CREATE INDEX EXPE_IDFRZ_S_PK_I ON EXPERIMENTS_ALL (id, frozen_for_samp); +CREATE INDEX EXPE_IDFRZ_D_PK_I ON EXPERIMENTS_ALL (id, frozen_for_data); +CREATE INDEX EXPE_EXTY_FK_I ON EXPERIMENTS_ALL (EXTY_ID); +CREATE INDEX EXPE_DEL_FK_I ON EXPERIMENTS_ALL (DEL_ID); +CREATE INDEX EXPE_PERS_FK_I ON EXPERIMENTS_ALL (PERS_ID_REGISTERER); +CREATE INDEX EXPE_PROJ_FK_I ON EXPERIMENTS_ALL (PROJ_ID); +CREATE INDEX EXPR_CVTE_FK_I ON EXPERIMENT_PROPERTIES (CVTE_ID); +CREATE INDEX EXPR_ETPT_FK_I ON EXPERIMENT_PROPERTIES (ETPT_ID); +CREATE INDEX EXPR_EXPE_FK_I ON EXPERIMENT_PROPERTIES (EXPE_ID); +CREATE INDEX EXPR_PERS_FK_I ON EXPERIMENT_PROPERTIES (PERS_ID_REGISTERER); +CREATE INDEX EXPR_MAPR_FK_I ON EXPERIMENT_PROPERTIES (MATE_PROP_ID); +CREATE INDEX EXPR_SAPR_FK_I ON EXPERIMENT_PROPERTIES (SAMP_PROP_ID); +CREATE INDEX EXPRH_ETPT_FK_I ON EXPERIMENT_PROPERTIES_HISTORY (ETPT_ID); +CREATE INDEX EXPRH_EXPE_FK_I ON EXPERIMENT_PROPERTIES_HISTORY (EXPE_ID); +CREATE INDEX EXPRH_VUTS_FK_I ON EXPERIMENT_PROPERTIES_HISTORY (VALID_UNTIL_TIMESTAMP); +CREATE INDEX SPACE_PERS_REGISTERED_BY_FK_I ON SPACES (PERS_ID_REGISTERER); +CREATE INDEX DEL_PERS_FK_I ON DELETIONS (PERS_ID_REGISTERER); +CREATE INDEX MAPR_CVTE_FK_I ON MATERIAL_PROPERTIES (CVTE_ID); +CREATE INDEX MAPR_MATE_FK_I ON MATERIAL_PROPERTIES (MATE_ID); +CREATE INDEX MAPR_MTPT_FK_I ON MATERIAL_PROPERTIES (MTPT_ID); +CREATE INDEX MAPR_PERS_FK_I ON MATERIAL_PROPERTIES (PERS_ID_REGISTERER); +CREATE INDEX MAPR_MAPR_FK_I ON MATERIAL_PROPERTIES (MATE_PROP_ID); +CREATE INDEX MAPRH_ETPT_FK_I ON MATERIAL_PROPERTIES_HISTORY (MTPT_ID); +CREATE INDEX MAPRH_EXPE_FK_I ON MATERIAL_PROPERTIES_HISTORY (MATE_ID); +CREATE INDEX MAPRH_VUTS_FK_I ON MATERIAL_PROPERTIES_HISTORY (VALID_UNTIL_TIMESTAMP); +CREATE INDEX MATE_MATY_FK_I ON MATERIALS (MATY_ID); +CREATE INDEX MATE_PERS_FK_I ON MATERIALS (PERS_ID_REGISTERER); +CREATE INDEX MTPT_MATY_FK_I ON MATERIAL_TYPE_PROPERTY_TYPES (MATY_ID); +CREATE INDEX MTPT_PERS_FK_I ON MATERIAL_TYPE_PROPERTY_TYPES (PERS_ID_REGISTERER); +CREATE INDEX MTPT_PRTY_FK_I ON MATERIAL_TYPE_PROPERTY_TYPES (PRTY_ID); +CREATE INDEX PERS_SPACE_FK_I ON PERSONS (SPACE_ID); +CREATE INDEX PERS_IS_ACTIVE_I ON PERSONS (IS_ACTIVE); +CREATE INDEX PROJ_IDFRZ_PK_I ON PROJECTS (ID, FROZEN); +CREATE INDEX PROJ_IDFRZ_E_PK_I ON PROJECTS (ID, FROZEN_FOR_EXP); +CREATE INDEX PROJ_IDFRZ_S_PK_I ON PROJECTS (ID, FROZEN_FOR_SAMP); +CREATE INDEX PROJ_SPACE_FK_I ON PROJECTS (SPACE_ID); +CREATE INDEX PROJ_PERS_FK_I_LEADER ON PROJECTS (PERS_ID_LEADER); +CREATE INDEX PROJ_PERS_FK_I_REGISTERER ON PROJECTS (PERS_ID_REGISTERER); +CREATE INDEX PRTY_COVO_FK_I ON PROPERTY_TYPES (COVO_ID); +CREATE INDEX PRTY_DATY_FK_I ON PROPERTY_TYPES (DATY_ID); +CREATE INDEX PRTY_PERS_FK_I ON PROPERTY_TYPES (PERS_ID_REGISTERER); +CREATE INDEX ROAS_SPACE_FK_I ON ROLE_ASSIGNMENTS (SPACE_ID); +CREATE INDEX ROAS_PROJECT_FK_I ON ROLE_ASSIGNMENTS (PROJECT_ID); +CREATE INDEX ROAS_PERS_FK_I_GRANTEE ON ROLE_ASSIGNMENTS (PERS_ID_GRANTEE); +CREATE INDEX ROAS_AG_FK_I_GRANTEE ON ROLE_ASSIGNMENTS (AG_ID_GRANTEE); +CREATE INDEX ROAS_PERS_FK_I_REGISTERER ON ROLE_ASSIGNMENTS (PERS_ID_REGISTERER); +CREATE INDEX SPACE_IDFRZ_PK_I ON SPACES (id, frozen); +CREATE INDEX SPACE_IDFRZ_P_PK_I ON SPACES (id, frozen_for_proj); +CREATE INDEX SPACE_IDFRZ_S_PK_I ON SPACES (id, frozen_for_samp); +CREATE INDEX SAMP_IDFRZ_PK_I ON SAMPLES_ALL (id, frozen); +CREATE INDEX SAMP_IDFRZ_C_PK_I ON SAMPLES_ALL (id, frozen_for_comp); +CREATE INDEX SAMP_IDFRZ_CH_PK_I ON SAMPLES_ALL (id, frozen_for_children); +CREATE INDEX SAMP_IDFRZ_P_PK_I ON SAMPLES_ALL (id, frozen_for_parents); +CREATE INDEX SAMP_IDFRZ_D_PK_I ON SAMPLES_ALL (id, frozen_for_data); +CREATE INDEX SAMP_DEL_FK_I ON SAMPLES_ALL (DEL_ID); +CREATE INDEX SAMP_PERS_FK_I ON SAMPLES_ALL (PERS_ID_REGISTERER); +CREATE INDEX SAMP_SAMP_FK_I_PART_OF ON SAMPLES_ALL (SAMP_ID_PART_OF); +CREATE INDEX SAMP_EXPE_FK_I ON SAMPLES_ALL (EXPE_ID); +CREATE INDEX SAMP_PROJ_FK_I ON SAMPLES_ALL (PROJ_ID); +CREATE INDEX SAMP_CODE_I ON SAMPLES_ALL (CODE); +CREATE INDEX SAMP_IDENTIFIER_I ON SAMPLES_ALL (SAMPLE_IDENTIFIER); +CREATE INDEX SAMP_SATY_FK_I ON SAMPLES_ALL (SATY_ID); +CREATE INDEX SAPR_CVTE_FK_I ON SAMPLE_PROPERTIES (CVTE_ID); +CREATE INDEX SAPR_PERS_FK_I ON SAMPLE_PROPERTIES (PERS_ID_REGISTERER); +CREATE INDEX SAPR_SAMP_FK_I ON SAMPLE_PROPERTIES (SAMP_ID); +CREATE INDEX SAPR_STPT_FK_I ON SAMPLE_PROPERTIES (STPT_ID); +CREATE INDEX SAPR_MAPR_FK_I ON SAMPLE_PROPERTIES (MATE_PROP_ID); +CREATE INDEX SAPR_SAPR_FK_I ON SAMPLE_PROPERTIES (SAMP_PROP_ID); +CREATE INDEX SAPRH_ETPT_FK_I ON SAMPLE_PROPERTIES_HISTORY (STPT_ID); +CREATE INDEX SAPRH_EXPE_FK_I ON SAMPLE_PROPERTIES_HISTORY (SAMP_ID); +CREATE INDEX SAPRH_VUTS_FK_I ON SAMPLE_PROPERTIES_HISTORY (VALID_UNTIL_TIMESTAMP); +CREATE INDEX STPT_PERS_FK_I ON SAMPLE_TYPE_PROPERTY_TYPES (PERS_ID_REGISTERER); +CREATE INDEX STPT_PRTY_FK_I ON SAMPLE_TYPE_PROPERTY_TYPES (PRTY_ID); +CREATE INDEX STPT_SATY_FK_I ON SAMPLE_TYPE_PROPERTY_TYPES (SATY_ID); +CREATE INDEX DSPR_CVTE_FK_I ON DATA_SET_PROPERTIES (CVTE_ID); +CREATE INDEX DSPR_DSTPT_FK_I ON DATA_SET_PROPERTIES (DSTPT_ID); +CREATE INDEX DSPR_DS_FK_I ON DATA_SET_PROPERTIES (DS_ID); +CREATE INDEX DSPR_PERS_FK_I ON DATA_SET_PROPERTIES (PERS_ID_REGISTERER); +CREATE INDEX DSPR_MAPR_FK_I ON DATA_SET_PROPERTIES (MATE_PROP_ID); +CREATE INDEX DSPR_SAPR_FK_I ON DATA_SET_PROPERTIES (SAMP_PROP_ID); +CREATE INDEX DSPRH_ETPT_FK_I ON DATA_SET_PROPERTIES_HISTORY (DSTPT_ID); +CREATE INDEX DSPRH_EXPE_FK_I ON DATA_SET_PROPERTIES_HISTORY (DS_ID); +CREATE INDEX DSPRH_VUTS_FK_I ON DATA_SET_PROPERTIES_HISTORY (VALID_UNTIL_TIMESTAMP); +CREATE INDEX DSTPT_DSTY_FK_I ON DATA_SET_TYPE_PROPERTY_TYPES (DSTY_ID); +CREATE INDEX DSTPT_PERS_FK_I ON DATA_SET_TYPE_PROPERTY_TYPES (PERS_ID_REGISTERER); +CREATE INDEX DSTPT_PRTY_FK_I ON DATA_SET_TYPE_PROPERTY_TYPES (PRTY_ID); +CREATE INDEX FILT_PERS_FK_I ON FILTERS (PERS_ID_REGISTERER); +CREATE INDEX GRID_CUSTOM_COLUMNS_PERS_FK_I ON GRID_CUSTOM_COLUMNS (PERS_ID_REGISTERER); +CREATE INDEX SCRIPT_PERS_FK_I ON SCRIPTS (PERS_ID_REGISTERER); +CREATE INDEX ENTITY_OPERATIONS_LOG_RID_I ON ENTITY_OPERATIONS_LOG(REGISTRATION_ID); +CREATE INDEX EXRELH_MAIN_EXPE_FK_I ON EXPERIMENT_RELATIONSHIPS_HISTORY (MAIN_EXPE_ID); +CREATE INDEX EXRELH_MAIN_EXPE_FK_SAMP_FK_I ON EXPERIMENT_RELATIONSHIPS_HISTORY (MAIN_EXPE_ID, SAMP_ID); +CREATE INDEX EXRELH_MAIN_EXPE_FK_DATA_FK_I ON EXPERIMENT_RELATIONSHIPS_HISTORY (MAIN_EXPE_ID, DATA_ID); +CREATE INDEX EXRELH_MAIN_EXPE_FK_PROJ_FK_I ON EXPERIMENT_RELATIONSHIPS_HISTORY (MAIN_EXPE_ID, PROJ_ID); +CREATE INDEX EXRELH_SAMP_ID_FK_I ON EXPERIMENT_RELATIONSHIPS_HISTORY (SAMP_ID); +CREATE INDEX EXRELH_DATA_ID_FK_I ON EXPERIMENT_RELATIONSHIPS_HISTORY (DATA_ID); +CREATE INDEX SAMPRELH_MAIN_SAMP_FK_I ON SAMPLE_RELATIONSHIPS_HISTORY (MAIN_SAMP_ID); +CREATE INDEX SAMPRELH_MAIN_SAMP_FK_EXPE_FK_I ON SAMPLE_RELATIONSHIPS_HISTORY (MAIN_SAMP_ID, EXPE_ID); +CREATE INDEX SAMPRELH_MAIN_SAMP_FK_SAMP_FK_I ON SAMPLE_RELATIONSHIPS_HISTORY (MAIN_SAMP_ID, SAMP_ID); +CREATE INDEX SAMPRELH_MAIN_SAMP_FK_DATA_FK_I ON SAMPLE_RELATIONSHIPS_HISTORY (MAIN_SAMP_ID, DATA_ID); +CREATE INDEX SAMPRELH_MAIN_SAMP_FK_SPACE_FK_I ON SAMPLE_RELATIONSHIPS_HISTORY (MAIN_SAMP_ID, SPACE_ID); +CREATE INDEX SAMPRELH_MAIN_SAMP_FK_PROJ_FK_I ON SAMPLE_RELATIONSHIPS_HISTORY (MAIN_SAMP_ID, PROJ_ID); +CREATE INDEX SAMPRELH_SAMP_ID_FK_I ON SAMPLE_RELATIONSHIPS_HISTORY (SAMP_ID); +CREATE INDEX SAMPRELH_DATA_ID_FK_I ON SAMPLE_RELATIONSHIPS_HISTORY (DATA_ID); +CREATE INDEX DATARELH_MAIN_DATA_FK_I ON DATA_SET_RELATIONSHIPS_HISTORY (MAIN_DATA_ID); +CREATE INDEX DATARELH_MAIN_DATA_FK_EXPE_FK_I ON DATA_SET_RELATIONSHIPS_HISTORY (MAIN_DATA_ID, EXPE_ID); +CREATE INDEX DATARELH_MAIN_DATA_FK_SAMP_FK_I ON DATA_SET_RELATIONSHIPS_HISTORY (MAIN_DATA_ID, SAMP_ID); +CREATE INDEX DATARELH_MAIN_DATA_FK_DATA_FK_I ON DATA_SET_RELATIONSHIPS_HISTORY (MAIN_DATA_ID, DATA_ID); +CREATE INDEX DATARELH_DATA_FK_I ON DATA_SET_RELATIONSHIPS_HISTORY (DATA_ID); +CREATE INDEX PRRELH_MAIN_PROJ_FK_I ON PROJECT_RELATIONSHIPS_HISTORY (MAIN_PROJ_ID); +CREATE INDEX PRRELH_MAIN_PROJ_FK_EXPE_FK_I ON PROJECT_RELATIONSHIPS_HISTORY (MAIN_PROJ_ID, EXPE_ID); +CREATE INDEX PRRELH_MAIN_PROJ_FK_SAMP_FK_I ON PROJECT_RELATIONSHIPS_HISTORY (MAIN_PROJ_ID, SAMP_ID); +CREATE INDEX PRRELH_MAIN_PROJ_FK_SPACE_FK_I ON PROJECT_RELATIONSHIPS_HISTORY (MAIN_PROJ_ID, SPACE_ID); +CREATE INDEX METAPROJECTS_OWNER_FK_I ON METAPROJECTS (OWNER); +CREATE INDEX METAPROJECTS_NAME_I ON METAPROJECTS (NAME); +CREATE UNIQUE INDEX METAPROJECTS_NAME_OWNER_UK ON METAPROJECTS (lower(NAME), OWNER); +CREATE INDEX METAPROJECT_ASSIGNMENTS_ALL_MEPR_FK_I ON METAPROJECT_ASSIGNMENTS_ALL (MEPR_ID); +CREATE INDEX METAPROJECT_ASSIGNMENTS_ALL_EXPE_FK_I ON METAPROJECT_ASSIGNMENTS_ALL (EXPE_ID); +CREATE INDEX METAPROJECT_ASSIGNMENTS_ALL_SAMP_FK_I ON METAPROJECT_ASSIGNMENTS_ALL (SAMP_ID); +CREATE INDEX METAPROJECT_ASSIGNMENTS_ALL_DATA_FK_I ON METAPROJECT_ASSIGNMENTS_ALL (DATA_ID); +CREATE INDEX METAPROJECT_ASSIGNMENTS_ALL_MATE_FK_I ON METAPROJECT_ASSIGNMENTS_ALL (MATE_ID); +CREATE INDEX METAPROJECT_ASSIGNMENTS_ALL_DEL_FK_I ON METAPROJECT_ASSIGNMENTS_ALL (DEL_ID); +CREATE INDEX OPERATION_EXECUTIONS_CODE_I ON OPERATION_EXECUTIONS (CODE); +CREATE INDEX OPERATION_EXECUTIONS_OWNER_I ON OPERATION_EXECUTIONS (OWNER); +CREATE INDEX OPERATION_EXECUTIONS_AVAILABILITY_I ON OPERATION_EXECUTIONS (AVAILABILITY); +CREATE INDEX OPERATION_EXECUTIONS_SUMMARY_AVAILABILITY_I ON OPERATION_EXECUTIONS (SUMMARY_AVAILABILITY); +CREATE INDEX OPERATION_EXECUTIONS_DETAILS_AVAILABILITY_I ON OPERATION_EXECUTIONS (DETAILS_AVAILABILITY); +CREATE INDEX SEMANTIC_ANNOTATIONS_SATY_ID_I ON SEMANTIC_ANNOTATIONS (SATY_ID); +CREATE INDEX SEMANTIC_ANNOTATIONS_STPT_ID_I ON SEMANTIC_ANNOTATIONS (STPT_ID); +CREATE INDEX SEMANTIC_ANNOTATIONS_PRTY_ID_I ON SEMANTIC_ANNOTATIONS (PRTY_ID); + +CREATE INDEX sample_properties_search_index ON sample_properties USING gin(tsvector_document); +CREATE INDEX experiment_properties_search_index ON experiment_properties USING gin(tsvector_document); +CREATE INDEX data_set_properties_search_index ON data_set_properties USING gin(tsvector_document); +CREATE INDEX material_properties_search_index ON material_properties USING gin(tsvector_document); + +CREATE UNIQUE INDEX SAMPLE_PROPERTIES_UNIQUE_VALUE ON SAMPLE_PROPERTIES (STPT_ID, VALUE) WHERE IS_UNIQUE AND VALUE IS NOT NULL; +CREATE UNIQUE INDEX SAMPLE_PROPERTIES_UNIQUE_CVTE ON SAMPLE_PROPERTIES (STPT_ID, CVTE_ID) WHERE IS_UNIQUE AND CVTE_ID IS NOT NULL; +CREATE UNIQUE INDEX SAMPLE_PROPERTIES_UNIQUE_MATE ON SAMPLE_PROPERTIES (STPT_ID, MATE_PROP_ID) WHERE IS_UNIQUE AND MATE_PROP_ID IS NOT NULL; +CREATE UNIQUE INDEX SAMPLE_PROPERTIES_UNIQUE_SAMP ON SAMPLE_PROPERTIES (STPT_ID, SAMP_PROP_ID) WHERE IS_UNIQUE AND SAMP_PROP_ID IS NOT NULL; + +CREATE UNIQUE INDEX EXPERIMENT_PROPERTIES_UNIQUE_VALUE ON EXPERIMENT_PROPERTIES (ETPT_ID, VALUE) WHERE IS_UNIQUE AND VALUE IS NOT NULL; +CREATE UNIQUE INDEX EXPERIMENT_PROPERTIES_UNIQUE_CVTE ON EXPERIMENT_PROPERTIES (ETPT_ID, CVTE_ID) WHERE IS_UNIQUE AND CVTE_ID IS NOT NULL; +CREATE UNIQUE INDEX EXPERIMENT_PROPERTIES_UNIQUE_MATE ON EXPERIMENT_PROPERTIES (ETPT_ID, MATE_PROP_ID) WHERE IS_UNIQUE AND MATE_PROP_ID IS NOT NULL; +CREATE UNIQUE INDEX EXPERIMENT_PROPERTIES_UNIQUE_SAMP ON EXPERIMENT_PROPERTIES (ETPT_ID, SAMP_PROP_ID) WHERE IS_UNIQUE AND SAMP_PROP_ID IS NOT NULL; + +CREATE UNIQUE INDEX DATA_SET_PROPERTIES_UNIQUE_VALUE ON DATA_SET_PROPERTIES (DSTPT_ID, VALUE) WHERE IS_UNIQUE AND VALUE IS NOT NULL; +CREATE UNIQUE INDEX DATA_SET_PROPERTIES_UNIQUE_CVTE ON DATA_SET_PROPERTIES (DSTPT_ID, CVTE_ID) WHERE IS_UNIQUE AND CVTE_ID IS NOT NULL; +CREATE UNIQUE INDEX DATA_SET_PROPERTIES_UNIQUE_MATE ON DATA_SET_PROPERTIES (DSTPT_ID, MATE_PROP_ID) WHERE IS_UNIQUE AND MATE_PROP_ID IS NOT NULL; +CREATE UNIQUE INDEX DATA_SET_PROPERTIES_UNIQUE_SAMP ON DATA_SET_PROPERTIES (DSTPT_ID, SAMP_PROP_ID) WHERE IS_UNIQUE AND SAMP_PROP_ID IS NOT NULL; + +CREATE UNIQUE INDEX MATERIAL_PROPERTIES_UNIQUE_VALUE ON MATERIAL_PROPERTIES (MTPT_ID, VALUE) WHERE IS_UNIQUE AND VALUE IS NOT NULL; +CREATE UNIQUE INDEX MATERIAL_PROPERTIES_UNIQUE_CVTE ON MATERIAL_PROPERTIES (MTPT_ID, CVTE_ID) WHERE IS_UNIQUE AND CVTE_ID IS NOT NULL; +CREATE UNIQUE INDEX MATERIAL_PROPERTIES_UNIQUE_MATE ON MATERIAL_PROPERTIES (MTPT_ID, MATE_PROP_ID) WHERE IS_UNIQUE AND MATE_PROP_ID IS NOT NULL; + +ALTER TABLE ROLE_ASSIGNMENTS ADD CONSTRAINT ROAS_AG_PERS_ARC_CK CHECK ((AG_ID_GRANTEE IS NOT NULL AND PERS_ID_GRANTEE IS NULL) OR (AG_ID_GRANTEE IS NULL AND PERS_ID_GRANTEE IS NOT NULL)); +ALTER TABLE ROLE_ASSIGNMENTS ADD CONSTRAINT ROAS_SPACE_PROJECT_CK CHECK (SPACE_ID IS NULL OR PROJECT_ID IS NULL); +ALTER TABLE MATERIAL_TYPES ADD CONSTRAINT MATY_BK_UK UNIQUE(CODE); +ALTER TABLE EXPERIMENT_TYPES ADD CONSTRAINT EXTY_BK_UK UNIQUE(CODE); +ALTER TABLE SAMPLE_TYPES ADD CONSTRAINT SATY_BK_UK UNIQUE(CODE); +ALTER TABLE DATA_SET_TYPES ADD CONSTRAINT DSTY_BK_UK UNIQUE(CODE); +ALTER TABLE SPACES ADD CONSTRAINT SPACE_BK_UK UNIQUE(CODE); diff --git a/openbis/source/sql/postgresql/189/domains-189.sql b/openbis/source/sql/postgresql/189/domains-189.sql new file mode 100644 index 0000000000000000000000000000000000000000..33171dfc76028a38bd0762a157ebf1e5ae3e58b1 --- /dev/null +++ b/openbis/source/sql/postgresql/189/domains-189.sql @@ -0,0 +1,36 @@ +-- Creating domains + +CREATE DOMAIN AUTHORIZATION_ROLE AS VARCHAR(40) CHECK (VALUE IN ('ADMIN', 'POWER_USER', 'USER', 'OBSERVER', 'ETL_SERVER')); +CREATE DOMAIN BOOLEAN_CHAR AS BOOLEAN DEFAULT FALSE; +CREATE DOMAIN BOOLEAN_CHAR_OR_UNKNOWN AS CHAR(1) DEFAULT 'U' CHECK (VALUE IN ('F', 'T', 'U')); +CREATE DOMAIN CODE AS VARCHAR(100); +CREATE DOMAIN SAMPLE_IDENTIFIER AS VARCHAR(404); -- /CODE/CODE/CODE:CODE +CREATE DOMAIN COLUMN_LABEL AS VARCHAR(128); +CREATE DOMAIN DATA_STORE_SERVICE_KIND AS VARCHAR(40) CHECK (VALUE IN ('PROCESSING', 'QUERIES')); +CREATE DOMAIN DATA_STORE_SERVICE_REPORTING_PLUGIN_TYPE AS VARCHAR(40) CHECK (VALUE IN ('TABLE_MODEL', 'DSS_LINK', 'AGGREGATION_TABLE_MODEL')); +CREATE DOMAIN EVENT_TYPE AS VARCHAR(40) CHECK (VALUE IN ('DELETION', 'MOVEMENT', 'FREEZING')); +CREATE DOMAIN FILE AS BYTEA; +CREATE DOMAIN FILE_NAME AS VARCHAR(255); +CREATE DOMAIN TEXT_VALUE AS TEXT; +CREATE DOMAIN OBJECT_NAME AS VARCHAR(50); +CREATE DOMAIN REAL_VALUE AS REAL; +CREATE DOMAIN TECH_ID AS BIGINT; +CREATE DOMAIN TIME_STAMP AS TIMESTAMP WITH TIME ZONE; +CREATE DOMAIN TIME_STAMP_DFL AS TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP; +CREATE DOMAIN USER_ID AS VARCHAR(50); +CREATE DOMAIN TITLE_100 AS VARCHAR(100); +CREATE DOMAIN GRID_EXPRESSION AS VARCHAR(2000); +CREATE DOMAIN GRID_ID AS VARCHAR(200); +CREATE DOMAIN ORDINAL_INT AS BIGINT CHECK (VALUE > 0); +CREATE DOMAIN DESCRIPTION_2000 AS VARCHAR(2000); +CREATE DOMAIN ARCHIVING_STATUS AS VARCHAR(100) CHECK (VALUE IN ('LOCKED', 'AVAILABLE', 'ARCHIVED', 'ARCHIVE_PENDING', 'UNARCHIVE_PENDING', 'BACKUP_PENDING')); +CREATE DOMAIN QUERY_TYPE AS VARCHAR(40) CHECK (VALUE IN ('GENERIC', 'EXPERIMENT', 'SAMPLE', 'DATA_SET', 'MATERIAL')); +CREATE DOMAIN ENTITY_KIND AS VARCHAR(40) CHECK (VALUE IN ('SAMPLE', 'EXPERIMENT', 'DATA_SET', 'MATERIAL')); +CREATE DOMAIN SCRIPT_TYPE AS VARCHAR(40) CHECK (VALUE IN ('DYNAMIC_PROPERTY', 'MANAGED_PROPERTY', 'ENTITY_VALIDATION')); +CREATE DOMAIN IDENTIFIER AS VARCHAR(200); +CREATE DOMAIN DATA_SET_KIND AS VARCHAR(40) CHECK (VALUE IN ('PHYSICAL', 'LINK', 'CONTAINER')); +CREATE DOMAIN PLUGIN_TYPE AS VARCHAR(40) CHECK (VALUE IN ('JYTHON', 'PREDEPLOYED')); +CREATE DOMAIN OPERATION_EXECUTION_STATE AS VARCHAR(40) CHECK (VALUE IN ('NEW', 'SCHEDULED', 'RUNNING', 'FINISHED', 'FAILED')); +CREATE DOMAIN OPERATION_EXECUTION_AVAILABILITY AS VARCHAR(40) CHECK (VALUE IN ('AVAILABLE','DELETE_PENDING','DELETED','TIME_OUT_PENDING','TIMED_OUT')); +CREATE DOMAIN EDMS_ADDRESS_TYPE AS TEXT CHECK (VALUE IN ('OPENBIS', 'URL', 'FILE_SYSTEM')); +CREATE DOMAIN LOCATION_TYPE AS TEXT CHECK (VALUE IN ('OPENBIS', 'URL', 'FILE_SYSTEM_PLAIN', 'FILE_SYSTEM_GIT')); \ No newline at end of file diff --git a/openbis/source/sql/postgresql/189/function-189.sql b/openbis/source/sql/postgresql/189/function-189.sql new file mode 100644 index 0000000000000000000000000000000000000000..275bf48f76d0e1bd875ee224afd3f5db34356821 --- /dev/null +++ b/openbis/source/sql/postgresql/189/function-189.sql @@ -0,0 +1,3642 @@ +-- Creating Functions + +------------------------------------------------------------------------------------ +-- Purpose: Create function RENAME_SEQUENCE() that is required for renaming the sequences belonging to tables +------------------------------------------------------------------------------------ +CREATE FUNCTION RENAME_SEQUENCE(OLD_NAME VARCHAR, NEW_NAME VARCHAR) RETURNS INTEGER AS $$ +DECLARE + CURR_SEQ_VAL INTEGER; +BEGIN + SELECT INTO CURR_SEQ_VAL NEXTVAL(OLD_NAME); + EXECUTE 'CREATE SEQUENCE ' || NEW_NAME || ' START WITH ' || CURR_SEQ_VAL; + EXECUTE 'DROP SEQUENCE ' || OLD_NAME; + RETURN CURR_SEQ_VAL; +END; +$$ LANGUAGE 'plpgsql'; + + +------------------------------------------------------------------------------------ +-- Purpose: Create trigger CONTROLLED_VOCABULARY_CHECK +------------------------------------------------------------------------------------ + +CREATE OR REPLACE FUNCTION CONTROLLED_VOCABULARY_CHECK() RETURNS trigger AS $$ +DECLARE + v_code CODE; +BEGIN + + select code into v_code from data_types where id = NEW.daty_id; + + -- Check if the data is of type "CONTROLLEDVOCABULARY" + if v_code = 'CONTROLLEDVOCABULARY' then + if NEW.covo_id IS NULL then + RAISE EXCEPTION 'Insert/Update of Property Type (Code: %) failed, as its Data Type is CONTROLLEDVOCABULARY, but it is not linked to a Controlled Vocabulary.', NEW.code; + end if; + end if; + + RETURN NEW; + +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER CONTROLLED_VOCABULARY_CHECK BEFORE INSERT OR UPDATE ON PROPERTY_TYPES + FOR EACH ROW EXECUTE PROCEDURE CONTROLLED_VOCABULARY_CHECK(); + + +------------------------------------------------------------------------------------ +-- Purpose: Create trigger EXTERNAL_DATA_STORAGE_FORMAT_CHECK +------------------------------------------------------------------------------------ + +CREATE OR REPLACE FUNCTION EXTERNAL_DATA_STORAGE_FORMAT_CHECK() RETURNS trigger AS $$ +DECLARE + v_covo_code CODE; + data_code CODE; +BEGIN + + select code into v_covo_code from controlled_vocabularies + where is_managed_internally = true and + id = (select covo_id from controlled_vocabulary_terms where id = NEW.cvte_id_stor_fmt); + -- Check if the data storage format is a term of the controlled vocabulary "STORAGE_FORMAT" + if v_covo_code != 'STORAGE_FORMAT' then + select code into data_code from data_all where id = NEW.id; + RAISE EXCEPTION 'Insert/Update of Data (Code: %) failed, as its Storage Format is %, but is required to be STORAGE_FORMAT.', data_code, v_covo_code; + end if; + + RETURN NEW; + +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER EXTERNAL_DATA_STORAGE_FORMAT_CHECK BEFORE INSERT OR UPDATE ON EXTERNAL_DATA + FOR EACH ROW EXECUTE PROCEDURE EXTERNAL_DATA_STORAGE_FORMAT_CHECK(); + + +------------------------------------------------------------------------------------ +-- Purpose: Create triggers for checking sample code uniqueness +------------------------------------------------------------------------------------ + + +CREATE OR REPLACE FUNCTION sample_fill_code_unique_check() + RETURNS trigger AS +$BODY$ +BEGIN + NEW.code_unique_check = NEW.code || ',' || coalesce(NEW.samp_id_part_of, -1) || ',' || coalesce(NEW.proj_id, -1) || ',' || coalesce(NEW.space_id, -1); + RETURN NEW; +END; +$BODY$ + LANGUAGE 'plpgsql'; + + + +CREATE OR REPLACE FUNCTION sample_fill_subcode_unique_check() + RETURNS trigger AS +$BODY$ +DECLARE + unique_subcode BOOLEAN_CHAR; +BEGIN + SELECT is_subcode_unique into unique_subcode FROM sample_types WHERE id = NEW.saty_id; + + IF (unique_subcode) THEN + NEW.subcode_unique_check = NEW.code || ',' || coalesce(NEW.saty_id, -1) || ',' || coalesce(NEW.proj_id, -1) || ',' || coalesce(NEW.space_id, -1); + ELSE + NEW.subcode_unique_check = NULL; + END IF; + + RETURN NEW; +END; +$BODY$ + LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION disable_project_level_samples() + RETURNS trigger AS +$BODY$ +BEGIN + IF (NEW.proj_id IS NOT NULL) THEN + RAISE EXCEPTION 'Project level samples are disabled'; + END IF; + + RETURN NEW; +END; +$BODY$ + LANGUAGE 'plpgsql'; + + +CREATE OR REPLACE FUNCTION sample_type_fill_subcode_unique_check() + RETURNS trigger AS +$BODY$ +BEGIN + IF (NEW.is_subcode_unique::boolean <> OLD.is_subcode_unique::boolean) THEN + UPDATE samples_all SET subcode_unique_check = subcode_unique_check WHERE saty_id = NEW.id; + END IF; + RETURN NEW; +END; +$BODY$ + LANGUAGE 'plpgsql'; + + +CREATE TRIGGER sample_fill_code_unique_check + BEFORE INSERT OR UPDATE + ON samples_all + FOR EACH ROW + EXECUTE PROCEDURE sample_fill_code_unique_check(); + +CREATE TRIGGER disable_project_level_samples + BEFORE INSERT OR UPDATE + ON samples_all + FOR EACH ROW + EXECUTE PROCEDURE disable_project_level_samples(); + + +CREATE TRIGGER sample_fill_subcode_unique_check + BEFORE INSERT OR UPDATE + ON samples_all + FOR EACH ROW + EXECUTE PROCEDURE sample_fill_subcode_unique_check(); + +CREATE TRIGGER sample_type_fill_subcode_unique_check + AFTER UPDATE + ON sample_types + FOR EACH ROW + EXECUTE PROCEDURE sample_type_fill_subcode_unique_check(); + +--------------------------------------------------------------------------------------- +-- Purpose: trigger for data sets: They should be linked to an experiment or a sample with space +--------------------------------------------------------------------------------------- +CREATE OR REPLACE FUNCTION data_exp_or_sample_link_check() RETURNS trigger AS $$ +DECLARE + space_id CODE; + sample_code CODE; +BEGIN + if NEW.expe_id IS NOT NULL then + RETURN NEW; + end if; + if NEW.samp_id IS NULL then + RAISE EXCEPTION 'Neither experiment nor sample is specified for data set %', NEW.code; + end if; + select s.id, s.code into space_id, sample_code from samples_all s where s.id = NEW.samp_id; + if space_id is NULL then + RAISE EXCEPTION 'Sample % is a shared sample.', sample_code; + end if; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER data_exp_or_sample_link_check BEFORE INSERT OR UPDATE ON data_all +FOR EACH ROW EXECUTE PROCEDURE data_exp_or_sample_link_check(); + +------------------------------------------------------------------------------------ +-- Purpose: Create trigger MATERIAL/SAMPLE/EXPERIMENT/DATA_SET _PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK +-- It checks that if material property value is assigned to the entity, +-- then the material type is equal to the one described by property type. +------------------------------------------------------------------------------------ + +CREATE OR REPLACE FUNCTION MATERIAL_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK() RETURNS trigger AS $$ +DECLARE + v_type_id CODE; + v_type_id_prop CODE; +BEGIN + if NEW.mate_prop_id IS NOT NULL then + -- find material type id of the property type + select pt.maty_prop_id into v_type_id_prop + from material_type_property_types etpt, property_types pt + where NEW.mtpt_id = etpt.id AND etpt.prty_id = pt.id; + + if v_type_id_prop IS NOT NULL then + -- find material type id of the material which consists the entity's property value + select entity.maty_id into v_type_id + from materials entity + where NEW.mate_prop_id = entity.id; + if v_type_id != v_type_id_prop then + RAISE EXCEPTION 'Insert/Update of property value referencing material (id: %) failed, as referenced material type is different than expected (id %, expected id: %).', + NEW.mate_prop_id, v_type_id, v_type_id_prop; + end if; + end if; + end if; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER MATERIAL_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK BEFORE INSERT OR UPDATE ON material_properties + FOR EACH ROW EXECUTE PROCEDURE MATERIAL_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK(); + +CREATE OR REPLACE FUNCTION SAMPLE_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK() RETURNS trigger AS $$ +DECLARE + v_type_id CODE; + v_type_id_prop CODE; +BEGIN + if NEW.mate_prop_id IS NOT NULL then + -- find material type id of the property type + select pt.maty_prop_id into v_type_id_prop + from sample_type_property_types etpt, property_types pt + where NEW.stpt_id = etpt.id AND etpt.prty_id = pt.id; + + if v_type_id_prop IS NOT NULL then + -- find material type id of the material which consists the entity's property value + select entity.maty_id into v_type_id + from materials entity + where NEW.mate_prop_id = entity.id; + if v_type_id != v_type_id_prop then + RAISE EXCEPTION 'Insert/Update of property value referencing material (id: %) failed, as referenced material type is different than expected (id %, expected id: %).', + NEW.mate_prop_id, v_type_id, v_type_id_prop; + end if; + end if; + end if; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER SAMPLE_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK BEFORE INSERT OR UPDATE ON sample_properties + FOR EACH ROW EXECUTE PROCEDURE SAMPLE_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK(); + +CREATE OR REPLACE FUNCTION EXPERIMENT_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK() RETURNS trigger AS $$ +DECLARE + v_type_id CODE; + v_type_id_prop CODE; +BEGIN + if NEW.mate_prop_id IS NOT NULL then + -- find material type id of the property type + select pt.maty_prop_id into v_type_id_prop + from experiment_type_property_types etpt, property_types pt + where NEW.etpt_id = etpt.id AND etpt.prty_id = pt.id; + + if v_type_id_prop IS NOT NULL then + -- find material type id of the material which consists the entity's property value + select entity.maty_id into v_type_id + from materials entity + where NEW.mate_prop_id = entity.id; + if v_type_id != v_type_id_prop then + RAISE EXCEPTION 'Insert/Update of property value referencing material (id: %) failed, as referenced material type is different than expected (id %, expected id: %).', + NEW.mate_prop_id, v_type_id, v_type_id_prop; + end if; + end if; + end if; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER EXPERIMENT_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK BEFORE INSERT OR UPDATE ON experiment_properties + FOR EACH ROW EXECUTE PROCEDURE EXPERIMENT_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK(); + + -- data set +CREATE OR REPLACE FUNCTION DATA_SET_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK() RETURNS trigger AS $$ +DECLARE + v_type_id CODE; + v_type_id_prop CODE; +BEGIN + if NEW.mate_prop_id IS NOT NULL then + -- find material type id of the property type + select pt.maty_prop_id into v_type_id_prop + from data_set_type_property_types dstpt, property_types pt + where NEW.dstpt_id = dstpt.id AND dstpt.prty_id = pt.id; + + if v_type_id_prop IS NOT NULL then + -- find material type id of the material which consists the entity's property value + select entity.maty_id into v_type_id + from materials entity + where NEW.mate_prop_id = entity.id; + if v_type_id != v_type_id_prop then + RAISE EXCEPTION 'Insert/Update of property value referencing material (id: %) failed, as referenced material type is different than expected (id %, expected id: %).', + NEW.mate_prop_id, v_type_id, v_type_id_prop; + end if; + end if; + end if; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER DATA_SET_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK BEFORE INSERT OR UPDATE ON data_set_properties + FOR EACH ROW EXECUTE PROCEDURE DATA_SET_PROPERTY_WITH_MATERIAL_DATA_TYPE_CHECK(); + +---------------------------------------------------------------------------------------------------- +-- Purpose: Create DEFERRED triggers for checking consistency of deletion state. +---------------------------------------------------------------------------------------------------- +-- utility function describing a deletion + +CREATE OR REPLACE FUNCTION deletion_description(del_id TECH_ID) RETURNS VARCHAR AS $$ +DECLARE + del_person VARCHAR; + del_date VARCHAR; + del_reason VARCHAR; +BEGIN + SELECT p.last_name || ' ' || p.first_name || ' (' || p.email || ')', + to_char(d.registration_timestamp, 'YYYY-MM-DD HH:MM:SS'), d.reason + INTO del_person, del_date, del_reason FROM deletions d, persons p + WHERE d.pers_id_registerer = p.id AND d.id = del_id; + RETURN 'deleted by ' || del_person || ' on ' || del_date || ' with reason: "' || del_reason || '"'; +END; +$$ LANGUAGE 'plpgsql'; + +---------------------------------------------------------------------------------------------------- +-- 1. data set +--- on insert/update - deleted experiment or sample can't be connected +--- - parents/children relationship stays unchanged + +CREATE OR REPLACE FUNCTION check_created_or_modified_data_set_owner_is_alive() RETURNS trigger AS $$ +DECLARE + owner_code CODE; + owner_del_id TECH_ID; +BEGIN + IF (NEW.del_id IS NOT NULL) THEN + RETURN NEW; + END IF; + + -- check sample + IF (NEW.samp_id IS NOT NULL) THEN + SELECT del_id, code INTO owner_del_id, owner_code + FROM samples + WHERE id = NEW.samp_id; + IF (owner_del_id IS NOT NULL) THEN + RAISE EXCEPTION 'Data Set (Code: %) cannot be connected to a Sample (Code: %) %.', + NEW.code, owner_code, deletion_description(owner_del_id); + END IF; + END IF; + -- check experiment + IF (NEW.expe_id IS NOT NULL) THEN + SELECT del_id, code INTO owner_del_id, owner_code + FROM experiments + WHERE id = NEW.expe_id; + IF (owner_del_id IS NOT NULL) THEN + RAISE EXCEPTION 'Data Set (Code: %) cannot be connected to an Experiment (Code: %) %.', + NEW.code, owner_code, deletion_description(owner_del_id); + END IF; + END IF; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE CONSTRAINT TRIGGER check_created_or_modified_data_set_owner_is_alive + AFTER INSERT OR UPDATE ON data_all + DEFERRABLE INITIALLY DEFERRED + FOR EACH ROW + EXECUTE PROCEDURE check_created_or_modified_data_set_owner_is_alive(); + +---------------------------------------------------------------------------------------------------- +-- 2. sample +--- on insert/update -> experiment can't be deleted unless the sample is deleted +--- deletion +----> all directly connected data sets need to be deleted +----> all components and children need to be deleted + +CREATE OR REPLACE FUNCTION check_created_or_modified_sample_owner_is_alive() RETURNS trigger AS $$ +DECLARE + owner_code CODE; + owner_del_id TECH_ID; +BEGIN + IF (NEW.del_id IS NOT NULL) THEN + RETURN NEW; + END IF; + + -- check experiment (can't be deleted) + IF (NEW.expe_id IS NOT NULL) THEN + SELECT del_id, code INTO owner_del_id, owner_code + FROM experiments + WHERE id = NEW.expe_id; + IF (owner_del_id IS NOT NULL) THEN + RAISE EXCEPTION 'Sample (Code: %) cannot be connected to an Experiment (Code: %) %.', + NEW.code, owner_code, deletion_description(owner_del_id); + END IF; + END IF; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE CONSTRAINT TRIGGER check_created_or_modified_sample_owner_is_alive + AFTER INSERT OR UPDATE ON samples_all + DEFERRABLE INITIALLY DEFERRED + FOR EACH ROW + EXECUTE PROCEDURE check_created_or_modified_sample_owner_is_alive(); + +CREATE OR REPLACE FUNCTION check_deletion_consistency_on_sample_deletion() RETURNS trigger AS $$ +DECLARE + counter INTEGER; +BEGIN + IF (OLD.del_id IS NOT NULL OR NEW.del_id IS NULL) THEN + RETURN NEW; + END IF; + + -- all directly connected data sets need to be deleted + -- check datasets + SELECT count(*) INTO counter + FROM data + WHERE data.samp_id = NEW.id AND data.del_id IS NULL; + IF (counter > 0) THEN + RAISE EXCEPTION 'Sample (Code: %) deletion failed because at least one of its data sets was not deleted.', NEW.code; + END IF; + -- all components need to be deleted + SELECT count(*) INTO counter + FROM samples + WHERE samples.samp_id_part_of = NEW.id AND samples.del_id IS NULL; + IF (counter > 0) THEN + RAISE EXCEPTION 'Sample (Code: %) deletion failed because at least one of its component samples was not deleted.', NEW.code; + END IF; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE CONSTRAINT TRIGGER check_deletion_consistency_on_sample_deletion + AFTER UPDATE ON samples_all + DEFERRABLE INITIALLY DEFERRED + FOR EACH ROW + EXECUTE PROCEDURE check_deletion_consistency_on_sample_deletion(); + +----------------------------------------- +-- update sample relationships on revert +----------------------------------------- + +CREATE OR REPLACE FUNCTION preserve_deletion_consistency_on_sample_relationships() RETURNS trigger AS $$ +DECLARE + delid TECH_ID; +BEGIN + IF (NEW.del_id IS NOT NULL OR OLD.del_id IS NULL) THEN + RETURN NEW; + END IF; + SELECT del_id INTO delid + FROM SAMPLES_ALL where id = NEW.sample_id_parent; + IF (delid IS NOT NULL) THEN + NEW.del_id = delid; + END IF; + SELECT del_id INTO delid + FROM SAMPLES_ALL where id = NEW.sample_id_child; + IF (delid IS NOT NULL) THEN + NEW.del_id = delid; + END IF; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER preserve_deletion_consistency_on_sample_relationships + BEFORE UPDATE ON sample_relationships_all + FOR EACH ROW + EXECUTE PROCEDURE preserve_deletion_consistency_on_sample_relationships(); + +----------------------------------------- +-- update dataset relationships on revert +----------------------------------------- +CREATE OR REPLACE FUNCTION preserve_deletion_consistency_on_data_set_relationships() RETURNS trigger AS $$ +DECLARE + delid TECH_ID; +BEGIN + IF (NEW.del_id IS NOT NULL OR OLD.del_id IS NULL) THEN + RETURN NEW; + END IF; + SELECT del_id INTO delid + FROM DATA_ALL where id = NEW.data_id_parent; + IF (delid IS NOT NULL) THEN + NEW.del_id = delid; + END IF; + SELECT del_id INTO delid + FROM DATA_ALL where id = NEW.data_id_child; + IF (delid IS NOT NULL) THEN + NEW.del_id = delid; + END IF; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER preserve_deletion_consistency_on_data_set_relationships + BEFORE UPDATE ON data_set_relationships_all + FOR EACH ROW + EXECUTE PROCEDURE preserve_deletion_consistency_on_data_set_relationships(); + +---------------------------------------------------------------------------------------------------- +-- 3. experiment +--- deletion -> all directly connected samples and data sets need to be deleted + +CREATE OR REPLACE FUNCTION check_deletion_consistency_on_experiment_deletion() RETURNS trigger AS $$ +DECLARE + counter INTEGER; +BEGIN + IF (OLD.del_id IS NOT NULL OR NEW.del_id IS NULL) THEN + RETURN NEW; + END IF; + + -- check datasets + SELECT count(*) INTO counter + FROM data + WHERE data.expe_id = NEW.id AND data.del_id IS NULL; + IF (counter > 0) THEN + RAISE EXCEPTION 'Experiment (Code: %) deletion failed because at least one of its data sets was not deleted.', NEW.code; + END IF; + -- check samples + SELECT count(*) INTO counter + FROM samples + WHERE samples.expe_id = NEW.id AND samples.del_id IS NULL; + IF (counter > 0) THEN + RAISE EXCEPTION 'Experiment (Code: %) deletion failed because at least one of its samples was not deleted.', NEW.code; + END IF; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE CONSTRAINT TRIGGER check_deletion_consistency_on_experiment_deletion + AFTER UPDATE ON experiments_all + DEFERRABLE INITIALLY DEFERRED + FOR EACH ROW + EXECUTE PROCEDURE check_deletion_consistency_on_experiment_deletion(); + + +------------------------------------------------------------------------------------ +-- Purpose: Create functions/triggers to validate data in table content_copies. +------------------------------------------------------------------------------------ +CREATE OR REPLACE FUNCTION content_copies_uniqueness_check() + RETURNS trigger AS +$BODY$ +BEGIN + NEW.location_unique_check = NEW.data_id || ',' || + NEW.edms_id || ',' || + coalesce(NEW.path, '') || ',' || + coalesce(NEW.git_commit_hash, '') || ',' || + coalesce(NEW.git_repository_id, '') || ',' || + coalesce(NEW.external_code, ''); + RETURN NEW; +END; +$BODY$ + LANGUAGE 'plpgsql'; + +CREATE TRIGGER content_copies_uniqueness_check + BEFORE INSERT OR UPDATE + ON content_copies + FOR EACH ROW + EXECUTE PROCEDURE content_copies_uniqueness_check(); + + +CREATE OR REPLACE FUNCTION content_copies_location_type_check() RETURNS trigger AS $$ +DECLARE + edms_address_type EDMS_ADDRESS_TYPE; + index integer; +BEGIN + + select position(address_type in NEW.location_type), address_type into index, edms_address_type from external_data_management_systems + where id = NEW.edms_id; + + if index != 1 then + RAISE EXCEPTION 'Insert/Update to content_copies failed. Location type %, but edms.address_type %', NEW.location_type, edms_address_type; + end if; + + RETURN NEW; + +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER content_copies_location_type_check + BEFORE INSERT OR UPDATE + ON content_copies + FOR EACH ROW + EXECUTE PROCEDURE content_copies_location_type_check(); + +---------------------------------------------------------------------------------------------------- +-- Rules for views +---------------------------------------------------------------------------------------------------- +CREATE OR REPLACE RULE sample_insert AS + ON INSERT TO samples DO INSTEAD + INSERT INTO samples_all ( + id, + frozen, + frozen_for_comp, + frozen_for_children, + frozen_for_parents, + frozen_for_data, + code, + del_id, + orig_del, + expe_id, + expe_frozen, + proj_id, + proj_frozen, + modification_timestamp, + perm_id, + pers_id_registerer, + pers_id_modifier, + registration_timestamp, + samp_id_part_of, + cont_frozen, + saty_id, + space_id, + space_frozen, + version + ) VALUES ( + NEW.id, + NEW.frozen, + NEW.frozen_for_comp, + NEW.frozen_for_children, + NEW.frozen_for_parents, + NEW.frozen_for_data, + NEW.code, + NEW.del_id, + NEW.orig_del, + NEW.expe_id, + NEW.expe_frozen, + NEW.proj_id, + NEW.proj_frozen, + NEW.modification_timestamp, + NEW.perm_id, + NEW.pers_id_registerer, + NEW.pers_id_modifier, + NEW.registration_timestamp, + NEW.samp_id_part_of, + NEW.cont_frozen, + NEW.saty_id, + NEW.space_id, + NEW.space_frozen, + NEW.version + ); + +CREATE OR REPLACE RULE sample_update AS + ON UPDATE TO samples DO INSTEAD + UPDATE samples_all + SET code = NEW.code, + frozen = NEW.frozen, + frozen_for_comp = NEW.frozen_for_comp, + frozen_for_children = NEW.frozen_for_children, + frozen_for_parents = NEW.frozen_for_parents, + frozen_for_data = NEW.frozen_for_data, + del_id = NEW.del_id, + orig_del = NEW.orig_del, + expe_id = NEW.expe_id, + expe_frozen = NEW.expe_frozen, + proj_id = NEW.proj_id, + proj_frozen = NEW.proj_frozen, + modification_timestamp = NEW.modification_timestamp, + perm_id = NEW.perm_id, + pers_id_registerer = NEW.pers_id_registerer, + pers_id_modifier = NEW.pers_id_modifier, + registration_timestamp = NEW.registration_timestamp, + samp_id_part_of = NEW.samp_id_part_of, + cont_frozen = NEW.cont_frozen, + saty_id = NEW.saty_id, + space_id = NEW.space_id, + space_frozen = NEW.space_frozen, + version = NEW.version + WHERE id = NEW.id; + +CREATE OR REPLACE RULE sample_delete AS + ON DELETE TO samples DO INSTEAD + DELETE FROM samples_all + WHERE id = OLD.id; + +CREATE OR REPLACE RULE sample_deleted_update AS + ON UPDATE TO samples_deleted DO INSTEAD + UPDATE samples_all + SET del_id = NEW.del_id, + orig_del = NEW.orig_del, + modification_timestamp = NEW.modification_timestamp, + version = NEW.version + WHERE id = NEW.id; + +CREATE OR REPLACE RULE sample_deleted_delete AS + ON DELETE TO samples_deleted DO INSTEAD + DELETE FROM samples_all + WHERE id = OLD.id; + +---------------- +-- experiment -- +---------------- + +CREATE OR REPLACE RULE experiment_insert AS + ON INSERT TO experiments DO INSTEAD + INSERT INTO experiments_all ( + id, + frozen, + frozen_for_samp, + frozen_for_data, + code, + del_id, + orig_del, + exty_id, + is_public, + modification_timestamp, + perm_id, + pers_id_registerer, + pers_id_modifier, + proj_id, + proj_frozen, + registration_timestamp, + version + ) VALUES ( + NEW.id, + NEW.frozen, + NEW.frozen_for_samp, + NEW.frozen_for_data, + NEW.code, + NEW.del_id, + NEW.orig_del, + NEW.exty_id, + NEW.is_public, + NEW.modification_timestamp, + NEW.perm_id, + NEW.pers_id_registerer, + NEW.pers_id_modifier, + NEW.proj_id, + NEW.proj_frozen, + NEW.registration_timestamp, + NEW.version + ); + +CREATE OR REPLACE RULE experiment_update AS + ON UPDATE TO experiments DO INSTEAD + UPDATE experiments_all + SET code = NEW.code, + frozen = NEW.frozen, + frozen_for_samp = NEW.frozen_for_samp, + frozen_for_data = NEW.frozen_for_data, + del_id = NEW.del_id, + orig_del = NEW.orig_del, + exty_id = NEW.exty_id, + is_public = NEW.is_public, + modification_timestamp = NEW.modification_timestamp, + perm_id = NEW.perm_id, + pers_id_registerer = NEW.pers_id_registerer, + pers_id_modifier = NEW.pers_id_modifier, + proj_id = NEW.proj_id, + proj_frozen = NEW.proj_frozen, + registration_timestamp = NEW.registration_timestamp, + version = NEW.version + WHERE id = NEW.id; + +CREATE OR REPLACE RULE experiment_delete AS + ON DELETE TO experiments DO INSTEAD + DELETE FROM experiments_all + WHERE id = OLD.id; + +CREATE OR REPLACE RULE experiments_deleted_update AS + ON UPDATE TO experiments_deleted DO INSTEAD + UPDATE experiments_all + SET del_id = NEW.del_id, + orig_del = NEW.orig_del, + modification_timestamp = NEW.modification_timestamp, + version = NEW.version + WHERE id = NEW.id; + +CREATE OR REPLACE RULE experiments_deleted_delete AS + ON DELETE TO experiments_deleted DO INSTEAD + DELETE FROM experiments_all + WHERE id = OLD.id; + + +---------- +-- data -- +---------- + + +CREATE OR REPLACE RULE data_insert AS + ON INSERT TO data DO INSTEAD + INSERT INTO data_all ( + id, + frozen, + frozen_for_children, + frozen_for_parents, + frozen_for_comps, + frozen_for_conts, + code, + del_id, + orig_del, + expe_id, + expe_frozen, + dast_id, + data_producer_code, + dsty_id, + is_derived, + is_valid, + modification_timestamp, + access_timestamp, + pers_id_registerer, + pers_id_modifier, + production_timestamp, + registration_timestamp, + samp_id, + samp_frozen, + version, + data_set_kind + ) VALUES ( + NEW.id, + NEW.frozen, + NEW.frozen_for_children, + NEW.frozen_for_parents, + NEW.frozen_for_comps, + NEW.frozen_for_conts, + NEW.code, + NEW.del_id, + NEW.orig_del, + NEW.expe_id, + NEW.expe_frozen, + NEW.dast_id, + NEW.data_producer_code, + NEW.dsty_id, + NEW.is_derived, + NEW.is_valid, + NEW.modification_timestamp, + NEW.access_timestamp, + NEW.pers_id_registerer, + NEW.pers_id_modifier, + NEW.production_timestamp, + NEW.registration_timestamp, + NEW.samp_id, + NEW.samp_frozen, + NEW.version, + NEW.data_set_kind + ); + +CREATE OR REPLACE RULE data_update AS + ON UPDATE TO data DO INSTEAD + UPDATE data_all + SET code = NEW.code, + frozen = NEW.frozen, + frozen_for_children = NEW.frozen_for_children, + frozen_for_parents = NEW.frozen_for_parents, + frozen_for_comps = NEW.frozen_for_comps, + frozen_for_conts = NEW.frozen_for_conts, + del_id = NEW.del_id, + orig_del = NEW.orig_del, + expe_id = NEW.expe_id, + expe_frozen = NEW.expe_frozen, + dast_id = NEW.dast_id, + data_producer_code = NEW.data_producer_code, + dsty_id = NEW.dsty_id, + is_derived = NEW.is_derived, + is_valid = NEW.is_valid, + modification_timestamp = NEW.modification_timestamp, + access_timestamp = NEW.access_timestamp, + pers_id_registerer = NEW.pers_id_registerer, + pers_id_modifier = NEW.pers_id_modifier, + production_timestamp = NEW.production_timestamp, + registration_timestamp = NEW.registration_timestamp, + samp_id = NEW.samp_id, + samp_frozen = NEW.samp_frozen, + version = NEW.version, + data_set_kind = NEW.data_set_kind + WHERE id = NEW.id; + +CREATE OR REPLACE RULE data_all AS + ON DELETE TO data DO INSTEAD + DELETE FROM data_all + WHERE id = OLD.id; + +CREATE OR REPLACE RULE data_deleted_update AS + ON UPDATE TO data_deleted DO INSTEAD + UPDATE data_all + SET del_id = NEW.del_id, + orig_del = NEW.orig_del, + modification_timestamp = NEW.modification_timestamp, + version = NEW.version + WHERE id = NEW.id; + +CREATE OR REPLACE RULE data_deleted_delete AS + ON DELETE TO data_deleted DO INSTEAD + DELETE FROM data_all + WHERE id = OLD.id; + + +-- link_data must refer to a data set of kind LINK +CREATE OR REPLACE FUNCTION check_data_set_kind_link() RETURNS trigger AS $$ +DECLARE + kind DATA_SET_KIND; +BEGIN + SELECT data_set_kind INTO kind + FROM data_all + WHERE id = NEW.id; + IF (kind <> 'LINK') THEN + RAISE EXCEPTION 'Link data (Data Set Code: %) must reference a data set of kind LINK (is %).', + NEW.id, kind; + END IF; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE CONSTRAINT TRIGGER check_data_set_kind_link + AFTER INSERT OR UPDATE ON link_data + DEFERRABLE INITIALLY DEFERRED + FOR EACH ROW + EXECUTE PROCEDURE check_data_set_kind_link(); + +-- external_data must refer to a data set of kind PHYSICAL +CREATE OR REPLACE FUNCTION check_data_set_kind_physical() RETURNS trigger AS $$ +DECLARE + kind DATA_SET_KIND; +BEGIN + SELECT data_set_kind INTO kind + FROM data_all + WHERE id = NEW.id; + IF (kind <> 'PHYSICAL') THEN + RAISE EXCEPTION 'External data (Data Set Code: %) must reference a data set of kind PHYSICAL (is %).', + NEW.id, kind; + END IF; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE CONSTRAINT TRIGGER check_data_set_kind_physical + AFTER INSERT OR UPDATE ON external_data + DEFERRABLE INITIALLY DEFERRED + FOR EACH ROW + EXECUTE PROCEDURE check_data_set_kind_physical(); + +---------------------------------------------------------------------------------------------------- +-- Rules for properties history +---------------------------------------------------------------------------------------------------- + +-- Material Properties -- + +CREATE OR REPLACE RULE material_properties_update AS + ON UPDATE TO material_properties + WHERE (OLD.VALUE IS NOT NULL AND decode(replace(substring(OLD.value from 1 for 1), '\', '\\'), 'escape') != E'\\xefbfbd' AND OLD.VALUE != NEW.VALUE) + OR (OLD.CVTE_ID IS NOT NULL AND OLD.CVTE_ID != NEW.CVTE_ID) + OR (OLD.MATE_PROP_ID IS NOT NULL AND OLD.MATE_PROP_ID != NEW.MATE_PROP_ID) + DO ALSO + INSERT INTO material_properties_history ( + ID, + MATE_ID, + MTPT_ID, + VALUE, + VOCABULARY_TERM, + MATERIAL, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('MATERIAL_PROPERTY_ID_SEQ'), + OLD.MATE_ID, + OLD.MTPT_ID, + OLD.VALUE, + (select (t.code || ' [' || v.code || ']') from controlled_vocabulary_terms as t join controlled_vocabularies as v on t.covo_id = v.id where t.id = OLD.CVTE_ID), + (select (m.code || ' [' || mt.code || ']') from materials as m join material_types as mt on m.maty_id = mt.id where m.id = OLD.MATE_PROP_ID), + OLD.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + NEW.MODIFICATION_TIMESTAMP + ); + +CREATE OR REPLACE RULE material_properties_delete AS + ON DELETE TO material_properties + WHERE (OLD.VALUE IS NOT NULL AND decode(replace(substring(OLD.value from 1 for 1), '\', '\\'), 'escape') != E'\\xefbfbd') + OR OLD.CVTE_ID IS NOT NULL + OR OLD.MATE_PROP_ID IS NOT NULL + DO ALSO + INSERT INTO material_properties_history ( + ID, + MATE_ID, + MTPT_ID, + VALUE, + VOCABULARY_TERM, + MATERIAL, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('MATERIAL_PROPERTY_ID_SEQ'), + OLD.MATE_ID, + OLD.MTPT_ID, + OLD.VALUE, + (select (t.code || ' [' || v.code || ']') from controlled_vocabulary_terms as t join controlled_vocabularies as v on t.covo_id = v.id where t.id = OLD.CVTE_ID), + (select (m.code || ' [' || mt.code || ']') from materials as m join material_types as mt on m.maty_id = mt.id where m.id = OLD.MATE_PROP_ID), + OLD.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + current_timestamp + ); + +-- Experiment Properties -- + +CREATE OR REPLACE RULE experiment_properties_update AS + ON UPDATE TO experiment_properties + WHERE (OLD.VALUE IS NOT NULL AND decode(replace(substring(OLD.value from 1 for 1), '\', '\\'), 'escape') != E'\\xefbfbd' AND OLD.VALUE != NEW.VALUE) + OR (OLD.CVTE_ID IS NOT NULL AND OLD.CVTE_ID != NEW.CVTE_ID) + OR (OLD.MATE_PROP_ID IS NOT NULL AND OLD.MATE_PROP_ID != NEW.MATE_PROP_ID) + OR (OLD.SAMP_PROP_ID IS NOT NULL AND OLD.SAMP_PROP_ID != NEW.SAMP_PROP_ID) + DO ALSO + INSERT INTO experiment_properties_history ( + ID, + EXPE_ID, + ETPT_ID, + VALUE, + VOCABULARY_TERM, + MATERIAL, + SAMPLE, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('EXPERIMENT_PROPERTY_ID_SEQ'), + OLD.EXPE_ID, + OLD.ETPT_ID, + OLD.VALUE, + (select (t.code || ' [' || v.code || ']') from controlled_vocabulary_terms as t join controlled_vocabularies as v on t.covo_id = v.id where t.id = OLD.CVTE_ID), + (select (m.code || ' [' || mt.code || ']') from materials as m join material_types as mt on m.maty_id = mt.id where m.id = OLD.MATE_PROP_ID), + (select perm_id from samples_all where id = OLD.SAMP_PROP_ID), + OLD.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + NEW.MODIFICATION_TIMESTAMP + ); + +CREATE OR REPLACE RULE experiment_properties_delete AS + ON DELETE TO experiment_properties + WHERE (OLD.VALUE IS NOT NULL AND decode(replace(substring(OLD.value from 1 for 1), '\', '\\'), 'escape') != E'\\xefbfbd') + OR OLD.CVTE_ID IS NOT NULL + OR OLD.MATE_PROP_ID IS NOT NULL + OR OLD.SAMP_PROP_ID IS NOT NULL + DO ALSO + INSERT INTO experiment_properties_history ( + ID, + EXPE_ID, + ETPT_ID, + VALUE, + VOCABULARY_TERM, + MATERIAL, + SAMPLE, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('EXPERIMENT_PROPERTY_ID_SEQ'), + OLD.EXPE_ID, + OLD.ETPT_ID, + OLD.VALUE, + (select (t.code || ' [' || v.code || ']') from controlled_vocabulary_terms as t join controlled_vocabularies as v on t.covo_id = v.id where t.id = OLD.CVTE_ID), + (select (m.code || ' [' || mt.code || ']') from materials as m join material_types as mt on m.maty_id = mt.id where m.id = OLD.MATE_PROP_ID), + (select perm_id from samples_all where id = OLD.SAMP_PROP_ID), + OLD.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + current_timestamp + ); + +-- Sample Properties -- + + +CREATE OR REPLACE RULE sample_properties_update AS + ON UPDATE TO sample_properties + WHERE (OLD.VALUE IS NOT NULL AND decode(replace(substring(OLD.value from 1 for 1), '\', '\\'), 'escape') != E'\\xefbfbd' AND OLD.VALUE != NEW.VALUE) + OR (OLD.CVTE_ID IS NOT NULL AND OLD.CVTE_ID != NEW.CVTE_ID) + OR (OLD.MATE_PROP_ID IS NOT NULL AND OLD.MATE_PROP_ID != NEW.MATE_PROP_ID) + OR (OLD.SAMP_PROP_ID IS NOT NULL AND OLD.SAMP_PROP_ID != NEW.SAMP_PROP_ID) + DO ALSO + INSERT INTO sample_properties_history ( + ID, + SAMP_ID, + STPT_ID, + VALUE, + VOCABULARY_TERM, + MATERIAL, + SAMPLE, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_PROPERTY_ID_SEQ'), + OLD.SAMP_ID, + OLD.STPT_ID, + OLD.VALUE, + (select (t.code || ' [' || v.code || ']') from controlled_vocabulary_terms as t join controlled_vocabularies as v on t.covo_id = v.id where t.id = OLD.CVTE_ID), + (select (m.code || ' [' || mt.code || ']') from materials as m join material_types as mt on m.maty_id = mt.id where m.id = OLD.MATE_PROP_ID), + (select perm_id from samples_all where id = OLD.SAMP_PROP_ID), + OLD.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + NEW.MODIFICATION_TIMESTAMP + ); +CREATE OR REPLACE RULE sample_properties_delete AS + ON DELETE TO sample_properties + WHERE ((OLD.VALUE IS NOT NULL AND decode(replace(substring(OLD.value from 1 for 1), '\', '\\'), 'escape') != E'\\xefbfbd') + OR OLD.CVTE_ID IS NOT NULL + OR OLD.MATE_PROP_ID IS NOT NULL + OR OLD.SAMP_PROP_ID IS NOT NULL) + AND (SELECT DEL_ID FROM SAMPLES_ALL WHERE ID = OLD.SAMP_ID) IS NULL + DO ALSO + INSERT INTO sample_properties_history ( + ID, + SAMP_ID, + STPT_ID, + VALUE, + VOCABULARY_TERM, + MATERIAL, + SAMPLE, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_PROPERTY_ID_SEQ'), + OLD.SAMP_ID, + OLD.STPT_ID, + OLD.VALUE, + (select (t.code || ' [' || v.code || ']') from controlled_vocabulary_terms as t join controlled_vocabularies as v on t.covo_id = v.id where t.id = OLD.CVTE_ID), + (select (m.code || ' [' || mt.code || ']') from materials as m join material_types as mt on m.maty_id = mt.id where m.id = OLD.MATE_PROP_ID), + (select perm_id from samples_all where id = OLD.SAMP_PROP_ID), + OLD.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + current_timestamp + ); + + +-- Data Set Properties -- + +CREATE OR REPLACE RULE data_set_properties_update AS + ON UPDATE TO data_set_properties + WHERE (OLD.VALUE IS NOT NULL AND decode(replace(substring(OLD.value from 1 for 1), '\', '\\'), 'escape') != E'\\xefbfbd' AND OLD.VALUE != NEW.VALUE) + OR (OLD.CVTE_ID IS NOT NULL AND OLD.CVTE_ID != NEW.CVTE_ID) + OR (OLD.MATE_PROP_ID IS NOT NULL AND OLD.MATE_PROP_ID != NEW.MATE_PROP_ID) + OR (OLD.SAMP_PROP_ID IS NOT NULL AND OLD.SAMP_PROP_ID != NEW.SAMP_PROP_ID) + DO ALSO + INSERT INTO data_set_properties_history ( + ID, + DS_ID, + DSTPT_ID, + VALUE, + VOCABULARY_TERM, + MATERIAL, + SAMPLE, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('DATA_SET_PROPERTY_ID_SEQ'), + OLD.DS_ID, + OLD.DSTPT_ID, + OLD.VALUE, + (select (t.code || ' [' || v.code || ']') from controlled_vocabulary_terms as t join controlled_vocabularies as v on t.covo_id = v.id where t.id = OLD.CVTE_ID), + (select (m.code || ' [' || mt.code || ']') from materials as m join material_types as mt on m.maty_id = mt.id where m.id = OLD.MATE_PROP_ID), + (select perm_id from samples_all where id = OLD.SAMP_PROP_ID), + OLD.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + NEW.MODIFICATION_TIMESTAMP + ); + +CREATE OR REPLACE RULE data_set_properties_delete AS + ON DELETE TO data_set_properties + WHERE ((OLD.VALUE IS NOT NULL AND decode(replace(substring(OLD.value from 1 for 1), '\', '\\'), 'escape') != E'\\xefbfbd') + OR OLD.CVTE_ID IS NOT NULL + OR OLD.MATE_PROP_ID IS NOT NULL + OR OLD.SAMP_PROP_ID IS NOT NULL) + AND (SELECT DEL_ID FROM DATA_ALL WHERE ID = OLD.DS_ID) IS NULL + DO ALSO + INSERT INTO data_set_properties_history ( + ID, + DS_ID, + DSTPT_ID, + VALUE, + VOCABULARY_TERM, + MATERIAL, + SAMPLE, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('DATA_SET_PROPERTY_ID_SEQ'), + OLD.DS_ID, + OLD.DSTPT_ID, + OLD.VALUE, + (select (t.code || ' [' || v.code || ']') from controlled_vocabulary_terms as t join controlled_vocabularies as v on t.covo_id = v.id where t.id = OLD.CVTE_ID), + (select (m.code || ' [' || mt.code || ']') from materials as m join material_types as mt on m.maty_id = mt.id where m.id = OLD.MATE_PROP_ID), + (select perm_id from samples_all where id = OLD.SAMP_PROP_ID), + OLD.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + current_timestamp + ); + +-- End of rules for properties history +CREATE OR REPLACE RULE data_set_relationships_insert AS + ON INSERT TO data_set_relationships DO INSTEAD + INSERT INTO data_set_relationships_all ( + data_id_parent, + parent_frozen, + cont_frozen, + data_id_child, + child_frozen, + comp_frozen, + pers_id_author, + relationship_id, + ordinal, + registration_timestamp, + modification_timestamp + ) VALUES ( + NEW.data_id_parent, + NEW.parent_frozen, + NEW.cont_frozen, + NEW.data_id_child, + NEW.child_frozen, + NEW.comp_frozen, + NEW.pers_id_author, + NEW.relationship_id, + NEW.ordinal, + NEW.registration_timestamp, + NEW.modification_timestamp + ); + +CREATE OR REPLACE RULE data_set_relationships_update AS + ON UPDATE TO data_set_relationships DO INSTEAD + UPDATE data_set_relationships_all + SET + data_id_parent = NEW.data_id_parent, + parent_frozen = NEW.parent_frozen, + cont_frozen = NEW.cont_frozen, + data_id_child = NEW.data_id_child, + child_frozen = NEW.child_frozen, + comp_frozen = NEW.comp_frozen, + del_id = NEW.del_id, + relationship_id = NEW.relationship_id, + ordinal = NEW.ordinal, + pers_id_author = NEW.pers_id_author, + registration_timestamp = NEW.registration_timestamp, + modification_timestamp = NEW.modification_timestamp + WHERE data_id_parent = NEW.data_id_parent and data_id_child = NEW.data_id_child + and relationship_id = NEW.relationship_id; + +CREATE OR REPLACE RULE data_set_relationships_delete AS + ON DELETE TO data_set_relationships DO INSTEAD + DELETE FROM data_set_relationships_all + WHERE data_id_parent = OLD.data_id_parent and data_id_child = OLD.data_id_child + and relationship_id = OLD.relationship_id; + +CREATE OR REPLACE RULE sample_relationships_insert AS + ON INSERT TO sample_relationships DO INSTEAD + INSERT INTO sample_relationships_all ( + id, + sample_id_parent, + parent_frozen, + relationship_id, + sample_id_child, + child_frozen, + pers_id_author, + registration_timestamp, + modification_timestamp, + child_annotations, + parent_annotations + ) VALUES ( + NEW.id, + NEW.sample_id_parent, + NEW.parent_frozen, + NEW.relationship_id, + NEW.sample_id_child, + NEW.child_frozen, + NEW.pers_id_author, + NEW.registration_timestamp, + NEW.modification_timestamp, + NEW.child_annotations, + NEW.parent_annotations + ); + +CREATE OR REPLACE RULE sample_relationships_update AS + ON UPDATE TO sample_relationships DO INSTEAD + UPDATE sample_relationships_all + SET + sample_id_parent = NEW.sample_id_parent, + parent_frozen = NEW.parent_frozen, + relationship_id = NEW.relationship_id, + sample_id_child = NEW.sample_id_child, + child_frozen = NEW.child_frozen, + del_id = NEW.del_id, + pers_id_author = NEW.pers_id_author, + registration_timestamp = NEW.registration_timestamp, + modification_timestamp = NEW.modification_timestamp, + child_annotations = NEW.child_annotations, + parent_annotations = NEW.parent_annotations + WHERE id = NEW.id; + +CREATE OR REPLACE RULE sample_relationships_delete AS + ON DELETE TO sample_relationships DO INSTEAD + DELETE FROM sample_relationships_all + WHERE id = OLD.id; + +CREATE OR REPLACE RULE METAPROJECT_ASSIGNMENTS_INSERT AS + ON INSERT TO METAPROJECT_ASSIGNMENTS DO INSTEAD + INSERT INTO METAPROJECT_ASSIGNMENTS_ALL ( + ID, + MEPR_ID, + EXPE_ID, + SAMP_ID, + DATA_ID, + MATE_ID, + DEL_ID, + CREATION_DATE + ) VALUES ( + NEW.ID, + NEW.MEPR_ID, + NEW.EXPE_ID, + NEW.SAMP_ID, + NEW.DATA_ID, + NEW.MATE_ID, + NEW.DEL_ID, + NEW.CREATION_DATE + ); + +CREATE OR REPLACE RULE METAPROJECT_ASSIGNMENTS_UPDATE AS + ON UPDATE TO METAPROJECT_ASSIGNMENTS DO INSTEAD + UPDATE METAPROJECT_ASSIGNMENTS_ALL + SET + ID = NEW.ID, + MEPR_ID = NEW.MEPR_ID, + EXPE_ID = NEW.EXPE_ID, + SAMP_ID = NEW.SAMP_ID, + DATA_ID = NEW.DATA_ID, + MATE_ID = NEW.MATE_ID, + DEL_ID = NEW.DEL_ID, + CREATION_DATE = NEW.CREATION_DATE + WHERE ID = NEW.ID; + +CREATE OR REPLACE RULE METAPROJECT_ASSIGNMENTS_DELETE AS + ON DELETE TO METAPROJECT_ASSIGNMENTS DO INSTEAD + DELETE FROM METAPROJECT_ASSIGNMENTS_ALL + WHERE ID = OLD.ID; + +---------------------------------------------------------------------------------------------------- +-- Rules for relationships history +---------------------------------------------------------------------------------------------------- + +-- sample -> experiment + +CREATE OR REPLACE RULE sample_experiment_update AS + ON UPDATE TO samples_all + WHERE (OLD.EXPE_ID != NEW.EXPE_ID OR OLD.EXPE_ID IS NULL) AND NEW.EXPE_ID IS NOT NULL + DO ALSO ( + UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_EXPE_ID = OLD.EXPE_ID AND SAMP_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO EXPERIMENT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_EXPE_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('EXPERIMENT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.EXPE_ID, + 'OWNER', + NEW.ID, + 'SAMPLE', + NEW.PERM_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.ID AND EXPE_ID = OLD.EXPE_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + EXPE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.EXPE_ID, + 'EXPERIMENT', + (SELECT PERM_ID FROM EXPERIMENTS_ALL WHERE ID = NEW.EXPE_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_experiment_remove_update AS + ON UPDATE TO samples_all + WHERE OLD.EXPE_ID IS NOT NULL AND NEW.EXPE_ID IS NULL + DO ALSO ( + UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_EXPE_ID = OLD.EXPE_ID AND SAMP_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.ID AND EXPE_ID = OLD.EXPE_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + ); + +CREATE OR REPLACE RULE sample_experiment_insert AS + ON INSERT TO samples_all + WHERE NEW.EXPE_ID IS NOT NULL + DO ALSO ( + INSERT INTO EXPERIMENT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_EXPE_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('EXPERIMENT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.EXPE_ID, + 'OWNER', + NEW.ID, + 'SAMPLE', + NEW.PERM_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + EXPE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.EXPE_ID, + 'EXPERIMENT', + (SELECT PERM_ID FROM EXPERIMENTS_ALL WHERE ID = NEW.EXPE_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_experiment_delete AS + ON DELETE TO samples_all + WHERE OLD.EXPE_ID IS NOT NULL + DO ALSO + UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE MAIN_EXPE_ID = OLD.EXPE_ID AND SAMP_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + +-- container samples + +CREATE OR REPLACE RULE sample_container_update AS + ON UPDATE TO samples_all + WHERE (OLD.SAMP_ID_PART_OF != NEW.SAMP_ID_PART_OF OR OLD.SAMP_ID_PART_OF IS NULL) AND NEW.SAMP_ID_PART_OF IS NOT NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE (MAIN_SAMP_ID = OLD.SAMP_ID_PART_OF AND SAMP_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL AND RELATION_TYPE = 'CONTAINER') + OR (MAIN_SAMP_ID = OLD.ID AND SAMP_ID = OLD.SAMP_ID_PART_OF AND VALID_UNTIL_TIMESTAMP IS NULL AND RELATION_TYPE = 'CONTAINED'); + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMP_ID_PART_OF, + 'CONTAINER', + NEW.ID, + 'SAMPLE', + NEW.PERM_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'CONTAINED', + NEW.SAMP_ID_PART_OF, + 'SAMPLE', + (SELECT PERM_ID FROM SAMPLES_ALL WHERE ID = NEW.SAMP_ID_PART_OF), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_container_remove_update AS + ON UPDATE TO samples_all + WHERE OLD.SAMP_ID_PART_OF IS NOT NULL AND NEW.SAMP_ID_PART_OF IS NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE (MAIN_SAMP_ID = OLD.SAMP_ID_PART_OF AND SAMP_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL AND RELATION_TYPE = 'CONTAINER') + OR (MAIN_SAMP_ID = OLD.ID AND SAMP_ID = OLD.SAMP_ID_PART_OF AND VALID_UNTIL_TIMESTAMP IS NULL AND RELATION_TYPE = 'CONTAINED'); + ); + +CREATE OR REPLACE RULE sample_container_insert AS + ON INSERT TO samples_all + WHERE NEW.SAMP_ID_PART_OF IS NOT NULL + DO ALSO ( + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMP_ID_PART_OF, + 'CONTAINER', + NEW.ID, + 'SAMPLE', + NEW.PERM_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'CONTAINED', + NEW.SAMP_ID_PART_OF, + 'SAMPLE', + (SELECT PERM_ID FROM SAMPLES_ALL WHERE ID = NEW.SAMP_ID_PART_OF), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_container_delete AS + ON DELETE TO samples_all + WHERE OLD.SAMP_ID_PART_OF IS NOT NULL + DO ALSO + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE MAIN_SAMP_ID = OLD.SAMP_ID_PART_OF AND SAMP_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL AND RELATION_TYPE = 'CONTAINER'; + +-- dataset -> eperiment + +CREATE OR REPLACE RULE dataset_experiment_update AS + ON UPDATE TO data_all + WHERE (OLD.EXPE_ID != NEW.EXPE_ID OR OLD.SAMP_ID IS NOT NULL) AND NEW.SAMP_ID IS NULL + DO ALSO ( + UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_EXPE_ID = OLD.EXPE_ID AND DATA_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO EXPERIMENT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_EXPE_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('EXPERIMENT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.EXPE_ID, + 'OWNER', + NEW.ID, + 'DATA SET', + NEW.CODE, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + UPDATE DATA_SET_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE (MAIN_DATA_ID = OLD.ID AND EXPE_ID = OLD.EXPE_ID AND VALID_UNTIL_TIMESTAMP IS NULL); + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + EXPE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.EXPE_ID, + 'EXPERIMENT', + (SELECT PERM_ID FROM EXPERIMENTS_ALL WHERE ID = NEW.EXPE_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE dataset_experiment_remove_update AS + ON UPDATE TO data_all + WHERE OLD.SAMP_ID IS NULL AND NEW.SAMP_ID IS NOT NULL + DO ALSO ( + UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_EXPE_ID = OLD.EXPE_ID AND DATA_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + UPDATE DATA_SET_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_DATA_ID = OLD.ID AND EXPE_ID = OLD.EXPE_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + ); + +CREATE OR REPLACE RULE dataset_experiment_insert AS + ON INSERT TO data_all + WHERE NEW.EXPE_ID IS NOT NULL AND NEW.SAMP_ID IS NULL + DO ALSO ( + INSERT INTO EXPERIMENT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_EXPE_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('EXPERIMENT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.EXPE_ID, + 'OWNER', + NEW.ID, + 'DATA SET', + NEW.CODE, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + EXPE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.EXPE_ID, + 'EXPERIMENT', + (SELECT PERM_ID FROM EXPERIMENTS_ALL WHERE ID = NEW.EXPE_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE dataset_experiment_delete AS + ON DELETE TO data_all + WHERE OLD.EXPE_ID IS NOT NULL AND OLD.SAMP_ID IS NULL + DO ALSO + UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE MAIN_EXPE_ID = OLD.EXPE_ID AND DATA_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + +-- dataset -> sample + +CREATE OR REPLACE RULE dataset_sample_update AS + ON UPDATE TO data_all + WHERE (OLD.SAMP_ID != NEW.SAMP_ID OR OLD.SAMP_ID IS NULL) AND NEW.SAMP_ID IS NOT NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.SAMP_ID AND DATA_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMP_ID, + 'OWNER', + NEW.ID, + 'DATA SET', + NEW.CODE, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + UPDATE DATA_SET_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE (MAIN_DATA_ID = OLD.ID AND SAMP_ID = OLD.SAMP_ID AND VALID_UNTIL_TIMESTAMP IS NULL); + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.SAMP_ID, + 'SAMPLE', + (SELECT PERM_ID FROM SAMPLES_ALL WHERE ID = NEW.SAMP_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE dataset_sample_remove_update AS + ON UPDATE TO data_all + WHERE OLD.SAMP_ID IS NOT NULL AND NEW.SAMP_ID IS NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.SAMP_ID AND DATA_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + UPDATE DATA_SET_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_DATA_ID = OLD.ID AND SAMP_ID = OLD.SAMP_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + ); + +CREATE OR REPLACE RULE dataset_sample_insert AS + ON INSERT TO data_all + WHERE NEW.SAMP_ID IS NOT NULL + DO ALSO ( + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMP_ID, + 'OWNER', + NEW.ID, + 'DATA SET', + NEW.CODE, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.SAMP_ID, + 'SAMPLE', + (SELECT PERM_ID FROM SAMPLES_ALL WHERE ID = NEW.SAMP_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE dataset_sample_delete AS + ON DELETE TO data_all + WHERE OLD.SAMP_ID IS NOT NULL + DO ALSO + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE MAIN_SAMP_ID = OLD.SAMP_ID AND DATA_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + +-- data set relationship + +CREATE OR REPLACE RULE data_relationship_insert AS + ON INSERT TO data_set_relationships_all + WHERE NEW.DEL_ID IS NULL + DO ALSO ( + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + ORDINAL + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.DATA_ID_PARENT, + (SELECT UPPER(PARENT_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = NEW.RELATIONSHIP_ID), + NEW.DATA_ID_CHILD, + 'DATA SET', + (SELECT CODE FROM data_all WHERE ID = NEW.DATA_ID_CHILD), + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP, + NEW.ORDINAL + ); + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + ORDINAL + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.DATA_ID_CHILD, + (SELECT UPPER(CHILD_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = NEW.RELATIONSHIP_ID), + NEW.DATA_ID_PARENT, + 'DATA SET', + (SELECT CODE FROM data_all WHERE ID = NEW.DATA_ID_PARENT), + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP, + NEW.ORDINAL + ); + ); + +CREATE OR REPLACE RULE data_relationship_delete AS + ON DELETE TO data_set_relationships_all + WHERE OLD.DEL_ID IS NULL + DO ALSO ( + UPDATE DATA_SET_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE (MAIN_DATA_ID = OLD.DATA_ID_PARENT + AND DATA_ID = OLD.DATA_ID_CHILD + AND RELATION_TYPE = (SELECT UPPER(PARENT_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = OLD.RELATIONSHIP_ID) + AND VALID_UNTIL_TIMESTAMP IS NULL) + OR (MAIN_DATA_ID = OLD.DATA_ID_CHILD + AND DATA_ID = OLD.DATA_ID_PARENT + AND RELATION_TYPE = (SELECT UPPER(CHILD_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = OLD.RELATIONSHIP_ID) + AND VALID_UNTIL_TIMESTAMP IS NULL); + ); + +CREATE OR REPLACE RULE data_relationship_update AS + ON UPDATE TO data_set_relationships_all + WHERE NEW.DEL_ID IS NULL AND OLD.DEL_ID IS NULL + DO ALSO ( + UPDATE DATA_SET_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE (MAIN_DATA_ID = OLD.DATA_ID_PARENT + AND DATA_ID = OLD.DATA_ID_CHILD + AND RELATION_TYPE = (SELECT UPPER(PARENT_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = OLD.RELATIONSHIP_ID) + AND VALID_UNTIL_TIMESTAMP IS NULL) + OR (MAIN_DATA_ID = OLD.DATA_ID_CHILD + AND DATA_ID = OLD.DATA_ID_PARENT + AND RELATION_TYPE = (SELECT UPPER(CHILD_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = OLD.RELATIONSHIP_ID) + AND VALID_UNTIL_TIMESTAMP IS NULL); + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + ORDINAL + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.DATA_ID_PARENT, + (SELECT UPPER(PARENT_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = NEW.RELATIONSHIP_ID), + NEW.DATA_ID_CHILD, + 'DATA SET', + (SELECT CODE FROM data_all WHERE ID = NEW.DATA_ID_CHILD), + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP, + NEW.ORDINAL + ); + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + ORDINAL + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.DATA_ID_CHILD, + (SELECT UPPER(CHILD_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = NEW.RELATIONSHIP_ID), + NEW.DATA_ID_PARENT, + 'DATA SET', + (SELECT CODE FROM data_all WHERE ID = NEW.DATA_ID_PARENT), + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP, + NEW.ORDINAL + ); + ); + +CREATE OR REPLACE RULE data_relationship_trash_update AS + ON UPDATE TO data_set_relationships_all + WHERE NEW.DEL_ID IS NOT NULL AND OLD.DEL_ID IS NULL + DO ALSO ( + UPDATE DATA_SET_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE (MAIN_DATA_ID = OLD.DATA_ID_PARENT + AND DATA_ID = OLD.DATA_ID_CHILD + AND RELATION_TYPE = (SELECT UPPER(PARENT_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = OLD.RELATIONSHIP_ID) + AND VALID_UNTIL_TIMESTAMP IS NULL) + OR (MAIN_DATA_ID = OLD.DATA_ID_CHILD + AND DATA_ID = OLD.DATA_ID_PARENT + AND RELATION_TYPE = (SELECT UPPER(CHILD_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = OLD.RELATIONSHIP_ID) + AND VALID_UNTIL_TIMESTAMP IS NULL); + ); + +CREATE OR REPLACE RULE data_relationship_trash_revert_update AS + ON UPDATE TO data_set_relationships_all + WHERE OLD.DEL_ID IS NOT NULL AND NEW.DEL_ID IS NULL + DO ALSO ( + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + ORDINAL + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.DATA_ID_PARENT, + (SELECT UPPER(PARENT_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = NEW.RELATIONSHIP_ID), + NEW.DATA_ID_CHILD, + 'DATA SET', + (SELECT CODE FROM data_all WHERE ID = NEW.DATA_ID_CHILD), + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP, + NEW.ORDINAL + ); + INSERT INTO DATA_SET_RELATIONSHIPS_HISTORY ( + ID, + MAIN_DATA_ID, + RELATION_TYPE, + DATA_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + ORDINAL + ) VALUES ( + nextval('DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.DATA_ID_CHILD, + (SELECT UPPER(CHILD_LABEL) FROM RELATIONSHIP_TYPES WHERE ID = NEW.RELATIONSHIP_ID), + NEW.DATA_ID_PARENT, + 'DATA SET', + (SELECT CODE FROM data_all WHERE ID = NEW.DATA_ID_PARENT), + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP, + NEW.ORDINAL + ); + ); + + + +-- samples parent-child relationship + +CREATE OR REPLACE RULE sample_parent_child_insert AS + ON INSERT TO sample_relationships_all + WHERE NEW.DEL_ID IS NULL + DO ALSO ( + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + ANNOTATIONS, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMPLE_ID_PARENT, + 'PARENT', + NEW.SAMPLE_ID_CHILD, + 'SAMPLE', + (SELECT PERM_ID FROM samples_all WHERE ID = NEW.SAMPLE_ID_CHILD), + NEW.PARENT_ANNOTATIONS, + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + ANNOTATIONS, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMPLE_ID_CHILD, + 'CHILD', + NEW.SAMPLE_ID_PARENT, + 'SAMPLE', + (SELECT PERM_ID FROM samples_all WHERE ID = NEW.SAMPLE_ID_PARENT), + NEW.CHILD_ANNOTATIONS, + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_parent_child_delete AS + ON DELETE TO sample_relationships_all + WHERE OLD.DEL_ID IS NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE (MAIN_SAMP_ID = OLD.SAMPLE_ID_PARENT AND SAMP_ID = OLD.SAMPLE_ID_CHILD AND VALID_UNTIL_TIMESTAMP IS NULL) + OR (MAIN_SAMP_ID = OLD.SAMPLE_ID_CHILD AND SAMP_ID = OLD.SAMPLE_ID_PARENT AND VALID_UNTIL_TIMESTAMP IS NULL); + ); +CREATE OR REPLACE RULE sample_child_annotations_update AS + ON UPDATE TO sample_relationships_all + WHERE OLD.DEL_ID IS NULL AND NEW.DEL_ID IS NULL + AND OLD.SAMPLE_ID_CHILD = NEW.SAMPLE_ID_CHILD AND OLD.SAMPLE_ID_PARENT = NEW.SAMPLE_ID_PARENT + AND OLD.CHILD_ANNOTATIONS <> NEW.CHILD_ANNOTATIONS + DO ALSO ( + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + ANNOTATIONS, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP, + VALID_UNTIL_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMPLE_ID_CHILD, + 'CHILD', + NEW.SAMPLE_ID_PARENT, + 'SAMPLE', + (SELECT PERM_ID FROM samples_all WHERE ID = NEW.SAMPLE_ID_PARENT), + OLD.CHILD_ANNOTATIONS, + NEW.PERS_ID_AUTHOR, + OLD.MODIFICATION_TIMESTAMP, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_parent_annotations_update AS + ON UPDATE TO sample_relationships_all + WHERE OLD.DEL_ID IS NULL AND NEW.DEL_ID IS NULL + AND OLD.SAMPLE_ID_CHILD = NEW.SAMPLE_ID_CHILD AND OLD.SAMPLE_ID_PARENT = NEW.SAMPLE_ID_PARENT + AND OLD.PARENT_ANNOTATIONS <> NEW.PARENT_ANNOTATIONS + DO ALSO ( + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + ANNOTATIONS, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMPLE_ID_PARENT, + 'PARENT', + NEW.SAMPLE_ID_CHILD, + 'SAMPLE', + (SELECT PERM_ID FROM samples_all WHERE ID = NEW.SAMPLE_ID_CHILD), + OLD.PARENT_ANNOTATIONS, + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_parent_child_update AS + ON UPDATE TO sample_relationships_all + WHERE NEW.DEL_ID IS NOT NULL AND OLD.DEL_ID IS NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE (MAIN_SAMP_ID = OLD.SAMPLE_ID_PARENT AND SAMP_ID = OLD.SAMPLE_ID_CHILD AND VALID_UNTIL_TIMESTAMP IS NULL) + OR (MAIN_SAMP_ID = OLD.SAMPLE_ID_CHILD AND SAMP_ID = OLD.SAMPLE_ID_PARENT AND VALID_UNTIL_TIMESTAMP IS NULL); + ); + +CREATE OR REPLACE RULE sample_parent_child_revert_update AS + ON UPDATE TO sample_relationships_all + WHERE NEW.DEL_ID IS NULL AND OLD.DEL_ID IS NOT NULL + DO ALSO ( + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + ANNOTATIONS, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMPLE_ID_PARENT, + 'PARENT', + NEW.SAMPLE_ID_CHILD, + 'SAMPLE', + (SELECT PERM_ID FROM samples_all WHERE ID = NEW.SAMPLE_ID_CHILD), + NEW.PARENT_ANNOTATIONS, + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + ANNOTATIONS, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.SAMPLE_ID_CHILD, + 'CHILD', + NEW.SAMPLE_ID_PARENT, + 'SAMPLE', + (SELECT PERM_ID FROM samples_all WHERE ID = NEW.SAMPLE_ID_PARENT), + NEW.CHILD_ANNOTATIONS, + NEW.PERS_ID_AUTHOR, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +-- experiment -> project + +CREATE OR REPLACE RULE experiment_project_update AS + ON UPDATE TO experiments_all + WHERE (OLD.PROJ_ID != NEW.PROJ_ID OR OLD.PROJ_ID IS NULL) AND NEW.PROJ_ID IS NOT NULL + DO ALSO ( + UPDATE PROJECT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_PROJ_ID = OLD.PROJ_ID AND EXPE_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO PROJECT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_PROJ_ID, + RELATION_TYPE, + EXPE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('PROJECT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.PROJ_ID, + 'OWNER', + NEW.ID, + 'EXPERIMENT', + NEW.PERM_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_EXPE_ID = OLD.ID AND PROJ_ID = OLD.PROJ_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO EXPERIMENT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_EXPE_ID, + RELATION_TYPE, + PROJ_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('EXPERIMENT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.PROJ_ID, + 'PROJECT', + (SELECT perm_id FROM PROJECTS WHERE ID = NEW.PROJ_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE experiment_project_remove_update AS + ON UPDATE TO experiments_all + WHERE OLD.PROJ_ID IS NOT NULL AND NEW.PROJ_ID IS NULL + DO ALSO ( + UPDATE PROJECT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_PROJ_ID = OLD.PROJ_ID AND EXPE_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_EXPE_ID = OLD.ID AND PROJ_ID = OLD.PROJ_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + ); + +CREATE OR REPLACE RULE experiment_project_insert AS + ON INSERT TO experiments_all + WHERE NEW.PROJ_ID IS NOT NULL + DO ALSO ( + INSERT INTO PROJECT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_PROJ_ID, + RELATION_TYPE, + EXPE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('PROJECT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.PROJ_ID, + 'OWNER', + NEW.ID, + 'EXPERIMENT', + NEW.PERM_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO EXPERIMENT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_EXPE_ID, + RELATION_TYPE, + PROJ_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('EXPERIMENT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.PROJ_ID, + 'PROJECT', + (SELECT perm_id FROM PROJECTS WHERE ID = NEW.PROJ_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE experiment_project_delete AS + ON DELETE TO experiments_all + WHERE OLD.PROJ_ID IS NOT NULL + DO ALSO + UPDATE PROJECT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = current_timestamp + WHERE MAIN_PROJ_ID = OLD.PROJ_ID AND EXPE_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + +-- project -> space + +CREATE OR REPLACE RULE project_space_update AS + ON UPDATE TO projects + WHERE (OLD.SPACE_ID != NEW.SPACE_ID OR OLD.SPACE_ID IS NULL) AND NEW.SPACE_ID IS NOT NULL + DO ALSO ( + UPDATE PROJECT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_PROJ_ID = OLD.ID AND SPACE_ID = OLD.SPACE_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO PROJECT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_PROJ_ID, + RELATION_TYPE, + SPACE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('PROJECT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.SPACE_ID, + 'SPACE', + (SELECT CODE FROM SPACES WHERE ID = NEW.SPACE_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE project_space_remove_update AS + ON UPDATE TO projects + WHERE OLD.SPACE_ID IS NOT NULL AND NEW.SPACE_ID IS NULL + DO ALSO ( + UPDATE PROJECT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_PROJ_ID = OLD.ID AND SPACE_ID = OLD.SPACE_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + ); + +CREATE OR REPLACE RULE project_space_insert AS + ON INSERT TO projects + WHERE NEW.SPACE_ID IS NOT NULL + DO ALSO ( + INSERT INTO PROJECT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_PROJ_ID, + RELATION_TYPE, + SPACE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('PROJECT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.SPACE_ID, + 'SPACE', + (SELECT CODE FROM SPACES WHERE ID = NEW.SPACE_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +-- sample -> project + +CREATE OR REPLACE RULE sample_project_update AS + ON UPDATE TO samples_all + WHERE (OLD.PROJ_ID != NEW.PROJ_ID OR OLD.PROJ_ID IS NULL OR OLD.EXPE_ID IS NOT NULL) AND NEW.PROJ_ID IS NOT NULL AND NEW.EXPE_ID IS NULL + DO ALSO ( + UPDATE PROJECT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_PROJ_ID = OLD.PROJ_ID AND SAMP_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO PROJECT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_PROJ_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('PROJECT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.PROJ_ID, + 'OWNER', + NEW.ID, + 'SAMPLE', + NEW.PERM_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.ID AND PROJ_ID = OLD.PROJ_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + PROJ_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.PROJ_ID, + 'PROJECT', + (SELECT PERM_ID FROM PROJECTS WHERE ID = NEW.PROJ_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_project_remove_update AS + ON UPDATE TO samples_all + WHERE OLD.PROJ_ID IS NOT NULL AND (NEW.PROJ_ID IS NULL OR (OLD.EXPE_ID IS NULL AND NEW.EXPE_ID IS NOT NULL)) + DO ALSO ( + UPDATE PROJECT_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_PROJ_ID = OLD.PROJ_ID AND SAMP_ID = OLD.ID AND VALID_UNTIL_TIMESTAMP IS NULL; + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.ID AND PROJ_ID = OLD.PROJ_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + ); + +CREATE OR REPLACE RULE sample_project_insert AS + ON INSERT TO samples_all + WHERE NEW.EXPE_ID IS NULL AND NEW.PROJ_ID IS NOT NULL + DO ALSO ( + INSERT INTO PROJECT_RELATIONSHIPS_HISTORY ( + ID, + MAIN_PROJ_ID, + RELATION_TYPE, + SAMP_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('PROJECT_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.PROJ_ID, + 'OWNER', + NEW.ID, + 'SAMPLE', + NEW.PERM_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + PROJ_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.PROJ_ID, + 'PROJECT', + (SELECT PERM_ID FROM PROJECTS WHERE ID = NEW.PROJ_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +-- sample -> project + +CREATE OR REPLACE RULE sample_space_update AS + ON UPDATE TO samples_all + WHERE (OLD.SPACE_ID != NEW.SPACE_ID OR OLD.SPACE_ID IS NULL OR OLD.EXPE_ID IS NOT NULL OR OLD.PROJ_ID IS NOT NULL) AND NEW.SPACE_ID IS NOT NULL AND NEW.EXPE_ID IS NULL AND NEW.PROJ_ID IS NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.ID AND SPACE_ID = OLD.SPACE_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SPACE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.SPACE_ID, + 'SPACE', + (SELECT CODE FROM SPACES WHERE ID = NEW.SPACE_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_space_remove_update AS + ON UPDATE TO samples_all + WHERE OLD.SPACE_ID IS NOT NULL AND (NEW.SPACE_ID IS NULL OR (OLD.EXPE_ID IS NULL AND NEW.EXPE_ID IS NOT NULL) OR (OLD.PROJ_ID IS NULL AND NEW.PROJ_ID IS NOT NULL)) + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.ID AND SPACE_ID = OLD.SPACE_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + ); + +CREATE OR REPLACE RULE sample_space_insert AS + ON INSERT TO samples_all + WHERE NEW.EXPE_ID IS NULL AND NEW.SPACE_ID IS NOT NULL AND NEW.PROJ_ID IS NULL + DO ALSO ( + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SPACE_ID, + ENTITY_KIND, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.SPACE_ID, + 'SPACE', + (SELECT CODE FROM SPACES WHERE ID = NEW.SPACE_ID), + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +-- rules for shared samples + +CREATE OR REPLACE RULE sample_shared_insert AS + ON INSERT TO samples_all + WHERE NEW.SPACE_ID IS NULL + DO ALSO ( + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + EXPE_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.EXPE_ID, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_shared_update AS + ON UPDATE TO samples_all + WHERE OLD.SPACE_ID IS NOT NULL AND NEW.SPACE_ID IS NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.ID AND SPACE_ID = OLD.SPACE_ID AND VALID_UNTIL_TIMESTAMP IS NULL; + INSERT INTO SAMPLE_RELATIONSHIPS_HISTORY ( + ID, + MAIN_SAMP_ID, + RELATION_TYPE, + SPACE_ID, + ENTITY_PERM_ID, + PERS_ID_AUTHOR, + VALID_FROM_TIMESTAMP + ) VALUES ( + nextval('SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ'), + NEW.ID, + 'OWNED', + NEW.SPACE_ID, + NULL, + NEW.PERS_ID_MODIFIER, + NEW.MODIFICATION_TIMESTAMP + ); + ); + +CREATE OR REPLACE RULE sample_shared_remove_update AS + ON UPDATE TO samples_all + WHERE OLD.SPACE_ID IS NULL AND NEW.SPACE_ID IS NOT NULL + DO ALSO ( + UPDATE SAMPLE_RELATIONSHIPS_HISTORY SET VALID_UNTIL_TIMESTAMP = NEW.MODIFICATION_TIMESTAMP + WHERE MAIN_SAMP_ID = OLD.ID AND SPACE_ID IS NULL AND ENTITY_PERM_ID IS NULL AND PROJ_ID IS NULL + AND EXPE_ID IS NULL AND VALID_UNTIL_TIMESTAMP IS NULL; + ); + +-- end of rules for relationships history + + +-- data set content copies relationships + +CREATE OR REPLACE RULE content_copies_history_insert AS + ON INSERT TO content_copies + DO ALSO ( + INSERT INTO data_set_copies_history ( + id, + cc_id, + data_id, + external_code, + path, + git_commit_hash, + git_repository_id, + edms_id, + edms_code, + edms_label, + edms_address, + pers_id_author, + valid_from_timestamp + ) VALUES ( + nextval('data_set_copies_history_id_seq'), + NEW.id, + NEW.data_id, + NEW.external_code, + NEW.path, + NEW.git_commit_hash, + NEW.git_repository_id, + NEW.edms_id, + (SELECT code FROM external_data_management_systems WHERE id = NEW.edms_id), + (SELECT label FROM external_data_management_systems WHERE id = NEW.edms_id), + (SELECT address FROM external_data_management_systems WHERE id = NEW.edms_id), + NEW.pers_id_registerer, + NEW.registration_timestamp); + ); + +CREATE OR REPLACE RULE content_copies_history_delete AS + ON DELETE TO content_copies + DO ALSO ( + UPDATE data_set_copies_history SET valid_until_timestamp = CURRENT_TIMESTAMP + WHERE cc_id = OLD.id; + ); + +-- create content copy history entry on external dms change +CREATE OR REPLACE RULE edms_a_insert_content_copy_history AS + ON UPDATE TO external_data_management_systems + DO ALSO ( + INSERT INTO data_set_copies_history ( + id, + cc_id, + data_id, + external_code, + path, + git_commit_hash, + git_repository_id, + edms_id, + edms_code, + edms_label, + edms_address, + pers_id_author, + valid_from_timestamp + ) + SELECT + nextval('data_set_copies_history_id_seq'), + dsch.cc_id, + dsch.data_id, + dsch.external_code, + dsch.path, + dsch.git_commit_hash, + dsch.git_repository_id, + dsch.edms_id, + NEW.code, + NEW.label, + NEW.address, + dsch.pers_id_author, + CURRENT_TIMESTAMP + FROM data_set_copies_history dsch + JOIN external_data_management_systems edms + ON edms.id = dsch.edms_id + WHERE NEW.id = dsch.edms_id AND dsch.valid_until_timestamp IS NULL; + ); + +-- expire content copy history entry on external dms change +CREATE OR REPLACE RULE edms_b_expire_content_copy_history AS + ON UPDATE TO external_data_management_systems + DO ALSO ( + UPDATE + data_set_copies_history SET valid_until_timestamp = CURRENT_TIMESTAMP + WHERE valid_until_timestamp IS NULL + AND edms_id = NEW.id + AND valid_from_timestamp <> CURRENT_TIMESTAMP; +); + +--------------------------- +-- Triggers for freezing +--------------------------- + +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE() RETURNS trigger AS $$ +BEGIN + RAISE EXCEPTION 'Operation % is not allowed because % % is frozen.', TG_ARGV[0], TG_ARGV[1], OLD.code; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_SPACE_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + space_id TECH_ID; + operation TEXT; +BEGIN + IF (NEW.space_id IS NOT NULL AND NEW.space_frozen) THEN + space_id = NEW.space_id; + operation = 'SET SPACE'; + ELSEIF (OLD.space_id IS NOT NULL AND OLD.space_frozen) THEN + space_id = OLD.space_id; + operation = 'REMOVE SPACE'; + END IF; + + RAISE EXCEPTION 'Operation % is not allowed because % % and space % are frozen.', operation, TG_ARGV[0], NEW.code, + (select code from spaces where id = space_id); +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_PROJECT_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + project_id TECH_ID; + operation TEXT; +BEGIN + IF (NEW.proj_id IS NOT NULL AND NEW.proj_frozen) THEN + project_id = NEW.proj_id; + operation = 'SET PROJECT'; + ELSEIF (OLD.proj_id IS NOT NULL AND OLD.proj_frozen) THEN + project_id = OLD.proj_id; + operation = 'REMOVE PROJECT'; + END IF; + + RAISE EXCEPTION 'Operation % is not allowed because % % and project % are frozen.', operation, TG_ARGV[0], NEW.code, + (select code from projects where id = project_id); +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_EXPERIMENT_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + experiment_id TECH_ID; + operation TEXT; +BEGIN + IF (NEW.expe_id IS NOT NULL AND NEW.expe_frozen) THEN + experiment_id = NEW.expe_id; + operation = 'SET EXPERIMENT'; + ELSEIF (OLD.expe_id IS NOT NULL AND OLD.expe_frozen) THEN + experiment_id = OLD.expe_id; + operation = 'REMOVE EXPERIMENT'; + END IF; + + RAISE EXCEPTION 'Operation % is not allowed because % % and experiment % are frozen.', operation, TG_ARGV[0], NEW.code, + (select code from experiments_all where id = experiment_id); +END; +$$ LANGUAGE 'plpgsql'; + +--------------------------- +-- Triggers for freezing +--------------------------- + +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE() RETURNS trigger AS $$ +BEGIN + RAISE EXCEPTION 'Operation % is not allowed because % % is frozen.', TG_ARGV[0], TG_ARGV[1], OLD.code; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_SPACE_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + space_id TECH_ID; + operation TEXT; +BEGIN + IF (NEW.space_id IS NOT NULL AND NEW.space_frozen) THEN + space_id = NEW.space_id; + operation = 'SET SPACE'; + ELSEIF (OLD.space_id IS NOT NULL AND OLD.space_frozen) THEN + space_id = OLD.space_id; + operation = 'REMOVE SPACE'; + END IF; + + RAISE EXCEPTION 'Operation % is not allowed because space % is frozen for % %.', operation, + (select code from spaces where id = space_id), TG_ARGV[0], NEW.code; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_PROJECT_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + project_id TECH_ID; + operation TEXT; +BEGIN + IF (NEW.proj_id IS NOT NULL AND NEW.proj_frozen) THEN + project_id = NEW.proj_id; + operation = 'SET PROJECT'; + ELSEIF (OLD.proj_id IS NOT NULL AND OLD.proj_frozen) THEN + project_id = OLD.proj_id; + operation = 'REMOVE PROJECT'; + END IF; + + RAISE EXCEPTION 'Operation % is not allowed because project % is frozen for % %.', operation, + (select code from projects where id = project_id), TG_ARGV[0], NEW.code; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_EXPERIMENT_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + experiment_id TECH_ID; + operation TEXT; +BEGIN + IF (NEW.expe_id IS NOT NULL AND NEW.expe_frozen) THEN + experiment_id = NEW.expe_id; + operation = 'SET EXPERIMENT'; + ELSEIF (OLD.expe_id IS NOT NULL AND OLD.expe_frozen) THEN + experiment_id = OLD.expe_id; + operation = 'REMOVE EXPERIMENT'; + END IF; + + RAISE EXCEPTION 'Operation % is not allowed because experiment % is frozen for % %.', operation, + (select code from experiments_all where id = experiment_id), TG_ARGV[0], NEW.code; +END; +$$ LANGUAGE 'plpgsql'; + +-- Spaces -------------------- +-- Spaces melting + +CREATE OR REPLACE FUNCTION MELT_SPACE_FOR() RETURNS trigger as $$ +BEGIN + NEW.FROZEN_FOR_PROJ = 'f'; + NEW.FROZEN_FOR_SAMP = 'f'; + return NEW; +end; +$$ language plpgsql; + +DROP TRIGGER IF EXISTS MELT_SPACE_FOR ON SPACES; +CREATE TRIGGER MELT_SPACE_FOR BEFORE UPDATE ON SPACES + FOR EACH ROW WHEN ((NEW.FROZEN_FOR_PROJ OR NEW.FROZEN_FOR_SAMP) AND NOT NEW.FROZEN) + EXECUTE PROCEDURE MELT_SPACE_FOR(); + +-- Spaces deleting + +DROP TRIGGER IF EXISTS SPACE_FROZEN_CHECK_ON_DELETE ON SPACES; +CREATE TRIGGER SPACE_FROZEN_CHECK_ON_DELETE BEFORE DELETE ON SPACES + FOR EACH ROW WHEN (OLD.frozen) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('DELETE', 'space'); + +-- Space update + +DROP TRIGGER IF EXISTS SPACE_FROZEN_CHECK_ON_UPDATE ON SPACES; +CREATE TRIGGER SPACE_FROZEN_CHECK_ON_UPDATE BEFORE UPDATE ON SPACES + FOR EACH ROW WHEN (OLD.frozen AND NEW.frozen AND + (OLD.description <> NEW.description + OR (OLD.description IS NULL AND NEW.description IS NOT NULL) + OR (OLD.description IS NOT NULL AND NEW.description IS NULL))) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('UPDATE', 'space'); + +-- Projects -------------------- +-- Projects melting + +CREATE OR REPLACE FUNCTION MELT_PROJECT_FOR() RETURNS trigger as $$ +BEGIN + NEW.FROZEN_FOR_EXP = 'f'; + NEW.FROZEN_FOR_SAMP = 'f'; + return NEW; +end; +$$ language plpgsql; + +DROP TRIGGER IF EXISTS MELT_PROJECT_FOR ON PROJECTS; +CREATE TRIGGER MELT_PROJECT_FOR BEFORE UPDATE ON PROJECTS + FOR EACH ROW WHEN ((NEW.FROZEN_FOR_EXP OR NEW.FROZEN_FOR_SAMP) AND NOT NEW.FROZEN) + EXECUTE PROCEDURE MELT_PROJECT_FOR(); + +-- Project deleting + +DROP TRIGGER IF EXISTS PROJECT_FROZEN_CHECK_ON_DELETE ON PROJECTS; +CREATE TRIGGER PROJECT_FROZEN_CHECK_ON_DELETE BEFORE DELETE ON PROJECTS + FOR EACH ROW WHEN (OLD.frozen) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('DELETE', 'project'); + +-- Project update +DROP TRIGGER IF EXISTS PROJECT_FROZEN_CHECK_ON_UPDATE ON PROJECTS; +CREATE TRIGGER PROJECT_FROZEN_CHECK_ON_UPDATE BEFORE UPDATE ON PROJECTS + FOR EACH ROW WHEN (OLD.frozen AND NEW.frozen AND + (OLD.description <> NEW.description + OR (OLD.description IS NULL AND NEW.description IS NOT NULL) + OR (OLD.description IS NOT NULL AND NEW.description IS NULL))) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('UPDATE', 'project'); + +-- Project attachment inserting, updating and deleting +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_PROJECT() RETURNS trigger AS $$ +DECLARE + project_id TECH_ID; +BEGIN + IF (TG_OP = 'DELETE') THEN + project_id = OLD.proj_id; + ELSEIF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN + project_id = NEW.proj_id; + END IF; + + RAISE EXCEPTION 'Operation % % is not allowed because project % is frozen.', TG_OP, TG_ARGV[0], + (select code from projects where id = project_id); +END; +$$ LANGUAGE 'plpgsql'; +DROP TRIGGER IF EXISTS PROJECT_FROZEN_CHECK_ON_INSERT_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER PROJECT_FROZEN_CHECK_ON_INSERT_ATTACHMENT BEFORE INSERT ON ATTACHMENTS + FOR EACH ROW WHEN (NEW.PROJ_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_PROJECT('ATTACHMENT'); + +DROP TRIGGER IF EXISTS PROJECT_FROZEN_CHECK_ON_UPDATE_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER PROJECT_FROZEN_CHECK_ON_UPDATE_ATTACHMENT BEFORE UPDATE ON ATTACHMENTS + FOR EACH ROW WHEN (OLD.PROJ_FROZEN AND NEW.PROJ_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_PROJECT('ATTACHMENT'); + +DROP TRIGGER IF EXISTS PROJECT_FROZEN_CHECK_ON_DELETE_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER PROJECT_FROZEN_CHECK_ON_DELETE_ATTACHMENT BEFORE DELETE ON ATTACHMENTS + FOR EACH ROW WHEN (OLD.PROJ_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_PROJECT('ATTACHMENT'); + +-- Project space relationship +DROP TRIGGER IF EXISTS ADD_PROJECT_TO_SPACE_CHECK ON PROJECTS; +CREATE TRIGGER ADD_PROJECT_TO_SPACE_CHECK AFTER INSERT ON PROJECTS + FOR EACH ROW WHEN (NEW.SPACE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SPACE_RELATIONSHIP('project'); + +DROP TRIGGER IF EXISTS PROJECT_SPACE_RELATIONSHIP_FROZEN_CHECK ON PROJECTS; +CREATE TRIGGER PROJECT_SPACE_RELATIONSHIP_FROZEN_CHECK BEFORE UPDATE ON PROJECTS + FOR EACH ROW WHEN (NEW.space_id <> OLD.space_id AND (NEW.SPACE_FROZEN OR OLD.SPACE_FROZEN)) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SPACE_RELATIONSHIP('project'); + +-- Experiments -------------------- +-- Experiments melting + +CREATE OR REPLACE FUNCTION MELT_EXPERIMENT_FOR() RETURNS trigger as $$ +BEGIN + NEW.FROZEN_FOR_SAMP = 'f'; + NEW.FROZEN_FOR_DATA = 'f'; + return NEW; +end; +$$ language plpgsql; + +DROP TRIGGER IF EXISTS MELT_EXPERIMENT_FOR ON EXPERIMENTS_ALL; +CREATE TRIGGER MELT_EXPERIMENT_FOR BEFORE UPDATE ON EXPERIMENTS_ALL + FOR EACH ROW WHEN ((NEW.FROZEN_FOR_SAMP OR NEW.FROZEN_FOR_DATA) AND NOT NEW.FROZEN) + EXECUTE PROCEDURE MELT_EXPERIMENT_FOR(); + +-- Experiment trashing and deleting + +DROP TRIGGER IF EXISTS EXPERIMENT_FROZEN_CHECK_ON_TRASH ON EXPERIMENTS_ALL; +CREATE TRIGGER EXPERIMENT_FROZEN_CHECK_ON_TRASH BEFORE UPDATE ON EXPERIMENTS_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.frozen) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('TRASH', 'experiment'); + +DROP TRIGGER IF EXISTS EXPERIMENT_FROZEN_CHECK_ON_DELETE ON EXPERIMENTS_ALL; +CREATE TRIGGER EXPERIMENT_FROZEN_CHECK_ON_DELETE BEFORE DELETE ON EXPERIMENTS_ALL + FOR EACH ROW WHEN (OLD.frozen) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('DELETE', 'experiment'); + +-- Experiment property inserting, updating and deleting +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_EXPERIMENT() RETURNS trigger AS $$ +DECLARE + experiment_id TECH_ID; +BEGIN + IF (TG_OP = 'DELETE') THEN + experiment_id = OLD.expe_id; + ELSEIF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN + experiment_id = NEW.expe_id; + END IF; + + RAISE EXCEPTION 'Operation % % is not allowed because experiment % is frozen.', TG_OP, TG_ARGV[0], + (select code from experiments_all where id = experiment_id); +END; +$$ LANGUAGE 'plpgsql'; + +DROP TRIGGER IF EXISTS EXPERIMENT_FROZEN_CHECK_ON_INSERT_PROPERTY ON EXPERIMENT_PROPERTIES; +CREATE TRIGGER EXPERIMENT_FROZEN_CHECK_ON_INSERT_PROPERTY BEFORE INSERT ON EXPERIMENT_PROPERTIES + FOR EACH ROW WHEN (NEW.EXPE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT('PROPERTY'); + +DROP TRIGGER IF EXISTS EXPERIMENT_FROZEN_CHECK_ON_CHANGE_PROPERTY ON EXPERIMENT_PROPERTIES; +CREATE TRIGGER EXPERIMENT_FROZEN_CHECK_ON_CHANGE_PROPERTY BEFORE UPDATE ON EXPERIMENT_PROPERTIES + FOR EACH ROW WHEN (OLD.EXPE_FROZEN AND NEW.EXPE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT('PROPERTY'); + +DROP TRIGGER IF EXISTS EXPERIMENT_FROZEN_CHECK_ON_DELETE_PROPERTY ON EXPERIMENT_PROPERTIES; +CREATE TRIGGER EXPERIMENT_FROZEN_CHECK_ON_DELETE_PROPERTY BEFORE DELETE ON EXPERIMENT_PROPERTIES + FOR EACH ROW WHEN (OLD.EXPE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT('PROPERTY'); + +-- Experiment attachment inserting, updating and deleting +DROP TRIGGER IF EXISTS EXPERIMENT_FROZEN_CHECK_ON_INSERT_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER EXPERIMENT_FROZEN_CHECK_ON_INSERT_ATTACHMENT BEFORE INSERT ON ATTACHMENTS + FOR EACH ROW WHEN (NEW.EXPE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT('ATTACHMENT'); + +DROP TRIGGER IF EXISTS EXPERIMENT_FROZEN_CHECK_ON_UPDATE_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER EXPERIMENT_FROZEN_CHECK_ON_UPDATE_ATTACHMENT BEFORE UPDATE ON ATTACHMENTS + FOR EACH ROW WHEN (OLD.EXPE_FROZEN AND NEW.EXPE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT('ATTACHMENT'); + +DROP TRIGGER IF EXISTS EXPERIMENT_FROZEN_CHECK_ON_DELETE_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER EXPERIMENT_FROZEN_CHECK_ON_DELETE_ATTACHMENT BEFORE DELETE ON ATTACHMENTS + FOR EACH ROW WHEN (OLD.EXPE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT('ATTACHMENT'); + +-- Experiment project relationship +DROP TRIGGER IF EXISTS ADD_EXPERIMENT_TO_PROJECT_CHECK ON EXPERIMENTS_ALL; +CREATE TRIGGER ADD_EXPERIMENT_TO_PROJECT_CHECK AFTER INSERT ON EXPERIMENTS_ALL + FOR EACH ROW WHEN (NEW.PROJ_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_PROJECT_RELATIONSHIP('experiment'); + +DROP TRIGGER IF EXISTS EXPERIMENT_PROJECT_RELATIONSHIP_FROZEN_CHECK ON EXPERIMENTS_ALL; +CREATE TRIGGER EXPERIMENT_PROJECT_RELATIONSHIP_FROZEN_CHECK BEFORE UPDATE ON EXPERIMENTS_ALL + FOR EACH ROW WHEN (NEW.proj_id <> OLD.proj_id AND (NEW.PROJ_FROZEN OR OLD.PROJ_FROZEN)) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_PROJECT_RELATIONSHIP('experiment'); + +-- Samples -------------------- +-- Samples melting + +CREATE OR REPLACE FUNCTION MELT_SAMPLE_FOR() RETURNS trigger as $$ +BEGIN + NEW.FROZEN_FOR_COMP = 'f'; + NEW.FROZEN_FOR_CHILDREN = 'f'; + NEW.FROZEN_FOR_PARENTS = 'f'; + NEW.FROZEN_FOR_DATA = 'f'; + return NEW; +end; +$$ language plpgsql; + +DROP TRIGGER IF EXISTS MELT_SAMPLE_FOR ON SAMPLES_ALL; +CREATE TRIGGER MELT_SAMPLE_FOR BEFORE UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN ((NEW.FROZEN_FOR_COMP OR NEW.FROZEN_FOR_CHILDREN OR NEW.FROZEN_FOR_PARENTS OR NEW.FROZEN_FOR_DATA) AND NOT NEW.FROZEN) + EXECUTE PROCEDURE MELT_SAMPLE_FOR(); + +-- Sample trashing and deleting + +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_TRASH ON SAMPLES_ALL; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_TRASH BEFORE UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.frozen) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('TRASH', 'sample'); + +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_DELETE ON SAMPLES_ALL; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_DELETE BEFORE DELETE ON SAMPLES_ALL + FOR EACH ROW WHEN (OLD.frozen) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('DELETE', 'sample'); + +-- Sample property inserting, updating and deleting +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_SAMPLE() RETURNS trigger AS $$ +DECLARE + sample_id TECH_ID; +BEGIN + IF (TG_OP = 'DELETE') THEN + sample_id = OLD.samp_id; + ELSEIF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN + sample_id = NEW.samp_id; + END IF; + + RAISE EXCEPTION 'Operation % % is not allowed because sample % is frozen.', TG_OP, TG_ARGV[0], + (select code from samples_all where id = sample_id); +END; +$$ LANGUAGE 'plpgsql'; + +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_INSERT_PROPERTY ON SAMPLE_PROPERTIES; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_INSERT_PROPERTY BEFORE INSERT ON SAMPLE_PROPERTIES + FOR EACH ROW WHEN (NEW.SAMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE('PROPERTY'); + +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_CHANGE_PROPERTY ON SAMPLE_PROPERTIES; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_CHANGE_PROPERTY BEFORE UPDATE ON SAMPLE_PROPERTIES + FOR EACH ROW WHEN (OLD.SAMP_FROZEN AND NEW.SAMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE('PROPERTY'); + +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_DELETE_PROPERTY ON SAMPLE_PROPERTIES; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_DELETE_PROPERTY BEFORE DELETE ON SAMPLE_PROPERTIES + FOR EACH ROW WHEN (OLD.SAMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE('PROPERTY'); + +-- Sample attachment inserting, updating and deleting +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_INSERT_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_INSERT_ATTACHMENT BEFORE INSERT ON ATTACHMENTS + FOR EACH ROW WHEN (NEW.SAMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE('ATTACHMENT'); + +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_UPDATE_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_UPDATE_ATTACHMENT BEFORE UPDATE ON ATTACHMENTS + FOR EACH ROW WHEN (OLD.SAMP_FROZEN AND NEW.SAMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE('ATTACHMENT'); + +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_DELETE_ATTACHMENT ON ATTACHMENTS; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_DELETE_ATTACHMENT BEFORE DELETE ON ATTACHMENTS + FOR EACH ROW WHEN (OLD.SAMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE('ATTACHMENT'); + +-- Sample container setting and removing +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_SAMPLE_CONTAINER_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + sample_id TECH_ID; + operation TEXT; +BEGIN + IF (NEW.samp_id_part_of IS NOT NULL AND NEW.CONT_FROZEN) THEN + sample_id = NEW.samp_id_part_of; + operation = 'SET CONTAINER'; + ELSEIF (OLD.samp_id_part_of IS NOT NULL AND OLD.CONT_FROZEN) THEN + sample_id = OLD.samp_id_part_of; + operation = 'REMOVE CONTAINER'; + END IF; + + RAISE EXCEPTION 'Operation % is not allowed because sample % is frozen for sample %.', operation, + (select code from samples_all where id = sample_id), NEW.code; +END; +$$ LANGUAGE 'plpgsql'; + +DROP TRIGGER IF EXISTS ADD_SAMPLE_TO_CONTAINER_CHECK ON SAMPLES_ALL; +CREATE TRIGGER ADD_SAMPLE_TO_CONTAINER_CHECK AFTER INSERT ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.CONT_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE_CONTAINER_RELATIONSHIP(); + +DROP TRIGGER IF EXISTS SAMPLE_FROZEN_CHECK_ON_SET_CONTAINER ON SAMPLES_ALL; +CREATE TRIGGER SAMPLE_FROZEN_CHECK_ON_SET_CONTAINER BEFORE UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN ( + (NEW.samp_id_part_of <> OLD.samp_id_part_of + OR (NEW.samp_id_part_of IS NOT NULL AND OLD.samp_id_part_of IS NULL) + OR (NEW.samp_id_part_of IS NULL AND OLD.samp_id_part_of IS NOT NULL)) + AND (NEW.CONT_FROZEN OR OLD.CONT_FROZEN)) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE_CONTAINER_RELATIONSHIP(); + +-- Sample parent-child relationship inserting and deleting +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_SAMPLE_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + parent_id TECH_ID; + child_id TECH_ID; +BEGIN + IF (TG_OP = 'DELETE') THEN + parent_id = OLD.sample_id_parent; + child_id = OLD.sample_id_child; + ELSEIF (TG_OP = 'INSERT') THEN + parent_id = NEW.sample_id_parent; + child_id = NEW.sample_id_child; + END IF; + RAISE EXCEPTION 'Operation % is not allowed because sample % or % is frozen.', TG_OP, + (select code from samples_all where id = parent_id), + (select code from samples_all where id = child_id); +END; +$$ LANGUAGE 'plpgsql'; + +DROP TRIGGER IF EXISTS SAMPLE_RELATIONSHIP_FROZEN_CHECK_ON_INSERT ON SAMPLE_RELATIONSHIPS_ALL; +CREATE TRIGGER SAMPLE_RELATIONSHIP_FROZEN_CHECK_ON_INSERT BEFORE INSERT ON SAMPLE_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (NEW.PARENT_FROZEN OR NEW.CHILD_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE_RELATIONSHIP(); + +DROP TRIGGER IF EXISTS SAMPLE_RELATIONSHIP_FROZEN_CHECK_ON_DELETE ON SAMPLE_RELATIONSHIPS_ALL; +CREATE TRIGGER SAMPLE_RELATIONSHIP_FROZEN_CHECK_ON_DELETE BEFORE DELETE ON SAMPLE_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (OLD.PARENT_FROZEN OR OLD.CHILD_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SAMPLE_RELATIONSHIP(); + +-- Sample experiment relationship +DROP TRIGGER IF EXISTS ADD_SAMPLE_TO_EXPERIMENT_CHECK ON SAMPLES_ALL; +CREATE TRIGGER ADD_SAMPLE_TO_EXPERIMENT_CHECK AFTER INSERT ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.EXPE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT_RELATIONSHIP('sample'); + +DROP TRIGGER IF EXISTS SAMPLE_EXPERIMENT_RELATIONSHIP_FROZEN_CHECK ON SAMPLES_ALL; +CREATE TRIGGER SAMPLE_EXPERIMENT_RELATIONSHIP_FROZEN_CHECK BEFORE UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN ( + (NEW.expe_id <> OLD.expe_id + OR (NEW.expe_id IS NOT NULL AND OLD.expe_id IS NULL) + OR (NEW.expe_id IS NULL AND OLD.expe_id IS NOT NULL)) + AND (NEW.EXPE_FROZEN OR OLD.EXPE_FROZEN)) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT_RELATIONSHIP('sample'); + +-- Sample project relationship +DROP TRIGGER IF EXISTS ADD_SAMPLE_TO_PROJECT_CHECK ON SAMPLES_ALL; +CREATE TRIGGER ADD_SAMPLE_TO_PROJECT_CHECK AFTER INSERT ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.PROJ_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_PROJECT_RELATIONSHIP('sample'); + +DROP TRIGGER IF EXISTS SAMPLE_PROJECT_RELATIONSHIP_FROZEN_CHECK ON SAMPLES_ALL; +CREATE TRIGGER SAMPLE_PROJECT_RELATIONSHIP_FROZEN_CHECK BEFORE UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN ( + (NEW.proj_id <> OLD.proj_id + OR (NEW.proj_id IS NOT NULL AND OLD.proj_id IS NULL) + OR (NEW.proj_id IS NULL AND OLD.proj_id IS NOT NULL)) + AND (NEW.PROJ_FROZEN OR OLD.PROJ_FROZEN)) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_PROJECT_RELATIONSHIP('sample'); + +-- Sample space relationship +DROP TRIGGER IF EXISTS ADD_SAMPLE_TO_SPACE_CHECK ON SAMPLES_ALL; +CREATE TRIGGER ADD_SAMPLE_TO_SPACE_CHECK AFTER INSERT ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.SPACE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SPACE_RELATIONSHIP('sample'); + +DROP TRIGGER IF EXISTS SAMPLE_SPACE_RELATIONSHIP_FROZEN_CHECK ON SAMPLES_ALL; +CREATE TRIGGER SAMPLE_SPACE_RELATIONSHIP_FROZEN_CHECK BEFORE UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN ( + (NEW.space_id <> OLD.space_id + OR (NEW.space_id IS NOT NULL AND OLD.space_id IS NULL) + OR (NEW.space_id IS NULL AND OLD.space_id IS NOT NULL)) + AND (NEW.SPACE_FROZEN OR OLD.SPACE_FROZEN)) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_SPACE_RELATIONSHIP('sample'); + +-- Data Set -------------------- +-- Set melting + +CREATE OR REPLACE FUNCTION MELT_DATA_SET_FOR() RETURNS trigger as $$ +BEGIN + NEW.FROZEN_FOR_CHILDREN = 'f'; + NEW.FROZEN_FOR_PARENTS = 'f'; + NEW.FROZEN_FOR_COMPS = 'f'; + NEW.FROZEN_FOR_CONTS = 'f'; + return NEW; +end; +$$ language plpgsql; + +DROP TRIGGER IF EXISTS MELT_DATA_SET_FOR ON DATA_ALL; +CREATE TRIGGER MELT_DATA_SET_FOR BEFORE UPDATE ON DATA_ALL + FOR EACH ROW WHEN ((NEW.FROZEN_FOR_CHILDREN OR NEW.FROZEN_FOR_PARENTS OR NEW.FROZEN_FOR_COMPS OR NEW.FROZEN_FOR_CONTS) AND NOT NEW.FROZEN) + EXECUTE PROCEDURE MELT_DATA_SET_FOR(); + +-- Data set trashing and deleting + +DROP TRIGGER IF EXISTS DATA_SET_FROZEN_CHECK_ON_TRASH ON DATA_ALL; +CREATE TRIGGER DATA_SET_FROZEN_CHECK_ON_TRASH BEFORE UPDATE ON DATA_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.frozen) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('TRASH', 'data set'); + +DROP TRIGGER IF EXISTS DATA_SET_FROZEN_CHECK_ON_DELETE ON DATA_ALL; +CREATE TRIGGER DATA_SET_FROZEN_CHECK_ON_DELETE BEFORE DELETE ON DATA_ALL + FOR EACH ROW WHEN (OLD.frozen) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_ENTITY_BY_CODE('DELETE', 'data set'); + +-- Data set property inserting, updating and deleting +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_DATA_SET() RETURNS trigger AS $$ +DECLARE + ds_id TECH_ID; +BEGIN + IF (TG_OP = 'DELETE') THEN + ds_id = OLD.ds_id; + ELSEIF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN + ds_id = NEW.ds_id; + END IF; + + RAISE EXCEPTION 'Operation % % is not allowed because data set % is frozen.', TG_OP, TG_ARGV[0], + (select code from data_all where id = ds_id); +END; +$$ LANGUAGE 'plpgsql'; + +DROP TRIGGER IF EXISTS DATA_SET_FROZEN_CHECK_ON_INSERT_PROPERTY ON DATA_SET_PROPERTIES; +CREATE TRIGGER DATA_SET_FROZEN_CHECK_ON_INSERT_PROPERTY BEFORE INSERT ON DATA_SET_PROPERTIES + FOR EACH ROW WHEN (NEW.DASE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_DATA_SET('PROPERTY'); + +DROP TRIGGER IF EXISTS DATA_SET_FROZEN_CHECK_ON_CHANGE_PROPERTY ON DATA_SET_PROPERTIES; +CREATE TRIGGER DATA_SET_FROZEN_CHECK_ON_CHANGE_PROPERTY BEFORE UPDATE ON DATA_SET_PROPERTIES + FOR EACH ROW WHEN (OLD.DASE_FROZEN AND NEW.DASE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_DATA_SET('PROPERTY'); + +DROP TRIGGER IF EXISTS DATA_SET_FROZEN_CHECK_ON_DELETE_PROPERTY ON DATA_SET_PROPERTIES; +CREATE TRIGGER DATA_SET_FROZEN_CHECK_ON_DELETE_PROPERTY BEFORE DELETE ON DATA_SET_PROPERTIES + FOR EACH ROW WHEN (OLD.DASE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_DATA_SET('PROPERTY'); + +-- Data set parent-child/container-component relationship inserting and deleting +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_DATA_SET_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + parent_id TECH_ID; + child_id TECH_ID; + relationship_id TECH_ID; + relationship CODE; + parent_child_frozen BOOLEAN_CHAR; + cont_comp_frozen BOOLEAN_CHAR; +BEGIN + IF (TG_OP = 'DELETE') THEN + parent_id = OLD.data_id_parent; + child_id = OLD.data_id_child; + relationship_id = OLD.relationship_id; + parent_child_frozen = OLD.parent_frozen OR OLD.child_frozen; + cont_comp_frozen = OLD.cont_frozen OR OLD.comp_frozen; + ELSEIF (TG_OP = 'INSERT') THEN + parent_id = NEW.data_id_parent; + child_id = NEW.data_id_child; + relationship_id = NEW.relationship_id; + parent_child_frozen = NEW.parent_frozen OR NEW.child_frozen; + cont_comp_frozen = NEW.cont_frozen OR NEW.comp_frozen; + END IF; + SELECT code INTO relationship FROM relationship_types WHERE id = relationship_id; + IF (relationship = 'PARENT_CHILD' AND parent_child_frozen) OR (relationship = 'CONTAINER_COMPONENT' AND cont_comp_frozen) THEN + RAISE EXCEPTION 'Operation % % is not allowed because data set % or % is frozen.', TG_OP, relationship, + (select code from data_all where id = parent_id), + (select code from data_all where id = child_id); + END IF; + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSEIF (TG_OP = 'INSERT') THEN + RETURN NEW; + END IF; +END; +$$ LANGUAGE 'plpgsql'; + +DROP TRIGGER IF EXISTS DATA_SET_RELATIONSHIP_FROZEN_CHECK_ON_INSERT ON DATA_SET_RELATIONSHIPS_ALL; +CREATE TRIGGER DATA_SET_RELATIONSHIP_FROZEN_CHECK_ON_INSERT BEFORE INSERT ON DATA_SET_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (NEW.PARENT_FROZEN OR NEW.CHILD_FROZEN OR NEW.CONT_FROZEN OR NEW.COMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_DATA_SET_RELATIONSHIP(); + +DROP TRIGGER IF EXISTS DATA_SET_RELATIONSHIP_FROZEN_CHECK_ON_DELETE ON DATA_SET_RELATIONSHIPS_ALL; +CREATE TRIGGER DATA_SET_RELATIONSHIP_FROZEN_CHECK_ON_DELETE BEFORE DELETE ON DATA_SET_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (OLD.PARENT_FROZEN OR OLD.CHILD_FROZEN OR OLD.CONT_FROZEN OR OLD.COMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_DATA_SET_RELATIONSHIP(); + +-- Data set experiment relationship +DROP TRIGGER IF EXISTS ADD_DATA_SET_TO_EXPERIMENT_CHECK ON DATA_ALL; +CREATE TRIGGER ADD_DATA_SET_TO_EXPERIMENT_CHECK AFTER INSERT ON DATA_ALL + FOR EACH ROW WHEN (NEW.EXPE_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT_RELATIONSHIP('data set'); + +DROP TRIGGER IF EXISTS DATA_SET_EXPERIMENT_RELATIONSHIP_FROZEN_CHECK_ON_UPDATE ON DATA_ALL; +CREATE TRIGGER DATA_SET_EXPERIMENT_RELATIONSHIP_FROZEN_CHECK_ON_UPDATE BEFORE UPDATE ON DATA_ALL + FOR EACH ROW WHEN ( + (NEW.EXPE_ID <> OLD.EXPE_ID + OR (NEW.EXPE_ID IS NOT NULL AND OLD.EXPE_ID IS NULL) + OR (NEW.EXPE_ID IS NULL AND OLD.EXPE_ID IS NOT NULL)) + AND (NEW.EXPE_FROZEN OR OLD.EXPE_FROZEN)) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_EXPERIMENT_RELATIONSHIP('data set'); + +-- Data set sample relationship +CREATE OR REPLACE FUNCTION RAISE_EXCEPTION_FROZEN_DATA_SET_SAMPLE_RELATIONSHIP() RETURNS trigger AS $$ +DECLARE + sample_id TECH_ID; + operation TEXT; +BEGIN + IF (NEW.samp_id IS NOT NULL AND NEW.samp_frozen) THEN + sample_id = NEW.samp_id; + operation = 'SET SAMPLE'; + ELSEIF (OLD.samp_id IS NOT NULL AND OLD.samp_frozen) THEN + sample_id = OLD.samp_id; + operation = 'REMOVE SAMPLE'; + END IF; + + RAISE EXCEPTION 'Operation % is not allowed because sample % is frozen for data set %.', operation, + (select code from samples_all where id = sample_id), NEW.code; +END; +$$ LANGUAGE 'plpgsql'; + +DROP TRIGGER IF EXISTS ADD_DATA_SET_TO_SAMPLE_CHECK ON DATA_ALL; +CREATE TRIGGER ADD_DATA_SET_TO_SAMPLE_CHECK AFTER INSERT ON DATA_ALL + FOR EACH ROW WHEN (NEW.SAMP_FROZEN) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_DATA_SET_SAMPLE_RELATIONSHIP(); + +DROP TRIGGER IF EXISTS DATA_SET_SAMPLE_RELATIONSHIP_FROZEN_CHECK_ON_UPDATE ON DATA_ALL; +CREATE TRIGGER DATA_SET_SAMPLE_RELATIONSHIP_FROZEN_CHECK_ON_UPDATE BEFORE UPDATE ON DATA_ALL + FOR EACH ROW WHEN ( + (NEW.SAMP_ID <> OLD.SAMP_ID + OR (NEW.SAMP_ID IS NOT NULL AND OLD.SAMP_ID IS NULL) + OR (NEW.SAMP_ID IS NULL AND OLD.SAMP_ID IS NOT NULL)) + AND (NEW.SAMP_FROZEN OR OLD.SAMP_FROZEN)) + EXECUTE PROCEDURE RAISE_EXCEPTION_FROZEN_DATA_SET_SAMPLE_RELATIONSHIP(); + +-- Freezing checks for deletion +-- from space ---------------- +CREATE OR REPLACE FUNCTION RAISE_DELETE_FROM_SPACE_EXCEPTION() RETURNS trigger AS $$ +BEGIN + RAISE EXCEPTION 'Operation DELETE % is not allowed because space % is frozen.', TG_ARGV[0], + (select code from spaces where id = old.space_id); +END; +$$ LANGUAGE 'plpgsql'; + +-- Project from space deletion +DROP TRIGGER IF EXISTS DELETE_PROJECT_FROM_SPACE_CHECK ON PROJECTS; +CREATE TRIGGER DELETE_PROJECT_FROM_SPACE_CHECK AFTER DELETE ON PROJECTS + FOR EACH ROW WHEN (OLD.SPACE_FROZEN) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SPACE_EXCEPTION('PROJECT'); + +-- Sample from space deleting +DROP TRIGGER IF EXISTS TRASH_SAMPLE_FROM_SPACE_CHECK ON SAMPLES_ALL; +CREATE TRIGGER TRASH_SAMPLE_FROM_SPACE_CHECK AFTER UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.space_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SPACE_EXCEPTION('SAMPLE'); + +DROP TRIGGER IF EXISTS DELETE_SAMPLE_FROM_SPACE_CHECK ON SAMPLES_ALL; +CREATE TRIGGER DELETE_SAMPLE_FROM_SPACE_CHECK AFTER DELETE ON SAMPLES_ALL + FOR EACH ROW WHEN (OLD.space_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SPACE_EXCEPTION('SAMPLE'); + +-- from project ------------------- +CREATE OR REPLACE FUNCTION RAISE_DELETE_FROM_PROJECT_EXCEPTION() RETURNS trigger AS $$ +BEGIN + RAISE EXCEPTION 'Operation DELETE % is not allowed because project % is frozen.', TG_ARGV[0], + (select code from projects where id = old.proj_id); +END; +$$ LANGUAGE 'plpgsql'; + +-- Experiment from project deletion +DROP TRIGGER IF EXISTS TRASH_EXPERIMENT_FROM_PROJECT_CHECK ON EXPERIMENTS_ALL; +CREATE TRIGGER TRASH_EXPERIMENT_FROM_PROJECT_CHECK AFTER UPDATE ON EXPERIMENTS_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.proj_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_PROJECT_EXCEPTION('EXPERIMENT'); + +DROP TRIGGER IF EXISTS DELETE_EXPERIMENT_FROM_PROJECT_CHECK ON EXPERIMENTS_ALL; +CREATE TRIGGER DELETE_EXPERIMENT_FROM_PROJECT_CHECK AFTER DELETE ON EXPERIMENTS_ALL + FOR EACH ROW WHEN (OLD.proj_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_PROJECT_EXCEPTION('EXPERIMENT'); + +-- Sample from project deletion +DROP TRIGGER IF EXISTS TRASH_SAMPLE_FROM_PROJECT_CHECK ON SAMPLES_ALL; +CREATE TRIGGER TRASH_SAMPLE_FROM_PROJECT_CHECK AFTER UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.proj_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_PROJECT_EXCEPTION('SAMPLE'); + +DROP TRIGGER IF EXISTS DELETE_SAMPLE_FROM_PROJECT_CHECK ON SAMPLES_ALL; +CREATE TRIGGER DELETE_SAMPLE_FROM_PROJECT_CHECK AFTER DELETE ON SAMPLES_ALL + FOR EACH ROW WHEN (OLD.proj_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_PROJECT_EXCEPTION('SAMPLE'); + +-- from experiment --------------- +CREATE OR REPLACE FUNCTION RAISE_DELETE_FROM_EXPERIMENT_EXCEPTION() RETURNS trigger AS $$ +BEGIN + RAISE EXCEPTION 'Operation DELETE % is not allowed because experiment % is frozen.', TG_ARGV[0], + (select code from experiments_all where id = old.expe_id); +END; +$$ LANGUAGE 'plpgsql'; + +-- Sample from experiment deletion +DROP TRIGGER IF EXISTS TRASH_SAMPLE_FROM_EXPERIMENT_CHECK ON SAMPLES_ALL; +CREATE TRIGGER TRASH_SAMPLE_FROM_EXPERIMENT_CHECK AFTER UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.expe_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_EXPERIMENT_EXCEPTION('SAMPLE'); + +DROP TRIGGER IF EXISTS DELETE_SAMPLE_FROM_EXPERIMENT_CHECK ON SAMPLES_ALL; +CREATE TRIGGER DELETE_SAMPLE_FROM_EXPERIMENT_CHECK AFTER DELETE ON SAMPLES_ALL + FOR EACH ROW WHEN (OLD.expe_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_EXPERIMENT_EXCEPTION('SAMPLE'); + +-- Data set from experiment deletion +DROP TRIGGER IF EXISTS TRASH_DATA_SET_FROM_EXPERIMENT_CHECK ON DATA_ALL; +CREATE TRIGGER TRASH_DATA_SET_FROM_EXPERIMENT_CHECK AFTER UPDATE ON DATA_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.expe_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_EXPERIMENT_EXCEPTION('DATA SET'); + +DROP TRIGGER IF EXISTS DELETE_DATA_SET_FROM_EXPERIMENT_CHECK ON DATA_ALL; +CREATE TRIGGER DELETE_DATA_SET_FROM_EXPERIMENT_CHECK AFTER DELETE ON DATA_ALL + FOR EACH ROW WHEN (OLD.expe_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_EXPERIMENT_EXCEPTION('DATA SET'); + +-- from sample --------------- +CREATE OR REPLACE FUNCTION RAISE_DELETE_FROM_SAMPLE_EXCEPTION() RETURNS trigger AS $$ +DECLARE + samp_id TECH_ID; +BEGIN + IF (TG_ARGV[0] = 'SAMPLE CHILD') THEN + samp_id = old.sample_id_parent; + ELSEIF (TG_ARGV[0] = 'SAMPLE PARENT') THEN + samp_id = old.sample_id_child; + ELSEIF (TG_ARGV[0] = 'SAMPLE COMPONENT') THEN + samp_id = old.samp_id_part_of; + ELSE + samp_id = old.samp_id; + END IF; + RAISE EXCEPTION 'Operation DELETE % is not allowed because sample % is frozen.', TG_ARGV[0], + (select code from samples_all where id = samp_id); +END; +$$ LANGUAGE 'plpgsql'; + +-- Sample from container deletion +DROP TRIGGER IF EXISTS TRASH_SAMPLE_FROM_CONTAINER_CHECK ON SAMPLES_ALL; +CREATE TRIGGER TRASH_SAMPLE_FROM_CONTAINER_CHECK AFTER UPDATE ON SAMPLES_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.cont_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SAMPLE_EXCEPTION('SAMPLE COMPONENT'); + +DROP TRIGGER IF EXISTS DELETE_SAMPLE_FROM_CONTAINER_CHECK ON SAMPLES_ALL; +CREATE TRIGGER DELETE_SAMPLE_FROM_CONTAINER_CHECK AFTER DELETE ON SAMPLES_ALL + FOR EACH ROW WHEN (OLD.cont_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SAMPLE_EXCEPTION('SAMPLE COMPONENT'); + +-- Sample from parent deletion +DROP TRIGGER IF EXISTS TRASH_SAMPLE_FROM_PARENT_CHECK ON SAMPLE_RELATIONSHIPS_ALL; +CREATE TRIGGER TRASH_SAMPLE_FROM_PARENT_CHECK AFTER UPDATE ON SAMPLE_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.parent_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SAMPLE_EXCEPTION('SAMPLE CHILD'); + +-- Sample from child deletion +DROP TRIGGER IF EXISTS TRASH_SAMPLE_FROM_CHILD_CHECK ON SAMPLE_RELATIONSHIPS_ALL; +CREATE TRIGGER TRASH_SAMPLE_FROM_CHILD_CHECK AFTER UPDATE ON SAMPLE_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.child_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SAMPLE_EXCEPTION('SAMPLE PARENT'); + +-- Data set from sample deletion +DROP TRIGGER IF EXISTS TRASH_DATA_SET_FROM_SAMPLE_CHECK ON DATA_ALL; +CREATE TRIGGER TRASH_DATA_SET_FROM_SAMPLE_CHECK AFTER UPDATE ON DATA_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.samp_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SAMPLE_EXCEPTION('DATA SET'); + +DROP TRIGGER IF EXISTS DELETE_DATA_SET_FROM_SAMPLE_CHECK ON DATA_ALL; +CREATE TRIGGER DELETE_DATA_SET_FROM_SAMPLE_CHECK AFTER DELETE ON DATA_ALL + FOR EACH ROW WHEN (OLD.samp_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_SAMPLE_EXCEPTION('DATA SET'); + +-- from data set --------------- +CREATE OR REPLACE FUNCTION RAISE_DELETE_FROM_DATA_SET_EXCEPTION() RETURNS trigger AS $$ +DECLARE + data_id TECH_ID; +BEGIN + IF (TG_ARGV[0] = 'DATA SET CHILD') THEN + data_id = old.data_id_parent; + ELSEIF (TG_ARGV[0] = 'DATA SET PARENT') THEN + data_id = old.data_id_child; + ELSEIF (TG_ARGV[0] = 'DATA SET COMPONENT') THEN + data_id = old.data_id_parent; + ELSEIF (TG_ARGV[0] = 'DATA SET CONTAINER') THEN + data_id = old.data_id_child; + END IF; + RAISE EXCEPTION 'Operation DELETE % is not allowed because data set % is frozen.', TG_ARGV[0], + (select code from data_all where id = data_id); +END; +$$ LANGUAGE 'plpgsql'; + +-- Data set from parent deletion +DROP TRIGGER IF EXISTS TRASH_DATA_SET_FROM_PARENT_CHECK ON DATA_SET_RELATIONSHIPS_ALL; +CREATE TRIGGER TRASH_DATA_SET_FROM_PARENT_CHECK AFTER UPDATE ON DATA_SET_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.parent_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_DATA_SET_EXCEPTION('DATA SET CHILD'); + +-- Data set from child deletion +DROP TRIGGER IF EXISTS TRASH_DATA_SET_FROM_CHILD_CHECK ON DATA_SET_RELATIONSHIPS_ALL; +CREATE TRIGGER TRASH_DATA_SET_FROM_CHILD_CHECK AFTER UPDATE ON DATA_SET_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.child_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_DATA_SET_EXCEPTION('DATA SET PARENT'); + +-- Data set from container deletion +DROP TRIGGER IF EXISTS TRASH_DATA_SET_FROM_CONTAINER_CHECK ON DATA_SET_RELATIONSHIPS_ALL; +CREATE TRIGGER TRASH_DATA_SET_FROM_CONTAINER_CHECK AFTER UPDATE ON DATA_SET_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.cont_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_DATA_SET_EXCEPTION('DATA SET COMPONENT'); + +-- Data set from component deletion +DROP TRIGGER IF EXISTS TRASH_DATA_SET_FROM_COMPONENT_CHECK ON DATA_SET_RELATIONSHIPS_ALL; +CREATE TRIGGER TRASH_DATA_SET_FROM_COMPONENT_CHECK AFTER UPDATE ON DATA_SET_RELATIONSHIPS_ALL + FOR EACH ROW WHEN (NEW.del_id IS NOT NULL AND OLD.del_id IS NULL AND OLD.comp_frozen) + EXECUTE PROCEDURE RAISE_DELETE_FROM_DATA_SET_EXCEPTION('DATA SET CONTAINER'); + +-- end of triggers for freezing + +-- start of triggers for full text search + +DROP FUNCTION IF EXISTS escape_tsvector_string(VARCHAR) RESTRICT; + +CREATE FUNCTION escape_tsvector_string(value VARCHAR) RETURNS VARCHAR AS $$ +BEGIN + RETURN REPLACE( + REPLACE( + REPLACE( + REPLACE( + REPLACE( + REPLACE( + REPLACE( + REPLACE( + REPLACE(LOWER(value), '<', '\<'), + '!', '\!'), + '*', '\*'), + '&', '\&'), + '|', '\|'), + ')', '\)'), + '(', '\('), + ':', '\:'), + ' ', '\ '); +END +$$ LANGUAGE plpgsql; + +DROP FUNCTION IF EXISTS properties_tsvector_document_trigger() CASCADE; + +CREATE FUNCTION properties_tsvector_document_trigger() RETURNS trigger AS $$ +DECLARE cvt RECORD; +BEGIN + IF NEW.cvte_id IS NOT NULL THEN + SELECT code, label INTO STRICT cvt FROM controlled_vocabulary_terms WHERE id = NEW.cvte_id; + NEW.tsvector_document := to_tsvector('english', LOWER(left(cvt.code, 1048576))) || + to_tsvector('english', coalesce(LOWER(left(cvt.label, 1048576)), '')); + ELSE + NEW.tsvector_document := to_tsvector('english', coalesce(LOWER(left(NEW.value, 1048576)), '')); + END IF; + RETURN NEW; +END +$$ LANGUAGE plpgsql; + +CREATE FUNCTION samples_all_tsvector_document_trigger() RETURNS trigger AS $$ +DECLARE proj_code VARCHAR; + space_code VARCHAR; + container_code VARCHAR; + identifier VARCHAR := '/'; +BEGIN + IF NEW.space_id IS NOT NULL THEN + SELECT code INTO STRICT space_code FROM spaces WHERE id = NEW.space_id; + identifier := identifier || space_code || '/'; + END IF; + + IF NEW.proj_id IS NOT NULL THEN + IF NEW.space_id IS NOT NULL THEN + SELECT code INTO STRICT proj_code FROM projects WHERE id = NEW.proj_id; + ELSE + SELECT p.code, s.code INTO STRICT proj_code, space_code FROM projects p + INNER JOIN spaces s ON p.space_id = s.id WHERE id = NEW.proj_id; + identifier := identifier || space_code || '/'; + END IF; + + identifier := identifier || proj_code || '/'; + END IF; + + IF NEW.samp_id_part_of IS NOT NULL THEN + SELECT code INTO STRICT container_code FROM samples_all WHERE id = NEW.samp_id_part_of; + identifier := identifier || container_code || ':' || NEW.code; + ELSE + identifier := identifier || NEW.code; + END IF; + + NEW.sample_identifier := identifier; + NEW.tsvector_document := (escape_tsvector_string(NEW.perm_id) || ':1')::tsvector || + (escape_tsvector_string(NEW.code) || ':1')::tsvector || + (escape_tsvector_string(identifier) || ':1')::tsvector; + RETURN NEW; +END +$$ LANGUAGE plpgsql; + +CREATE FUNCTION experiments_all_tsvector_document_trigger() RETURNS trigger AS $$ +DECLARE proj_code VARCHAR; + space_code VARCHAR; +BEGIN + SELECT p.code, s.code INTO STRICT proj_code, space_code FROM projects p + INNER JOIN spaces s ON p.space_id = s.id WHERE p.id = NEW.proj_id; + NEW.tsvector_document := (escape_tsvector_string(NEW.perm_id) || ':1')::tsvector || + (escape_tsvector_string(NEW.code) || ':1')::tsvector || + (escape_tsvector_string('/' || space_code || '/' || proj_code || '/' || NEW.code) || ':1')::tsvector; + RETURN NEW; +END +$$ LANGUAGE plpgsql; + +CREATE FUNCTION data_all_tsvector_document_trigger() RETURNS trigger AS $$ +BEGIN + NEW.tsvector_document := (escape_tsvector_string(NEW.data_set_kind) || ':1')::tsvector || + (escape_tsvector_string(NEW.code) || ':1')::tsvector || + ('/' || escape_tsvector_string(NEW.code) || ':1')::tsvector; + RETURN NEW; +END +$$ LANGUAGE plpgsql; + +CREATE FUNCTION materials_tsvector_document_trigger() RETURNS trigger AS $$ +DECLARE material_type_code VARCHAR; +BEGIN + SELECT code INTO STRICT material_type_code FROM material_types WHERE id = NEW.maty_id; + NEW.tsvector_document := (escape_tsvector_string(NEW.code) || ':1')::tsvector || + (escape_tsvector_string(NEW.code || ' (' || material_type_code || ')') || ':1')::tsvector; + RETURN NEW; +END +$$ LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS samples_all_tsvector_document ON samples_all; +CREATE TRIGGER samples_all_tsvector_document BEFORE INSERT OR UPDATE + ON samples_all FOR EACH ROW EXECUTE PROCEDURE + samples_all_tsvector_document_trigger(); +DROP TRIGGER IF EXISTS sample_properties_tsvector_document ON sample_properties; +CREATE TRIGGER sample_properties_tsvector_document BEFORE INSERT OR UPDATE + ON sample_properties FOR EACH ROW EXECUTE PROCEDURE + properties_tsvector_document_trigger(); + +DROP TRIGGER IF EXISTS experiments_all_tsvector_document ON experiments_all; +CREATE TRIGGER experiments_all_tsvector_document BEFORE INSERT OR UPDATE + ON experiments_all FOR EACH ROW EXECUTE PROCEDURE + experiments_all_tsvector_document_trigger(); + +DROP TRIGGER IF EXISTS experiment_properties_tsvector_document ON experiment_properties; +CREATE TRIGGER experiment_properties_tsvector_document BEFORE INSERT OR UPDATE + ON experiment_properties FOR EACH ROW EXECUTE PROCEDURE + properties_tsvector_document_trigger(); + +DROP TRIGGER IF EXISTS data_all_tsvector_document ON data_all; +CREATE TRIGGER data_all_tsvector_document BEFORE INSERT OR UPDATE + ON data_all FOR EACH ROW EXECUTE PROCEDURE + data_all_tsvector_document_trigger(); + +DROP TRIGGER IF EXISTS data_set_properties_tsvector_document ON data_set_properties; +CREATE TRIGGER data_set_properties_tsvector_document BEFORE INSERT OR UPDATE + ON data_set_properties FOR EACH ROW EXECUTE PROCEDURE + properties_tsvector_document_trigger(); + +DROP TRIGGER IF EXISTS materials_tsvector_document ON materials; +CREATE TRIGGER materials_tsvector_document BEFORE INSERT OR UPDATE + ON materials FOR EACH ROW EXECUTE PROCEDURE + materials_tsvector_document_trigger(); + +DROP TRIGGER IF EXISTS material_properties_tsvector_document ON material_properties; +CREATE TRIGGER material_properties_tsvector_document BEFORE INSERT OR UPDATE + ON material_properties FOR EACH ROW EXECUTE PROCEDURE + properties_tsvector_document_trigger(); + +-- end of triggers for full text search + +CREATE OR REPLACE FUNCTION safe_double(s text) RETURNS double precision AS $$ +BEGIN + RETURN s::double precision; + EXCEPTION WHEN OTHERS THEN + RETURN NULL; +END; $$ LANGUAGE plpgsql STRICT; + +CREATE OR REPLACE FUNCTION safe_timestamp(s text) RETURNS timestamp with time zone AS $$ +BEGIN + RETURN s::timestamp with time zone; + EXCEPTION WHEN OTHERS THEN + RETURN NULL; +END; $$ LANGUAGE plpgsql STRICT; \ No newline at end of file diff --git a/openbis/source/sql/postgresql/189/grants-189.sql b/openbis/source/sql/postgresql/189/grants-189.sql new file mode 100644 index 0000000000000000000000000000000000000000..0e5ad65c5289fa4d3ad3b9972026c665351730c4 --- /dev/null +++ b/openbis/source/sql/postgresql/189/grants-189.sql @@ -0,0 +1,131 @@ +-- Granting SELECT privilege to group OPENBIS_READONLY + +GRANT SELECT ON SEQUENCE attachment_content_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE attachment_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE code_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE experiment_code_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE sample_code_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE controlled_vocabulary_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE core_plugin_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE cvte_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE data_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE data_set_property_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE data_set_relationship_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE data_set_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE data_store_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE DATA_STORE_SERVICES_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE data_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE database_instance_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE dstpt_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE etpt_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE event_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE EVENTS_SEARCH_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE experiment_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE experiment_property_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE experiment_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE file_format_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE space_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE deletion_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE locator_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE material_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE material_property_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE material_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE mtpt_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE perm_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE person_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE project_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE property_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE role_assignment_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE sample_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE sample_property_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE sample_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE stpt_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE authorization_group_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE filter_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE query_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE POST_REGISTRATION_DATASET_QUEUE_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE ENTITY_OPERATIONS_LOG_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE EXPERIMENT_RELATIONSHIPS_HISTORY_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE SAMPLE_RELATIONSHIPS_HISTORY_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE DATA_SET_RELATIONSHIPS_HISTORY_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE PROJECT_RELATIONSHIPS_HISTORY_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE EXTERNAL_DATA_MANAGEMENT_SYSTEM_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE METAPROJECT_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE METAPROJECT_ASSIGNMENT_ID_SEQ TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE grid_custom_columns_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE sample_relationship_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE script_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON SEQUENCE relationship_type_id_seq TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE attachment_contents TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE attachments TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE controlled_vocabularies TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE controlled_vocabulary_terms TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE core_plugins TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE data_all TO GROUP OPENBIS_READONLY; +GRANT SELECT ON data TO GROUP OPENBIS_READONLY; +GRANT SELECT ON data_deleted TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE data_set_properties TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE data_set_properties_history TO GROUP OPENBIS_READONLY; +GRANT SELECT ON data_set_relationships TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE data_set_relationships_all TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE data_set_type_property_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE data_set_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE data_stores TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE data_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE DATA_STORE_SERVICES TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE DATA_STORE_SERVICE_DATA_SET_TYPES TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE database_version_logs TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE events TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE EVENTS_SEARCH TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE experiment_properties TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE experiment_properties_history TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE experiment_type_property_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE experiment_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE experiments_all TO GROUP OPENBIS_READONLY; +GRANT SELECT ON experiments TO GROUP OPENBIS_READONLY; +GRANT SELECT ON experiments_deleted TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE external_data TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE file_format_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE spaces TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE deletions TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE locator_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE material_properties TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE material_properties_history TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE material_type_property_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE material_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE materials TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE persons TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE projects TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE property_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE role_assignments TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE sample_properties TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE sample_properties_history TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE sample_type_property_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE sample_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE samples_all TO GROUP OPENBIS_READONLY; +GRANT SELECT ON samples TO GROUP OPENBIS_READONLY; +GRANT SELECT ON samples_deleted TO GROUP OPENBIS_READONLY; +GRANT SELECT ON sample_relationships TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE sample_relationships_all TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE authorization_groups TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE authorization_group_persons TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE filters TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE queries TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE scripts TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE POST_REGISTRATION_DATASET_QUEUE TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE ENTITY_OPERATIONS_LOG TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE EXPERIMENT_RELATIONSHIPS_HISTORY TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE SAMPLE_RELATIONSHIPS_HISTORY TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE DATA_SET_RELATIONSHIPS_HISTORY TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE PROJECT_RELATIONSHIPS_HISTORY TO GROUP OPENBIS_READONLY; +GRANT SELECT ON sample_history_view TO GROUP OPENBIS_READONLY; +GRANT SELECT ON data_set_history_view TO GROUP OPENBIS_READONLY; +GRANT SELECT ON experiment_history_view TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE EXTERNAL_DATA_MANAGEMENT_SYSTEMS TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE LINK_DATA TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE grid_custom_columns TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE relationship_types TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE METAPROJECTS TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE METAPROJECT_ASSIGNMENTS_ALL TO GROUP OPENBIS_READONLY; +GRANT SELECT ON METAPROJECT_ASSIGNMENTS TO GROUP OPENBIS_READONLY; +GRANT SELECT ON TABLE OPERATION_EXECUTIONS TO GROUP OPENBIS_READONLY; diff --git a/openbis/source/sql/postgresql/migration/migration-188-189.sql b/openbis/source/sql/postgresql/migration/migration-188-189.sql new file mode 100644 index 0000000000000000000000000000000000000000..905da6e06c2974a10dc032fa59132d593ae76e9c --- /dev/null +++ b/openbis/source/sql/postgresql/migration/migration-188-189.sql @@ -0,0 +1,237 @@ +-- migration from 188 to 189 + +-- fix project authors (set non-existent to system) + +UPDATE PROJECT_RELATIONSHIPS_HISTORY +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT PRH.ID + FROM PROJECT_RELATIONSHIPS_HISTORY PRH + LEFT OUTER JOIN PERSONS P ON PRH.PERS_ID_AUTHOR = P.ID + WHERE PRH.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +-- fix experiment authors (set non-existent to system) + +UPDATE EXPERIMENT_PROPERTIES +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT EP.ID + FROM EXPERIMENT_PROPERTIES EP + LEFT OUTER JOIN PERSONS P ON EP.PERS_ID_AUTHOR = P.ID + WHERE EP.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +UPDATE EXPERIMENT_PROPERTIES_HISTORY +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT EPH.ID + FROM EXPERIMENT_PROPERTIES_HISTORY EPH + LEFT OUTER JOIN PERSONS P ON EPH.PERS_ID_AUTHOR = P.ID + WHERE EPH.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +UPDATE EXPERIMENT_RELATIONSHIPS_HISTORY +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT ERH.ID + FROM EXPERIMENT_RELATIONSHIPS_HISTORY ERH + LEFT OUTER JOIN PERSONS P ON ERH.PERS_ID_AUTHOR = P.ID + WHERE ERH.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +-- fix sample authors (set non-existent to system) + +UPDATE SAMPLE_PROPERTIES +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT SP.ID + FROM SAMPLE_PROPERTIES SP + LEFT OUTER JOIN PERSONS P ON SP.PERS_ID_AUTHOR = P.ID + WHERE SP.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +UPDATE SAMPLE_PROPERTIES_HISTORY +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT SPH.ID + FROM SAMPLE_PROPERTIES_HISTORY SPH + LEFT OUTER JOIN PERSONS P ON SPH.PERS_ID_AUTHOR = P.ID + WHERE SPH.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +UPDATE SAMPLE_RELATIONSHIPS_HISTORY +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT SRH.ID + FROM SAMPLE_RELATIONSHIPS_HISTORY SRH + LEFT OUTER JOIN PERSONS P ON SRH.PERS_ID_AUTHOR = P.ID + WHERE SRH.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +-- fix dataset authors (set non-existent to system) + +UPDATE DATA_SET_PROPERTIES +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT DP.ID + FROM DATA_SET_PROPERTIES DP + LEFT OUTER JOIN PERSONS P ON DP.PERS_ID_AUTHOR = P.ID + WHERE DP.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +UPDATE DATA_SET_PROPERTIES_HISTORY +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT DPH.ID + FROM DATA_SET_PROPERTIES_HISTORY DPH + LEFT OUTER JOIN PERSONS P ON DPH.PERS_ID_AUTHOR = P.ID + WHERE DPH.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +UPDATE DATA_SET_RELATIONSHIPS_HISTORY +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT DRH.ID + FROM DATA_SET_RELATIONSHIPS_HISTORY DRH + LEFT OUTER JOIN PERSONS P ON DRH.PERS_ID_AUTHOR = P.ID + WHERE DRH.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +-- fix material authors (set non-existent to system) + +UPDATE MATERIAL_PROPERTIES +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT MP.ID + FROM MATERIAL_PROPERTIES MP + LEFT OUTER JOIN PERSONS P ON MP.PERS_ID_AUTHOR = P.ID + WHERE MP.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +UPDATE MATERIAL_PROPERTIES_HISTORY +SET PERS_ID_AUTHOR = + (SELECT ID + FROM PERSONS + WHERE USER_ID = 'system') +WHERE ID IN + (SELECT MPH.ID + FROM MATERIAL_PROPERTIES_HISTORY MPH + LEFT OUTER JOIN PERSONS P ON MPH.PERS_ID_AUTHOR = P.ID + WHERE MPH.PERS_ID_AUTHOR IS NOT NULL + AND P.ID IS NULL); + +-- add author FKs to project tables + +ALTER TABLE project_relationships_history +ADD CONSTRAINT prrelh_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +-- add author FKs to experiment tables + +ALTER TABLE experiment_properties +ADD CONSTRAINT expr_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE experiment_properties_history +ADD CONSTRAINT exprh_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE experiment_relationships_history +ADD CONSTRAINT exrelh_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +-- add author FKs to sample tables + +ALTER TABLE sample_properties +ADD CONSTRAINT sapr_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE sample_properties_history +ADD CONSTRAINT saprh_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE sample_relationships_history +ADD CONSTRAINT samprelh_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +-- add author FKs to dataset tables + +ALTER TABLE data_set_properties +ADD CONSTRAINT dspr_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE data_set_properties_history +ADD CONSTRAINT dsprh_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE data_set_relationships_history +ADD CONSTRAINT datarelh_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +-- add author FKs to material tables + +ALTER TABLE material_properties +ADD CONSTRAINT mapr_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE material_properties_history +ADD CONSTRAINT maprh_auth_fk FOREIGN KEY (pers_id_author) REFERENCES persons(id) +ON UPDATE NO ACTION +ON DELETE NO ACTION +DEFERRABLE INITIALLY DEFERRED;